第十一节、自动创建设备节点
本节用于介绍如何自动创建设备节点
在上面的Linux驱动实验中,当我们通过insmod命令加载模块后,还需要通过mknod命令来手动创建设备节点,这样使用起来太麻烦了,并且不可能每个设备都去这样操作,Linux系统的存在就是为了方便使用。所以我们来看一下如何实现自动创建设备节点,当加载模块时,在/dev目录下自动创建相应的设备文件。
1、怎么自动创建一个设备节点?
在嵌入式Linux中使用mdev来实现设备节点文件的自动创建和删除。
2、什么是mdev?
mdev是udev的简化版本,是busybox中所带的程序,最适合用在嵌入式系统。
3、什么是udev?
udev是一种工具,它能够根据系统中的硬件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在/dev目录下。使用udev后,在/dev目录下就只包含系统中真正存在的设备。udev 一般用在PC上的linux中,相对mdev 来说要复杂些。
4、怎么自动创建设备节点?
自动创建设备节点分为俩个步骤:
步骤一:使用class_create函数创建一个class的类。
步骤二:使用device_create函数在我们创建的类下面创建一个设备。
5、创建和删除类函数
在Linux驱动程序中一般通过两个函数来完成设备节点的创建和删除。
首先要创建一个class 类结构体
文件位置路径:include/linux/device.h
struct class {
const char *name;
struct module *owner;
const struct attribute_group **class_groups;
const struct attribute_group **dev_groups;
struct kobject *dev_kobj;
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(struct device *dev, umode_t *mode);
void (*class_release)(struct class *class);
void (*dev_release)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
int (*shutdown_pre)(struct device *dev);
const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(struct device *dev);
const struct dev_pm_ops *pm;
struct subsys_private *p;
};
class_create 是类创建函数,class create是个宏定义
文件位置路径:include/linux/device.h
#define class_create(owner, name) \
({ \
static struct lock_class_key __key; \
__class_create(owner, name, &__key); \
})
//参数
//owner:一般为THIS_MODULE
//name:类的名字
//返回值
//指向结构体class的指针,也就是创建的类
实际上这个函数调用的是__class_create函数
文件位置路径:drivers/base/class.c
struct class *__class_create(struct module *owner, const char *name,
struct lock_class_key *key)
//可以看出来返回的值是struct class *类型,是指向结构体class的指针,也就是创建的类
创建类的成功之后,我们可以在文件系统的/sys/class下面看到叫name名字的类
卸载驱动程序的时候需要删除掉类,类删除函数为class_destroy
文件位置路径:include/linux/device.h
extern void class_destroy(struct class *cls);
//参数
//cls:要删除的类
6、创建和删除设备函数
当使用上节的函数创建完成一个类后,使用device_create函数在这个类下创建一个设备。
文件位置路径:include/linux/device.h
struct device *device_create(struct class *cls, struct device *parent,
dev_t devt, void *drvdata,
const char *fmt, ...);
//参数
//cls:设备要创建到哪个类下面
//parent:父设备,一般为NULL,也就是没有父设备
//devt:设备号
//drvdata:设备可能会使用的一些数据,一般为NULL
//fmt:设备节点的名字,如果设置fmt=xxx的话,就会生成/dev/xxx这个设备文件。
//返回值是struct device *类型,是指向结构体device的指针,也就是创建的设备
同样的,卸载驱动的时候需要删除掉创建的设备,设备删除函数为device_destroy,这个函数要写在类注销函数的上面
文件位置路径:include/linux/device.h
extern void device_destroy(struct class *cls, dev_t devt);
//参数
//cls:设备要创建到哪个类下面
//devt:设备号