class_device_create函数转

Linux 逻辑设备创建
本文介绍 Linux 内核中逻辑设备的创建过程,通过 class_device_create 函数实现。该函数负责生成并注册一个逻辑设备,关联物理设备,并将其添加到指定的设备类中。
class_device_create() -- 生成并注册一个逻辑设备
2007年08月31日 星期五 11:31
usb_register_bus() --> class_device_create()

linux-2.6.21.5/drivers/base/class.c

class_device_create - creates a class device and registers it with sysfs

每个class_device对象表示一个逻辑设备,并通过struct class_device中的dev域(一个指向struct device的指针)关联一个物理设备。这样,一个逻辑设备总是对应于一个物理设备,但是一个物理设备却可能对应于多个逻辑设备。

*device对应的逻辑设备(class_device)添加到*cls所代表的设备类中。在*cls所在目录下,建立代表逻辑设备的目录。

struct class_device *class_device_create(
                     struct class        *cls,
                     struct class_device *parent,
                     dev_t               devt,
                     struct device       *device,
                     const char          *fmt, ...)
{
    va_list args;
    struct class_device *class_dev = NULL;
    int retval = -ENODEV;

    if (cls == NULL || IS_ERR(cls))
        goto error;

    class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL);
    if (!class_dev) {
        retval = -ENOMEM;
        goto error;
    }

    class_dev->devt
- = devt;
    class_dev->dev   = device;
    class_dev->class = cls;
    class_dev->parent
- = parent;
    class_dev->release = class_device_create_release;
    class_dev->uevent
- = class_device_create_uevent;

    va_start(args, fmt);
    vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
    va_end(args);
    retval = class_device_register(class_dev);
    if (retval)
        goto error;

    return class_dev;

error:
    kfree(class_dev);
    return ERR_PTR(retval);
}
<think>好的,用户现在想了解`class_create`和`device_create`函数的关系。之前他问了关于`write`和`kernel_write`的区别,现在向Linux内核模块中的设备模型相关函数。这说明用户可能在进行内核模块开发,或者在学习如何创建设备节点。 首先,我需要回忆这两个函数的作用。记得在Linux设备模型中,`class_create`用于创建一个设备类,而`device_create`则是在该类下创建设备。这可能涉及到sysfs中的目录结构,比如在/sys/class下出现对应的类,然后在类下生成设备目录。 接下来要考虑用户可能的背景。用户可能是刚开始接触内核模块开发的新手,不太清楚设备模型中的层次结构。所以需要解释清楚类和设备的关系,以及这两个函数如何配合使用。用户可能已经知道如何注册字符设备,但需要进一步了解如何让设备出现在用户空间,方便udev或mdev自动创建设备节点。 需要确认这两个函数的调用顺序,应该是先调用`class_create`创建类,再调用`device_create`在该类下创建设备。同时,这两个函数在错误处理上需要注意,比如`class_create`失败时需要处理,而`device_create`失败时可能需要撤销之前的操作。 另外,用户可能想知道为什么需要这两个步骤,而不仅仅是注册一个设备。这时候需要解释设备类的作用,比如统一管理设备,提供统一的属性接口,以及自动创建设备节点的机制。这样用户就能理解分开这两个函数的意义。 可能还需要提到实际应用中的例子,比如在字符设备驱动中,先创建类,然后在probe函数中创建设备。这样当模块加载时,类被创建,设备被添加到sysfs,进而触发用户空间的udev规则,生成/dev下的设备文件。 还要注意版本兼容性,不同内核版本中这两个函数的参数可能有所变化,比如返回类型或宏定义的名称。需要提醒用户查阅对应版本的内核文档,避免编译错误。 最后,总结两者的关系和调用流程,确保用户能够清晰地理解它们在设备驱动开发中的作用,以及如何正确使用它们来管理设备节点。</think>在 Linux 内核驱动开发中,`class_create` 和 `device_create` 是用于 **设备模型(Device Model)** 的关键函数,二者协同工作以实现设备在 sysfs 中的动态管理和用户空间设备节点的自动创建(如 `/dev/` 下的节点)。以下是它们的详细关系和区别: --- ### **1. `class_create` 函数** - **作用**: 创建一个 **设备类(Class)**,表示一类具有相同特性的设备(如所有输入设备、USB设备等)。类在 sysfs 中表现为 `/sys/class/` 下的一个目录(例如 `/sys/class/my_class/`)。 - **参数**: ```c struct class *class_create(const char *name); ``` - `name`:类名(会在 `/sys/class/` 下生成同名目录)。 - **返回值**: 成功返回 `struct class *` 指针,失败返回 `ERR_PTR()` 错误码。 - **特点**: - 类的生命周期需要手动管理:驱动加载时创建,卸载时通过 `class_destroy` 销毁。 - 类为设备提供统一的属性接口(可通过 `class_attr_*` 添加属性)。 --- ### **2. `device_create` 函数** - **作用**: 在指定的设备类下 **创建设备对象**,并在 sysfs 中生成对应的设备目录(如 `/sys/class/my_class/my_device/`)。同时触发用户空间的 `udev` 或 `mdev` 机制,自动在 `/dev/` 下创建设备节点。 - **参数**: ```c struct device *device_create( struct class *class, // 所属的类(由 class_create 返回) struct device *parent, // 父设备(通常为 NULL) dev_t devt, // 设备号(主次设备号组合) void *drvdata, // 驱动私有数据 const char *fmt, ... // 设备名称格式(如 "mydevice%d", minor) ); ``` - **返回值**: 成功返回 `struct device *` 指针,失败返回 `ERR_PTR()` 错误码。 - **特点**: - 设备节点(如 `/dev/mydevice0`)的创建依赖于内核与用户空间工具(如 `udev`)的协作。 - 设备生命周期由驱动管理:加载时创建,卸载时通过 `device_destroy` 销毁。 --- ### **二者的关系** 1. **层次关系**: - `class_create` 定义了一个逻辑上的设备类别(如键盘、传感器)。 - `device_create` 在该类别下注册具体的设备实例(如 `/dev/keyboard0`)。 2. **依赖关系**: - 必须先调用 `class_create` 创建类,再调用 `device_create` 创建设备。 - 类的存在是设备注册到 sysfs 和用户空间的前提。 3. **Sysfs 结构**: ```bash /sys/class/ └── my_class/ # class_create 创建的类 └── my_device/ # device_create 创建的设备 ├── dev # 设备号(主次设备号) ├── subsystem -> ../../class/my_class └── uevent # 用户空间事件触发点 ``` --- ### **典型使用流程** ```c // 1. 创建设备类(通常在模块初始化函数中) static struct class *my_class; my_class = class_create(THIS_MODULE, "my_class"); // 2. 创建设备(结合设备号分配) dev_t devt = MKDEV(major, minor); device_create(my_class, NULL, devt, NULL, "mydevice%d", minor); // 3. 销毁流程(在模块退出函数中) device_destroy(my_class, devt); class_destroy(my_class); ``` --- ### **实际应用场景** - **字符设备驱动**: 结合 `register_chrdev` 注册字符设备后,通过 `class_create` 和 `device_create` 自动生成 `/dev/` 节点。 - **平台设备驱动**: 在 `probe` 函数中动态创建设备节点。 - **热插拔设备**: 当设备插入时,内核触发 `device_create`,用户空间工具自动响应。 --- ### **注意事项** 1. **内核版本兼容性**: - 在旧内核中,`class_create` 可能命名为 `class_create_module`。 - 新内核(如 5.x+)中参数可能略有变化(例如返回类型为 `struct class *`)。 2. **错误处理**: - 必须检查 `class_create` 和 `device_create` 的返回值,避免内核崩溃。 3. **用户空间依赖**: - `/dev/` 节点生成需要用户空间工具(如 `udev` 或 `mdev`)的支持,需确保它们已配置。 --- ### **总结** - `class_create`:定义设备类别,建立 sysfs 中的类目录。 - `device_create`:在类下注册具体设备,触发用户空间设备节点的生成。 - **二者协作**:实现内核驱动与用户空间设备节点的动态关联,简化驱动开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值