linux字符驱动之自动创建设备节点

转自:http://blog.csdn.net/lwj103862095/article/details/17470573

上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了。

上一节文章链接:http://blog.csdn.net/lwj103862095/article/details/17468587

问:能不能让系统自动创建设备节点?

答:可以,linux有udev、mdev的机制,而我们的ARM开发板上移植的busybox有mdev机制,那么就使用mdev机制来自动创建设备节点。

问:文件系统里,在哪里设置了mdev机制?

答:在etc/init.d/rcS文件里有一句:

echo /sbin/mdev > /proc/sys/kernel/hotplug

问:在驱动程序里面如何编写程序,让系统自动创建设备节点?

答:首先创建一个class类,然后在class类下,创建一个class_device,即类下面创建类的设备。


详细请参考驱动源码:

[cpp]  view plain  copy
 print ?
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include      //class_create  
  10.   
  11. static struct class *firstdrv_class;  
  12. static struct device *firstdrv_device;  
  13.   
  14. int major;  
  15. static int first_drv_open(struct inode * inode, struct file * filp)  
  16. {  
  17.     printk("first_drv_open\n");  
  18.     return 0;  
  19. }  
  20. static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos)  
  21. {  
  22.     printk("first_drv_write\n");  
  23.     return 0;  
  24. }  
  25.   
  26. /* File operations struct for character device */  
  27. static const struct file_operations first_drv_fops = {  
  28.     .owner      = THIS_MODULE,  
  29.     .open       = first_drv_open,  
  30.     .write      = first_drv_write,  
  31. };  
  32.   
  33. /* 驱动入口函数 */  
  34. static int first_drv_init(void)  
  35. {  
  36.     /* 主设备号设置为0表示由系统自动分配主设备号 */  
  37.     major = register_chrdev(0, "first_drv", &first_drv_fops);  
  38.   
  39.     /* 创建firstdrv类 */  
  40.     firstdrv_class = class_create(THIS_MODULE, "firstdrv");  
  41.   
  42.     /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/  
  43.     firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");  
  44.     return 0;  
  45. }  
  46.   
  47. /* 驱动出口函数 */  
  48. static void first_drv_exit(void)  
  49. {  
  50.     unregister_chrdev(major, "first_drv");  
  51.     device_unregister(firstdrv_device);  //卸载类下的设备  
  52.     class_destroy(firstdrv_class);      //卸载类  
  53. }  
  54.   
  55. module_init(first_drv_init);  //用于修饰入口函数  
  56. module_exit(first_drv_exit);  //用于修饰出口函数      
  57.   
  58. MODULE_AUTHOR("LWJ");  
  59. MODULE_DESCRIPTION("Just for Demon");  
  60. MODULE_LICENSE("GPL");  //遵循GPL协议  


注意事项:

1.因韦老师使用的linux版本跟我使用的linux版本不一致,头文件路径可能有所变动。

2.使用的函数名可能也不一样,例如:

韦老师是这样子创建类和创建类的设备:

一、定义

static struct class *firstdrv_class;
static struct class_device *firstdrv_class_dev;

二、入口函数里

firstdrv_class = class_create(THIS_MODULE, "firstdrv");
firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */

三、出口函数里

class_device_unregister(firstdrv_class_dev);
class_destroy(firstdrv_class);


而在linux2.6.30.4里,并没有class_device_createclass_device_unregister函数

我是这样子创建类和创建类的设备:

一、定义

static struct class *firstdrv_class;
static struct device *firstdrv_device;

二、入口函数里

/* 创建firstdrv类 */

firstdrv_class = class_create(THIS_MODULE, "firstdrv");


/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");

三、出口函数里

device_unregister(firstdrv_device);  //卸载类下的设备
class_destroy(firstdrv_class); //卸载类


linux2.6.30.4使用device_create函数替代class_device_create函数;

使用device_unregister函数替代class_device_unregister函数。


测试程序和Makefile没有修改,故再不贴。

上一节文章链接:http://blog.csdn.net/lwj103862095/article/details/17468587

测试步骤:

[cpp]  view plain  copy
 print ?
  1. [WJ2440]# ls  
  2. Qt            driver_test   lib           root          udisk  
  3. TQLedtest     etc           linuxrc       sbin          usr  
  4. app_test      first_drv.ko  mnt           sddisk        var  
  5. bin           first_test    opt           sys           web  
  6. dev           home          proc          tmp  
  7. [WJ2440]# ls -l /dev/xxx  
  8. ls: /dev/xxx: No such file or directory  
  9. [WJ2440]# insmod first_drv.ko   
  10. [WJ2440]# lsmod  
  11. first_drv 1912 0 - Live 0xbf000000  
  12. [WJ2440]# ls -l /dev/xxx  
  13. crw-rw----    1 root     root      252,   0 Jan  1 23:17 /dev/xxx  
  14. [WJ2440]# cat proc/devices   
  15. Character devices:  
  16.   1 mem  
  17.   4 /dev/vc/0  
  18.   4 tty  
  19.   5 /dev/tty  
  20.   5 /dev/console  
  21.   5 /dev/ptmx  
  22.   7 vcs  
  23.  10 misc  
  24.  13 input  
  25.  14 sound  
  26.  29 fb  
  27.  81 video4linux  
  28.  89 i2c  
  29.  90 mtd  
  30. 116 alsa  
  31. 128 ptm  
  32. 136 pts  
  33. 180 usb  
  34. 188 ttyUSB  
  35. 189 usb_device  
  36. 204 tq2440_serial  
  37. 252 first_drv  
  38. 253 usb_endpoint  
  39. 254 rtc  
  40.   
  41. Block devices:  
  42. 259 blkext  
  43.   7 loop  
  44.   8 sd  
  45.  31 mtdblock  
  46.  65 sd  
  47.  66 sd  
  48.  67 sd  
  49.  68 sd  
  50.  69 sd  
  51.  70 sd  
  52.  71 sd  
  53. 128 sd  
  54. 129 sd  
  55. 130 sd  
  56. 131 sd  
  57. 132 sd  
  58. 133 sd  
  59. 134 sd  
  60. 135 sd  
  61. 179 mmc  
  62. [WJ2440]# cd /sys/class/  
  63. [WJ2440]# ls  
  64. bdi           i2c-adapter   misc          scsi_device   usb_endpoint  
  65. block         i2c-dev       mmc_host      scsi_disk     usb_host  
  66. firmware      ieee80211     mtd           scsi_host     vc  
  67. firstdrv      input         net           sound         video4linux  
  68. graphics      mem           rtc           tty           vtconsole  
  69. [WJ2440]# cd firstdrv/  
  70. [WJ2440]# ls  
  71. xxx  
  72. [WJ2440]# cd xxx/  
  73. [WJ2440]# ls   
  74. dev        subsystem  uevent  
  75. [WJ2440]# cat dev   
  76. 252:0  
  77. [WJ2440]# cat uevent   
  78. MAJOR=252  
  79. MINOR=0  
  80. [WJ2440]# cd /     
  81. [WJ2440]# ./first_test   
  82. first_drv_open  
  83. first_drv_write  
  84. [WJ2440]#   

你可能感兴趣的:(Linux设备驱动)