在上面的Linux驱动实验中,当我们通过insmod命令加载模块后,还需要通过mkmod命令来手动创建设备节点,这样使用起来太麻烦了,并且不可能每个设备都去这样操作,Linux系统的存在就是为了方便使用,所以我们来看一下如何实现自动创建设备节点,当加载模块时,在/dev目录下自动创建相应的设备文件。
1 mdev简介
udev是一种工具,它能够根据系统中的硬件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在/dev目录下。使用udev后,在/dev目录下就只包含系统中真正存在的设备。而mdev是udev的简化版本,是busybox中所带的程序,最适合用在嵌入式系统,而udev一般用在PC上的linux中,相对mdev来说要复杂些,所以在嵌入式Linux中使用mdev来实现设备节点文件的自动创建和删除。
2 创建和删除类函数
在Linux驱动程序中一般通过两个函数来完成设备节点的创建和删除。首先要创建一个class类结构体,class结构体定义在include/linux/device.h里面。class_create是类创建函数,class_create是个宏定义,内容如下:
#define class_create(owner, name) \
({
\
static struct lock_class_key __key; \
__class_create(owner, name, &__key); \
})
struct class *__class_create(struct module *owner, const char *name,
struct lock_class_key *key)
class_create一共有两个参数,参数owner一般为THIS_MODULE,参数name是类名字。返回值是个指向结构体class的指针,也就是创建的类。
卸载驱动程序的时候需要删除掉类,类删除函数为class_destroy,函数原型如下:
void class_destroy(struct class *cls);
参数cls就是要删除的类。
3 创建设备函数
当使用上节的函数创建完成一个类后,使用device_create 函数在这个类下创建一个设备。device_create函数原型如下:
struct device *device_create(struct class *class,
struct device *parent,
dev_t devt,
void *drvdata,
const char *fmt, ...)
device_create是个可变参数函数,参数class就是设备要创建哪个类下面;参数parent是父设备,一般为NULL,也就是没有父设备;参数devt是设备号;参数drvdata是设备可能会使用的一些数据,一般为NULL;参数fmt是设备名字,如果设置fmt=xxx的话,就会生成/dev/xxx这个设备文件。返回值就是创建好的设备。
同样的,卸载驱动的时候需要删除掉创建的设备,设备删除函数为device_destroy,函数原型如下:
void device_destroy(struct class *class, dev_t devt)
参数class是要删除的设备所处的类,参数devt是要删除的设备号。
4 代码实例
实验例程对应路径:i.MX6UL终结者光盘资料/06_Linux驱动例程/01_chartest
前面我们了解了如何在Linux下自动创建和删除设备节点。这样我们就可以通过修改常规字符驱动程序来验证一下。创建chartest_medv.c文件,程序内容如下:
1 #include <linux/types.h>
2 #include <linux/kernel.h>
3 #include <linux/delay.h>
4 #include <linux/ide.h>
5 #include <linux/init.h>
6 #include <linux/module.h>
7 #include <linux/cdev.h>
8 #define CHRDEVBASE_MAJOR 200 /* 主设备号 */
9 #define CHRDEVBASE_NAME "chartest" /* 设备名 */
10
11 struct cdev *cdev;
12 struct class *class;/* 类 */
13 str