工控驿站

 找回密码
 立即注册
工控驿站»工控驿站 » 编程软件»ARM,Linux,搭建一个字符设备驱动程序的框架
查看: 405|回复: 0

[分享帖] ARM,Linux,搭建一个字符设备驱动程序的框架

[复制链接]

该用户从未签到

发表于 2017-3-1 16:05:47 | 显示全部楼层 |阅读模式
在我看来,Linux内核开发,有两步,第一步,不管是字符设备驱动程序,还是块设备驱动程序,还是网络设备驱动程序,都需要一个空的框架,第二步,在这个空的框架下再填充对硬件的控制。然后编译,下载到板子上运行。

先写一个最简单的字符设备驱动:

  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/init.h>
  5. #include <linux/delay.h>
  6. #include <asm/uaccess.h>
  7. #include <asm/irq.h>
  8. #include <asm/io.h>
  9. #include <linux/cdev.h>
  10. #include <linux/device.h>
  11. #include <linux/slab.h>
  12. #include <asm/uaccess.h>

  13. #define DEVICE_NAME     "kong"   /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */
  14. #define kong_MAJOR       250     /* 主设备号 */


  15. static int kong_open(struct inode *inode, struct file *file)
  16. {
  17.   printk("open ok\n");
  18.   return 0;
  19. }

  20. static kong_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
  21. {
  22.   printk("write ok\n");
  23.   char val;

  24.   copy_from_user(&val,buf,1);

  25.   printk("write data:%d \n",val);

  26.   return 0;
  27.   
  28. }
  29. static struct file_operations kong_fops = {
  30.     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
  31.     .open   =   kong_open,     
  32.         .write        =        kong_write,           
  33. };


  34. static int __init kong_init(void)
  35. {
  36.     int ret;
  37.     ret = register_chrdev(kong_MAJOR, DEVICE_NAME, &kong_fops);
  38.     if (ret < 0) {
  39.       printk(" can't register major number\n");
  40.       return ret;
  41.     }
  42.         printk("register sucess /dev/kong OK!\n");
  43.     printk(DEVICE_NAME " initialized\n");
  44.         return 0;
  45. }

  46. static void __exit kong_exit(void)
  47. {
  48.    unregister_chrdev(kong_MAJOR, DEVICE_NAME);
  49.    
  50.    printk("rmmod OK!\n");
  51. }

  52. module_init(kong_init);
  53. module_exit(kong_exit);

  54. MODULE_LICENSE("GPL");
复制代码

可以看到,这个代码中,入口函数就这个register_chrdev函数,这个函数做了什么?注册了设备号250,这个设备号是通过终端cat /proc/devices 发现250号没用用到,于是就用上了,提交了一个结构体kong_fops,这里只对open,write,做了处理,后续可以根据情况添加。将文件传到虚拟机Linux系统里,make,在板子上insmod
再写一个测试.c文件

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>

  5. int main(int argc, char **argv)
  6. {

  7.   int fd;
  8.   char val;
  9.   val = 13;
  10.   fd=open("/dev/xxx",O_RDWR);
  11.   if (fd < 0)
  12.   {
  13.         printf("error, can't open \n");
  14.         return 0;
  15.   }
  16.   write(fd, &val, 1);
  17.   printf("write :%d \n",val);

  18.   return 0;
  19.   
  20. }
复制代码



如果注意到了,会发现驱动文件是注册的"/dev/kong" ,而测试文件是打开的“/dev/xxx”,这能打开吗,答案是能,为什么?因为......太多的解释,我也不清楚,我就知道内核之所以能找上这个驱动因为主设备号,来看结果,我们为/dev/xxx创建一个设备节点,驱动的主设备号是250,那就创建250号,好让测试文件可以打开。在板子终端输入  mknod /dev/xxx c 250 0
运行测试文件,需要先交叉编译

开始改进:
每次驱动程序写完,都需要自己看下哪个这设备号没有用到,然后在选择没有用到的设备号,需要改进为动态注册设备号,让系统自动分配,写完后还需要手动创建设备节点,需要改进为让系统自己去为这个驱动创建设备节点,这样应用层就更好的测试和开发了
上面的驱动程序不变,刚才需要改进的地方都是可以在入口函数做的
  1. static int __init kong_init(void)
  2. {
  3. int ret;
  4. ret = register_chrdev(kong_MAJOR, DEVICE_NAME, &kong_fops);
  5. if (ret < 0) {
  6. printk(" can't register major number\n");
  7. return ret;
  8. }
  9. printk("register sucess /dev/kong OK!\n");
  10. kong_class = class_create(THIS_MODULE, "kong");
  11. if (IS_ERR(kong_class))
  12. return PTR_ERR(kong_class);

  13. kong_class_devs = device_create(kong_class, NULL, MKDEV(kong_MAJOR, 0), NULL, "kong");
  14. if (unlikely(IS_ERR(kong_class_devs)))
  15. return PTR_ERR(kong_class_devs);

  16. printk(DEVICE_NAME " initialized\n");
  17. return 0;
  18. }
复制代码


整个函数先不要被if语句给看误导了,就三个函数
   register_chrdev
   class_create
   device_create
既然入口函数变了,出口也要相应的变

  1. static void __exit kong_exit(void)
  2. {
  3.    unregister_chrdev(kong_MAJOR, DEVICE_NAME);
  4.    
  5.    device_unregister(kong_class_devs);
  6.    
  7.    class_destroy(kong_class);
  8.    
  9.    printk("rmmod OK!\n");
  10. }
复制代码

这样,测试函数就不要写open "/dev/xxx",可以直接“dev/kong”,系统可以直接找到这个驱动的



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

武汉夜生活 武汉夜生活 武汉桑拿网 武汉桑拿网 武汉桑拿网 武汉夜生活

QQ|小黑屋|手机版|Archiver|工控驿站 ( 鲁ICP备11011731号-4

GMT+8, 2020-4-2 18:12 , Processed in 0.062500 second(s), 20 queries .

Powered by 工控资料窝

© 2013-2015 www.gkwo.net

快速回复 返回顶部 返回列表