linux 宏 DEVICE_ATTR

理解 DEVICE_ATTR

DEVICE_ATTR 是 Linux 内核中用于创建设备属性的宏,通常用于 sysfs 文件系统。通过 sysfs,用户空间的程序可以读取或修改内核中的设备属性。DEVICE_ATTR 宏定义在 <linux/device.h> 头文件中,用于声明和定义一个设备属性。

基本语法

DEVICE_ATTR 宏的基本语法如下:

c 复制代码
DEVICE_ATTR(_name, _mode, _show, _store);
  • _name:属性的名称,会在 /sys/ 下生成对应的文件。
  • _mode:文件的访问权限,例如 0644 表示用户可读写,组和其他用户只读。
  • _show:当用户读取该属性时调用的函数。
  • _store:当用户写入该属性时调用的函数。

使用示例

以下是一个简单的示例,展示如何使用 DEVICE_ATTR:

c 复制代码
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

static char my_value[100] = "default";

static ssize_t show_my_value(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", my_value);
}

static ssize_t store_my_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    strncpy(my_value, buf, sizeof(my_value) - 1);
    my_value[sizeof(my_value) - 1] = '\0';
    return count;
}

static DEVICE_ATTR(my_value, 0644, show_my_value, store_my_value);

static struct device *my_device;

static int __init my_module_init(void)
{
    int ret;
    my_device = &(some_device); // 需要替换为实际的设备结构体
    ret = device_create_file(my_device, &dev_attr_my_value);
    if (ret) {
        printk(KERN_ERR "Failed to create device file\n");
        return ret;
    }
    return 0;
}

static void __exit my_module_exit(void)
{
    device_remove_file(my_device, &dev_attr_my_value);
}

module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");

关键点

  • show 和 store 函数是必须的,分别用于读取和写入属性。如果不需要写入功能,可以将 _mode 设置为只读(如 0444),并将 _store 设置为 NULL。
  • DEVICE_ATTR 宏会生成一个名为 dev_attr_my_value 的结构体变量,其中 my_value 是属性的名称。
  • 使用 device_create_file 和 device_remove_file 来创建和删除属性文件。

访问属性

在用户空间,可以通过以下方式访问该属性:

bash 复制代码
# 读取属性
cat /sys/.../my_value

# 写入属性
echo "new_value" > /sys/.../my_value

注意事项

  • 确保设备的 struct device 结构体已经正确初始化并注册到内核中。
  • 在 store 函数中,必须对用户传入的数据进行验证,防止缓冲区溢出或其他安全问题。
  • 如果设备被卸载或移除,务必删除所有创建的属性文件,否则可能导致内核崩溃。

其他变体

除了 DEVICE_ATTR,Linux 内核还提供了其他类似的宏,例如:

  • DEVICE_ATTR_RO:只读属性,无需提供 store 函数。
  • DEVICE_ATTR_WO:只写属性,无需提供 show 函数。
  • DEVICE_ATTR_RW:读写属性,需要提供 show 和 store 函数。

这些宏的使用方式与 DEVICE_ATTR 类似,但更加简洁。

相关推荐
Zenova EdgeOS24 分钟前
Linux 日志实战:用 journalctl 精准检索与治理工业边缘日志
linux·运维·chrome
Dxy123931021638 分钟前
Linux 压缩解压相关命令介绍
linux·运维·服务器
eleven_4u38 分钟前
QPS如何计算,如何部署架构
java·linux·运维·jvm·中间件
东城居士1 小时前
理解Linux RTC驱动
linux·嵌入式系统
蘑菇小白2 小时前
Linux多线程开发
linux·开发语言·线程
Ruiery2 小时前
Linux 6.6内核内存管理深度解析(十):KSM 同页合并 — 内容去重,把 N 份相同内存合并成 1 份
linux·运维·服务器
Huangjin007_2 小时前
【Linux 系统篇(三十三)】通信(三):System V 共享内存详解
linux·运维·服务器
叼烟扛炮2 小时前
Linux 学习笔记(三十八):从实模式到分页——处理器内存管理的发展史
linux·运维·服务器
叼烟扛炮3 小时前
Linux 学习笔记(三十六):并发进阶——读写锁 vs 自旋锁,到底怎么选?
linux·运维·服务器·笔记·学习
bu_shuo3 小时前
删除Windows资源管理器左侧【此电脑】的Linux企鹅图标
linux·windows