DEVICE_ATTR 详解

56 篇文章 5 订阅
42 篇文章 2 订阅
【官方文档】
    官方描述文档路径为 /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_head	entry;         // 连接到kset建立层次结构
	struct kobject		*parent;       // 指向父节点,面向对象的层次架构
	struct kset		*kset;        
	struct kobj_type	*ktype;        // 属性文件</span>
	struct sysfs_dirent	*sd;
	struct kref		kref;          // 引用计数
	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_t			mode;     // 属性文件的访问权限,例如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》
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DEVICE_ATTR是一个宏,用于声明设备属性文件的属性。这个宏在Linux内核的device.h头文件中定义。它的语法如下: #define DEVICE_ATTR(_name, _mode, _show, _store) 其中,_name是属性文件的名称,_mode是属性文件的权限,_show是从属性文件读取数据时调用的函数,_store是向属性文件写入数据时调用的函数。 属性文件的权限值是一个4位数,类似于0644,其中每一位表示SUID/GUID User Group Others的权限。具体权限值的含义如下: - 400:拥有者能够读,其他任何人不能进行任何操作。 - 644:拥有者都能够读,但只有拥有者可以编辑。 - 660:拥有者和组用户都可读和写,其他人不能进行任何操作。 - 664:所有人都可读,但只有拥有者和组用户可编辑。 - 700:拥有者能够读、写和执行,其他用户不能任何操作。 - 744:所有人都能读,但只有拥有者才能编辑和执行。 - 755:所有人都能读和执行,但只有拥有者才能编辑。 - 777:所有人都能读、写和执行(该设置通常不是好想法)。 在使用DEVICE_ATTR宏定义属性文件时,需要提供一个show函数和一个store函数。show函数在读取属性文件数据时被调用,而store函数在写入属性文件数据时被调用。 例如,我们可以使用DEVICE_ATTR宏来定义一个名为my_device_test的设备属性文件,其权限被设置为用户可写和用户可读,并指定了show_my_device和set_my_device两个函数来处理读写操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Linux-DEVICE_ATTR()介绍及使用示例](https://blog.csdn.net/Wang20122013/article/details/121948508)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [DEVICE_ATTR 详解](https://blog.csdn.net/Qidi_Huang/article/details/51102994)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值