Yuhang Zheng

第十一节、自动创建设备节点

N 人看过

本节用于介绍如何自动创建设备节点

在上面的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:设备号