我们将设备驱动加载到内核以后,并不会在 /dev 目录下生成对应的设备节点文件,应用程序读写设备,本质就是在读写 /dev 下对应的设备节点文件。
因此,我们需要在加载到驱动的时候自动创建设备节点。这个就需要依靠 mdev 来实现,mdev 是一个简化版的udev,能够检测系统中的硬件设备状态,以此来创建或者删除设备文件。
目录
一、类的创建 / 销毁
1、创建类
一个设备可以有属于自己的类型,比如触摸、鼠标、键盘都属于输入设备,这就是一个最典型的类,可以在 /sys/class 看到其他类似的类。
内核中使用 class 结构体来表示一个类,创建一个类使用的原型如下(本质是一个宏)
/*
* @description: 创建一个类
* @param - owner
* @param - name
*/
#define class_create(owner, name) \
({ \
static struct lock_class_key __key; \
__class_create(owner, name, &__key); \
})
extern struct class * __must_check __class_create(struct module *owner,
const char *name,
struct lock_class_key *key);
owner:一般为 THIS_MODULE
name:类的名字,调用成功以后,会在 /sys/class 目录下生成对应的类目录
返回值:返回一个class结构体的指针
static struct class* _class;
_class = class_create(THIS_MODULE, CHRDEVBASE_NAME);
if (IS_ERR(_class)) // 判断指针是否有效,IS_ERR 在 #include <linux/err.h> 中定义
{
return -1;
}
2、销毁类
销毁一个类会将类目录从 /sys/class 下移除,原型如下。参数 cls 就代表要销毁的类
void class_destroy(struct class *cls);
二、设备节点的创建 / 移除
1、创建设备节点
创建一个设备节点会在对应的类目录下生成一个设备目录,同时也会在 /dev 目录下生成对应的设备节点文件。
内核中使用 device 结构体表示设备节点,创建设备所使用的原型如下:
struct device *device_create(struct class *class,
struct device *parent,
dev_t devt,
void *drvdata,
const char *fmt, ...)
class:该设备节点所属类
parent:表示父设备,一般为NULL,代表没有父设备
devt:设备号
drvdata:设备所需的数据,一般为NULL
fmt:设备名字,如果设置fmt=xxx,就会生成 /dev/xxx 这个设备文件
返回值:创建号的设备节点指针
2、移除设备节点
卸载驱动时需要删除掉创建的设备,/dev/xxx 下对应的设备文件也会被删除,函数原型如下:
void device_destroy(struct class *class, dev_t devt);
class:设备节点所属类
devt:设备号
参考文章: