上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了。
上一节文章链接:https://blog.csdn.net/qq_37659294/article/details/104302700
问:能不能让系统自动创建设备节点?
答:可以,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/module.h>
#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 <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
static struct class *firstdrv_class;
static struct class_device *firstdrv_class_dev;
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设备,供应用程序打开设备*/
/* 在“类”里面创建设备
* MKDEV(major, 0)指定主设备号为major,次设备号为0(这里的major必须和register_chrdev返回的一致,不然会出错)
*/
firstdrv_class_dev = 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_class_dev); //卸载类下的设备
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协议
测试程序和Makefile没有修改,故再不贴。
上一节文章链接:https://blog.csdn.net/qq_37659294/article/details/104302700
测试步骤:
[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 //装上我们写的驱动后,会自动生成设备节点/dev/xxx
[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/ //打开/sys/class可以看到我们生成的firstdrv类
[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/ //firstdrv类里面有我们的xxx设备
[WJ2440]# ls
xxx
[WJ2440]# cd xxx/
[WJ2440]# ls
dev subsystem uevent
[WJ2440]# cat dev //主设备号252,次设备号0
252:0
[WJ2440]# cat uevent
MAJOR=252
MINOR=0
[WJ2440]# cd /
[WJ2440]# ./first_test //有了设备节点便能够运行我们的程序了
first_drv_open
first_drv_write
[WJ2440]#
本文参考于: