linux驱动模型中的 DEVICE_ATTR 宏分析

本文探讨Linux驱动模型中用于定义设备属性的关键宏DEVICE_ATTR。该宏在'include/linux/device.h'中定义,它创建了一个struct device_attribute类型的结构体实例。通过分析,我们了解到__ATTR、__ATTR_RO等辅助宏的作用,以及struct attribute和struct device_attribute结构体的详细字段,包括mode_t类型的用途。在不同架构下,如ARM,mode_t通常是unsigned short类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

定义于 "include/linux/device.h"  文件中:

 

#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

而 "kernel/include/linux/sysfs.h" 也定义了 __ATTR , 这个宏被多个设备模型的宏使用到了。

 


/**
 * Use these macros to make defining attributes easier. See include/linux/device.h
 * for examples..
 */

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

#define __ATTR_RO(_name) { \
        .attr   = { .name = __stringify(_name), .mode = 0444 }, \
        .show   = _name##_show,                                 \
}

#define __ATTR_NULL { .attr = { .name = NULL } }

#define attr_name(_attr) (_attr).attr.name

 

sysfs.h 也定义了 struct attribute

/* FIXME
 * The *owner field is no longer used.
 * x86 tree has been cleaned up. The owner
 * attribute is still left for other arches.
 */
struct attribute {
        const char              *name;
        struct module           *owner;
        mode_t                  mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
        struct lock_class_key   *key;
        struct lock_class_key   skey;
#endif
};

 

 

struct device_attribute  也 定义于 "include/linux/device.h"  文件中:

 

/* interface for exporting device attributes */
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 这个宏实际上是定义并初始化了一个 名叫 “dev_attr_##_name”的 struct device_attribute 类型的结构体。

 

关于mode_t这个类型

include/linux/types.h:

        typedef __kernel_mode_t            mode_t;


arch/arm/include/asm/posix_types.h

        typedef unsigned short                __kernel_mode_t;

实际上 mode_t 这个类型,就是  unsigned short

include/asm-generic/posix_types.h

            typedef unsigned int   __kernel_mode_t; // 因为我们的平台是arm架构的所以,用的应该是“arch/arm/include/asm/posix_types.h” 这个文件对__kernel_mode_t的定义。

include/asm-generic/types.h

      typedef unsigned short umode_t; 

arch/arm/include/asm/types.h

      typedef unsigned short umode_t;

 

 

<think>好的,我现在需要回答用户关于Linux内核中device_attribute结构体的问题。首先,我得回忆一下自己在内核驱动开发方面的知识。 记得在Linux设备模型中,sysfs文件系统用于暴露设备信息给用户空间,而device_attribute应该和这个相关。结构体通常用来定义设备的属性,这样可以通过sysfs进行访问。不过具体的结构体成员和用法可能需要进一步确认。 接下来,我应该查阅一下内核源码或者相关文档。比如,在Linux内核中,device_attribute的定义可能包含show和store函数指针,以及attr属性。这个结构体应该使用DEVICE_ATTR来创建,这样会生成对应的名称,比如dev_attr_xxx。 用户想知道这个结构体的作用,需要解释它如何将驱动程序的变量或属性暴露到sysfs,允许用户空间读取或设置这些属性。比如,一个设备的状态可以通过cat命令读取,或者通过echo命令修改,这背后就是通过device_attribute实现的。 还要提到创建和注销的方法,比如使用device_create_file和device_remove_file函数。可能还需要举一个例子,说明如何定义一个属性,并实现show和store函数。 需要确保回答结构清晰,分点说明,同时结合实际的例子帮助理解。注意使用中文,避免技术术语的堆砌,让用户能够逐步理解。</think>在Linux内核驱动开发中,`device_attribute`结构体是sysfs接口的核心组成部分。它的作用是将设备驱动程序的参数/属性暴露给用户空间,通过sysfs文件系统实现内核与用户空间的交互。以下是逐步说明: --- ### 一、结构体定义 ```c 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); // 写入属性值的回调函数 }; ``` --- ### 二、核心作用 1. **sysfs接口映射** 每个`device_attribute`对应sysfs中的一个文件,路径通常为`/sys/class/xxx_class/xxx_device/属性名` 2. **双向通信** - `show()`函数:用户执行`cat /sys/.../属性名`时触发,将内核数据输出到用户空间 - `store()`函数:用户执行`echo value > /sys/.../属性名`时触发,将用户输入写入内核 --- ### 三、典型使用场景 #### 步骤1:定义属性 ```c static ssize_t mydev_show(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%d\n", device_status); // 向用户空间输出状态值 } static ssize_t mydev_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; sscanf(buf, "%d", &value); // 从用户输入解析数值 device_status = value; // 更新设备状态 return count; } // 使用定义属性对象 static DEVICE_ATTR(status, 0644, mydev_show, mydev_store); ``` #### 步骤2:注册属性 ```c device_create_file(dev, &dev_attr_status); // 在设备初始化时调用 ``` #### 步骤3:用户空间操作 ```bash # 读取属性 cat /sys/class/my_class/my_device/status # 写入属性 echo 1 > /sys/class/my_class/my_device/status ``` --- ### 四、关键特点 1. **权限控制** 通过`DEVICE_ATTR`的第二个参数设置文件权限(如0644),控制读写权限 2. **动态更新** 修改属性值会实时反馈到驱动状态,适用于调试、参数调整等场景 3. **设备热插拔支持** 属性文件会随着设备的插拔自动创建/删除 --- ### 五、对比其他结构体 | 结构体 | 作用域 | 典型应用场景 | |--------------------|----------------|-------------------| | `device_attribute` | 单个设备 | 设备特定参数 | | `class_attribute` | 设备类 | 类通用属性 | | `driver_attribute` | 驱动 | 驱动全局参数 | 通过这种机制,内核开发者可以灵活地暴露设备控制接口,用户也能直观地通过文件操作与硬件交互。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值