刚开学有点忙,没有来得及提交心得。今天把之前的GPIO驱动发上来给大家参考下。@spacexplorer 由于第一次学linux所以学的比较忙,还请boss多指点指点。
本驱动参考了《linux 设备驱动开发技术及应用》这本书,大家可以去看看。虽然书里用的是2.6的内核,君益兴提供了3.2的内核,但代码基本都能实现,可能部分代码需要改动。
先上GPIO驱动的代码
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- //#include
- #define RDWR_DEV_NAME "rdwrdev"
- #define RDWR_DEV_MAJOR 240
- //#define GPBCON 0x56000010
- //#define GPBDAT 0x56000014
- //static void *GPB_CON;
- //static void *GPB_DAT;
- volatile unsigned long *GPBCON,*GPBDAT;
- //#define RDWR_WRITE_CONFIG_ADDR *GPBCON
- //#define RDWR_WRITE_ADDR *GPBDAT
- //#define RDWR_READ_ADDR *GPBDAT
- //#define RDWR_READ_CONFIG_ADD *GPBCON
- int rdwr_open(struct inode *inode,struct file *filp)
- {
- // RDWR_WRITE_CONFIG_ADD = 0x00000004;
- // GPB_CON= 0x00000004;
- (*GPBCON) = 0x00000004;
- printk("dev open finished\n");
- return 0;
- }
- ssize_t rdwr_read(struct file *filp,char *buf,size_t count,loff_t *f_pos )
- {
- unsigned int status;
- int loop;
-
- for(loop = 0;loop < count ;loop++)
- {
- // status = RDWR_READ_ADD & 0x00000004;
- // status = GPB_DAT& 0x00000004;
- status = ((*GPBDAT)&0x00000004);
- // copy_to_user()
- put_user(status,(char *)&buf[loop]);
- }
- return count;
- }
- ssize_t rdwr_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos)
- {
- unsigned int status;
- int loop;
- for(loop = 0;loop < count;loop++)
- {
- get_user(status,(char *)buf);
- // RDWR_WRITE_ADDR = status;
- (*GPBDAT) = status;
- }
- return count;
- }
- int rdwr_release(struct inode *inode,struct file *filp)
- {
- return 0;
- }
- struct file_operations rdwr_fops =
- {
- .owner = THIS_MODULE,
- .read = rdwr_read,
- .write = rdwr_write,
- .open = rdwr_open,
- .release = rdwr_release,
- };
- int rdwr_init(void)
- {
- int result;
-
- result = register_chrdev(RDWR_DEV_MAJOR,RDWR_DEV_NAME,&rdwr_fops);
- if(result < 0)
- {
- printk("rdwr init failed\n");
- return result;
- }
- GPBCON = (volatile unsigned long *)ioremap(0x56000010,0x00000004);
- GPBDAT = (volatile unsigned long *)ioremap(0x56000014,0x00000004);
- // GPB_CON = ioremap(GPBCON,0x00000004);
- // GPB_DAT = ioremap(GPBDAT,0x00000004);
- printk("rdwr init success\n");
- return 0;
- }
- void rdwr_exit(void)
- {
- unregister_chrdev(RDWR_DEV_MAJOR,RDWR_DEV_NAME);
- printk("rdwr exit success\n");
- }
- module_init(rdwr_init);
- module_exit(rdwr_exit);
- MODULE_LICENSE("Dual BSD/GPL");
复制代码重点讲解其中几个比较重要的函数1.
get_user,put_user这两个宏的效果是内核空间数据和用户空间数据的交换。
2(volatile unsigned long *)ioremap(0x56000010,0x00000004)这个函数的效果是把0x56000010这个物理地址映射到虚拟地址里。可能有人会问0x00000004是什么意思?我的理解是:arm是32位的,每个地址都是8位的,8*4=32正好是一个寄存器的长度。
3.rdwr_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos)这个函数的效果是把buf里的数据写到GPBDAT里,count决定写几次。
下面贴上应用程序的代码
- #include
- #include
- #include
- #include
- #include
- #include
- #define DEVICE_FILENAME "/dev/rdwrdev"
- int main()
- {
- int dev;
- char buff[128];
- int loop;
-
- dev = open(DEVICE_FILENAME,O_RDWR|O_NDELAY);
-
- if(dev >= 0)
- {
- printf("Please wait input\n");
-
- /* while(1)
- {
- if(read(dev,buff,1)== 1)
- {
- printf("read data [%02X]\n",buff[0]&0xff);
- if(buff[0]== 0x04)
- {
- break;
- }
- }
- }*/
- printf("input ok...\n");
- printf("led flashing...\n");
- for(loop = 0;loop < 5;loop++)
- {
- buff[0]= 0x02;
- write(dev,buff,1);
- sleep(1);
- buff[0]= 0x00;
- write(dev,buff,1);
- sleep(1);
- }
- //buff[0] = 0x02;
- //write(dev,buff,1);
- close(dev);
- printf("ioctl test finished\n");
- }
- else
- {
- printf("open dev failed\n");
- }
- return 0;
- }
复制代码这个应用的效果是让led灭1s,亮1s如此反复5次。
makefile文件大家可以参考我之前写的关于hello_world的驱动。
编译过后把生成的.ko 和app文件传到开发板。
首先输入
- [root@jyxtec /]# mknod /dev/rdwrdev c 240 0
复制代码创建设备文件
然后到达上传之前2个文件的文件夹
- [root@jyxtec /]# cd home/test
- [root@jyxtec test]# ls
- ioctl_test_app ioctl_test_module.ko
复制代码然后安装驱动
- [root@jyxtec test]# insmod ioctl_test_module.ko
- rdwr init success
复制代码接着运行应用程序
- [root@jyxtec test]# ./ioctl_test_app
复制代码- [root@jyxtec test]# ./ioctl_test_app
- dev open finished
- Please wait input
- input ok...
- led flashing...
- ioctl test finished
复制代码就可以看到led闪烁5次。

原来我的渣像素,不过代码绝对可用。
本文来自论坛,点击查看完整帖子内容。