In the previous section, we created the device nodes manually, and you will surely find it too cumbersome to do so.
Link to the previous article: http://blog.csdn.net/xiaoxiaopengbo/article/details/78779613
Q: Can the system automatically create device nodes?
Answer: Yes, linux has the mechanism of udev and mdev, and the busybox transplanted on our ARM development board has the mdev mechanism, then the mdev mechanism is used to automatically create device nodes.
Q: Where is the mdev mechanism set in the file system?
Answer: There is a sentence in the etc/init.d/rcS file:
echo /sbin/mdev > /proc/sys/kernel/hotplug
Q: How to write a program in the driver to let the system automatically create a device node?
Answer: First create a class class, and then create a class_device under the class class, that is, the device of the class created under the class.
For details, please refer to the driver source code:
#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, }; /* Driver entry function */ static int first_drv_init(void) { /* If the main device number is set to 0, the system will automatically assign the main device number */ major = register_chrdev(0, "first_drv", &first_drv_fops); /* Create firstdrv class */ firstdrv_class = class_create(THIS_MODULE, "firstdrv"); /* Create a xxx device under the firstdrv class for the application to open the device */ firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx"); return 0; } /* driver exit function */ static void first_drv_exit(void) { unregister_chrdev(major, "first_drv"); device_unregister(firstdrv_device); //Uninstall the device under the class class_destroy(firstdrv_class); //Uninstall the class } module_init(first_drv_init); //Used to decorate the entry function module_exit(first_drv_exit); //Used to decorate the exit function MODULE_AUTHOR ("LWJ"); MODULE_DESCRIPTION("Just for Demon"); MODULE_LICENSE("GPL"); //Follow GPL agreementPrecautions:
1. Because the linux version used by Mr. Wei is different from the linux version I use, the header file path may be changed.
2. The function names used may also be different, for example:
Mr. Wei creates classes and devices like this:
1. Definition
static struct class *firstdrv_class;
static struct class_device *firstdrv_class_dev;
2. In the entry function
firstdrv_class = class_create(THIS_MODULE, "firstdrv");
firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */
3. In the export function
class_device_unregister(firstdrv_class_dev);
class_destroy(firstdrv_class);
In linux2.6.30.4, there is no class_device_create and class_device_unregister functions
I create the class and create the device class like this:
1. Definition
static struct class *firstdrv_class;
static struct device *firstdrv_device;
2. In the entry function
/* Create firstdrv class */
firstdrv_class = class_create(THIS_MODULE, "firstdrv");
/* Create a xxx device under the firstdrv class for the application to open the device */
firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
3. In the export function
device_unregister(firstdrv_device); //Uninstall the device under the class
class_destroy(firstdrv_class); //Uninstall the class
linux2.6.30.4 uses the device_create function to replace the class_device_create function;
Use device_unregister function instead of class_device_unregister function.
The test program and Makefile have not been modified, so they will not be posted again.
上一节文章链接:http://blog.csdn.net/xiaoxiaopengbo/article/details/78779613
测试步骤:
[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]#
Reprinted: http://blog.csdn.net/lwj103862095/article/details/17470573