DEVICE_ATTR 详解

来源:互联网 发布:永强集团淘宝店是什么 编辑:程序博客网 时间:2024/05/17 01:17
【官方文档】
    官方描述文档路径为 /linux-4.3/Documentation/driver-model/device.txt
    源码路径为 /linux-4.3/include/linux/device.h

【DEVICE_ATTR 说明】
    原文描述:
    ˉˉˉˉˉˉˉˉˉˉˉˉˉ
    Attributes are declared using a macro called DEVICE_ATTR
    #define DEVICE_ATTR(name, mode, show, store)

    意思是说,宏 DEVICE_ATTR 用来声明 设备属性文件的 属性(听起来像绕口令)。宏的各参数含义如下:
    name    属性文件的名称
    mode    属性文件的权限。这个权限值为类似于 0644 这样的 4 位数,分别表示 SUID/GUID+User+Group+Others
    show    从该属性文件读数据时调用的函数

    store    向该属性文件写数据时调用的函数


    如果往底层继续追踪这 4 个参数,会发现他们实际上最后赋值给了结构体 kobject 中的成员 *ktype 所指向的 kobj_type 类型结构体。而 kobj_type 类型结构体中又有 attribute类型结构体 和 sysfs_ops类型结构体,后 2 个结构体中的成员即 name、mode、show、store。

    这几个结构体常在设备模型中使用,其在内核中的定义如下:

struct kobject {const char*name;         // 名字struct list_headentry;         // 连接到kset建立层次结构struct kobject*parent;       // 指向父节点,面向对象的层次架构struct kset*kset;        struct kobj_type*ktype;        // 属性文件</span>struct sysfs_dirent*sd;struct krefkref;          // 引用计数unsigned int state_initialized:1;      // 初始化状态。使用位域进行定义,表示该变量在内存中只占用一个二进制位。unsigned int state_in_sysfs:1;unsigned int state_add_uevent_sent:1;unsigned int state_remove_uevent_sent:1;unsigned int uevent_suppress:1;};
struct kobj_type {void (*release)(struct kobject *kobj);  // 用于释放 kobject 占用的资源const struct sysfs_ops *sysfs_ops;      // 提供属性文件的方法struct attribute **default_attrs;       // 用于保存类型属性列表(指针的指针)const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);const void *(*namespace)(struct kobject *kobj);};
struct sysfs_ops {ssize_t(*show)(struct kobject *, struct attribute *,char *);    //数据读取ssize_t(*store)(struct kobject *,struct attribute *,const char *, size_t);  //数据保存};
struct attribute {const char*name;    // 属性的名字( 在 kobject 的 sysfs 目录中显示)struct module*owner;   // 指向模块的指针( 如果存在), 此模块负责实现这个属性mode_tmode;     // 属性文件的访问权限,例如S_IRUGO 为只读属性等等。在 <linux/stat.h> 中定义};

    源码描述:
    ˉˉˉˉˉˉˉˉˉˉˉˉˉ
    宏 DEVICE_ATTR 的定义:
    #define DEVICE_ATTR(_name, _mode, _show, _store) \
                 struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

    宏 __ATTR(_name, _mode, _show, _store) 的定义:
    #define __ATTR(_name, _mode, _show, _store) { \
        .attr = {.name = __stringify(_name), .mode = _mode }, \
        .show = _show, \
        .store = _store, \
    }

    结构体 device_attribute 的定义:
    struct device_attribute {
        struct attribute        attr;
        ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
        ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
    };

    由此可见,宏 DEVICE_ATTR的作用实际上是在声明并初始化一个 device_attribute结构体。
    该结构体名称为 dev_attr_##_name (这里使用了预处理命令中 粘贴操作符 的概念)。

【用处】
    使用 DEVICE_ATTR 初始化 device_attribute结构体后,调用 device_create_file() 函数为设备在 sysfs 中创建一个设备属性文件
    device_create_file() 函数体如下:
    /**
     * device_create_file - create sysfs attribute file for device.
     * @dev: device.
     * @attr: device attribute descriptor.
     */
    int device_create_file(struct device *dev, const struct device_attribute *attr)
    {
        int error = 0;
        if (dev)
            error = sysfs_create_file(&dev->kobj, &attr->attr);
        return error;
    }


【举一反三】
    类似的宏还有 DRIVER_ATTR、BUS_ATTR、CLASS_ATTR。

【参考文献】
    [1]《sysfs接口函数的建立_DEVICE_ATTR》
0 0
原创粉丝点击