DEVICE_ATTR分析

本文介绍了Linux驱动中DEVICE_ATTR的使用,通过它可在sysfs中创建设备属性文件,实现运行时动态控制设备。DEVICE_ATTR定义的属性文件位于/sys/devices/目录下,而DRIVER_ATTR、BUS_ATTR、CLASS_ATTR分别对应于driver、bus和class目录。属性文件的权限可设定为只读、只写或读写。展示了显示函数和写入函数的通用实现,并详细说明了如何注册属性、创建sysfs接口。最终,通过sysfs_create_group在probe函数中创建接口,实现应用层与内核的交互,其中write和show函数分别对应数据写入和读取操作。

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

使用DEVICE_ATTR,可以在sys fs中添加“文件”,通过修改该文件内容,可以实现在运行过程中动态控制device的目的。
在documentation/driver-model/Device.txt中有对DEVICE_ATTR的详细介绍,这儿主要说明使用方法。
DEVICE_ATTR对应的文件在/sys/devices/目录中对应的device下面,DRIVER_ATTR,BUS_ATTR,CLASS_ATTR分别在driver,bus,class中对应的目录下。

DEVICE_ATTR(_name, _mode, _show, _store)
_name:名称,也就是将在sys fs中生成的文件名称。
_mode:上述文件的访问权限,与普通文件相同,UGO的格式。
_show:显示函数,cat该文件时,此函数被调用。
_store:写函数,echo内容到该文件时,此函数被调用。

模式可以为只读0444,只写0222,或者读写都行的0666。

显示函数的一般实现:

static ssize_t xxx_show(struct device *dev,
 struct device_attribute *attr, char *buf)
{
 return scnprintf(buf, PAGE_SIZE, "%d\n", dma_dump_flag);
}

我自己写的驱动

/**
 * irfpa_show_nucdata() - This function show the nucdata register.
 *
### 关于 `device_create_with_groups` 函数 在设备管理和驱动开发中,`device_create_with_groups` 是一个用于创建新设备实例并关联属性组的重要函数。此函数允许开发者不仅注册一个新的字符或块设备,还可以同时定义一组随设备一起呈现给用户的属性。 #### 函数原型 ```c struct device *device_create_with_groups(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, ...); ``` 参数解释如下: - `class`: 设备所属的类对象指针。 - `parent`: 新建设备的父级设备结构体指针;如果不存在,则传入 NULL。 - `devt`: 表示要分配给这个设备的主要和次要编号组合。 - `drvdata`: 驱动私有数据,通常用来存储与特定硬件有关的信息。 - `groups`: 属性集合数组,这些属性将在 sysfs 中可见,并可用于配置或者监控设备状态。 - `fmt`: 字符串格式化模板,用于指定显示名称或其他描述信息[^1]。 #### 使用案例分析 当编写 Linux 内核模块时,可能希望暴露某些控制接口供用户空间程序访问。通过调用 `device_create_with_groups`, 可以为自定义驱动添加额外的功能入口点。下面是一个简单的例子来展示如何利用该 API 创建带有属性集的新设备节点: ```c #include <linux/device.h> #include <linux/fs.h> static struct class *my_class; static struct device *my_device; // 定义一些可读写的属性... static ssize_t show_example_attr(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf(buf, "%s\n", "example value"); } static ssize_t store_example_attr(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { printk(KERN_INFO "Received data: %.*s\n", (int)count, buf); return count; } DEVICE_ATTR(example, S_IWUSR | S_IRUGO, show_example_attr, store_example_attr); const struct attribute_group my_dev_attrs[] = { __ATTR_NULL, }; void create_my_custom_device(void){ int err; /* Create a new class */ my_class = class_create(THIS_MODULE, "custom_class"); /* Register our custom device with attributes */ my_device = device_create_with_groups(my_class, NULL, MKDEV(MAJOR_NUM, MINOR_NUM), NULL, my_dev_attrs, "custom_device_name"); if(IS_ERR(my_device)){ pr_err("Failed to register device.\n"); goto error_cleanup; } error_cleanup: // Cleanup code here... } ``` 上述代码片段展示了怎样声明两个辅助函数 (`show_example_attr` 和 `store_example_attr`) 来处理来自用户空间的数据请求,并将它们绑定到名为 `example` 的属性上。接着,在 `create_my_custom_device()` 函数内部,先创建了一个新的类别(Class),再使用 `device_create_with_groups` 注册了具有预设属性列表的实际物理设备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值