上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了。
上一节文章链接: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 mem4 /dev/vc/04 tty5 /dev/tty5 /dev/console5 /dev/ptmx7 vcs10 misc13 input14 sound29 fb81 video4linux89 i2c90 mtd
116 alsa
128 ptm
136 pts
180 usb
188 ttyUSB
189 usb_device
204 tq2440_serial
252 first_drv
253 usb_endpoint
254 rtcBlock devices:
259 blkext7 loop8 sd31 mtdblock65 sd66 sd67 sd68 sd69 sd70 sd71 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]#
本文参考于:
https://blog.csdn.net/lwj103862095/article/details/17470573