上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了。
上一节文章链接: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,即类下面创建类的设备。
详细请参考驱动源码:
#include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> #include <linux/module.h> #include <linux/device.h> //class_create static struct class *firstdrv_class; static struct device *firstdrv_device; int major; static int first_drv_open(struct inode * inode, struct file * filp) { printk("first_drv_open\n"); return 0; } static int first_drv_write(struct file * file, const char __user * buffer, size_t count, loff_t * ppos) { printk("first_drv_write\n"); return 0; } /* File operations struct for character device */ static const struct file_operations first_drv_fops = { .owner = THIS_MODULE, .open = first_drv_open, .write = first_drv_write, }; /* 驱动入口函数 */ static int first_drv_init(void) { /* 主设备号设置为0表示由系统自动分配主设备号 */ major = register_chrdev(0, "first_drv", &first_drv_fops); /* 创建firstdrv类 */ firstdrv_class = class_create(THIS_MODULE, "firstdrv"); /* 在firstdrv类下创建xxx设备,供应用程序打开设备*/ firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx"); return 0; } /* 驱动出口函数 */ static void first_drv_exit(void) { unregister_chrdev(major, "first_drv"); device_unregister(firstdrv_device); //卸载类下的设备 class_destroy(firstdrv_class); //卸载类 } module_init(first_drv_init); //用于修饰入口函数 module_exit(first_drv_exit); //用于修饰出口函数 MODULE_AUTHOR("LWJ"); MODULE_DESCRIPTION("Just for Demon"); 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_create和class_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
测试步骤:
[WJ2440]# ls Qt driver_test lib root udisk TQLedtest etc linuxrc sbin usr app_test first_drv.ko mnt sddisk var bin first_test opt sys web dev home proc tmp [WJ2440]# ls -l /dev/xxx ls: /dev/xxx: No such file or directory [WJ2440]# insmod first_drv.ko [WJ2440]# lsmod first_drv 1912 0 - Live 0xbf000000 [WJ2440]# ls -l /dev/xxx crw-rw---- 1 root root 252, 0 Jan 1 23:17 /dev/xxx [WJ2440]# cat proc/devices Character devices: 1 mem 4 /dev/vc/0 4 tty 5 /dev/tty 5 /dev/console 5 /dev/ptmx 7 vcs 10 misc 13 input 14 sound 29 fb 81 video4linux 89 i2c 90 mtd 116 alsa 128 ptm 136 pts 180 usb 188 ttyUSB 189 usb_device 204 tq2440_serial 252 first_drv 253 usb_endpoint 254 rtc Block devices: 259 blkext 7 loop 8 sd 31 mtdblock 65 sd 66 sd 67 sd 68 sd 69 sd 70 sd 71 sd 128 sd 129 sd 130 sd 131 sd 132 sd 133 sd 134 sd 135 sd 179 mmc [WJ2440]# cd /sys/class/ [WJ2440]# ls bdi i2c-adapter misc scsi_device usb_endpoint block i2c-dev mmc_host scsi_disk usb_host firmware ieee80211 mtd scsi_host vc firstdrv input net sound video4linux graphics mem rtc tty vtconsole [WJ2440]# cd firstdrv/ [WJ2440]# ls xxx [WJ2440]# cd xxx/ [WJ2440]# ls dev subsystem uevent [WJ2440]# cat dev 252:0 [WJ2440]# cat uevent MAJOR=252 MINOR=0 [WJ2440]# cd / [WJ2440]# ./first_test first_drv_open first_drv_write [WJ2440]#