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");

关键点

  • showstore 函数是必须的,分别用于读取和写入属性。如果不需要写入功能,可以将 _mode 设置为只读(如 0444),并将 _store 设置为 NULL
  • DEVICE_ATTR 宏会生成一个名为 dev_attr_my_value 的结构体变量,其中 my_value 是属性的名称。
  • 使用 device_create_filedevice_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:读写属性,需要提供 showstore 函数。

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

相关推荐
AlfredZhao12 小时前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户97183563346618 小时前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪19 小时前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠1 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush41 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5201 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩2 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
古城小栈2 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
凡人叶枫2 天前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
2601_961875242 天前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant