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 类似,但更加简洁。

相关推荐
sunoo-22911 小时前
【C 语言标准 IO 入门】第二天学习笔记:文件操作核心函数 + 实战案例 + 踩坑合集
linux·笔记·vscode·学习
波特率11520011 小时前
pthread库函数解析
linux·线程·pthread
Escalating_xu12 小时前
【Linux线程同步】从数据竞争到 mutex、条件变量与生产者消费者(上篇)
android·java·linux
晨曦花锦12 小时前
Vim基础操作与Ollama模型管理,顺便配置Nginx反向代理
linux·nginx·编辑器·vim
Eloudy12 小时前
Ubuntu 22.04 从源码编译安装 ROS 2 Jazzy 笔记
linux·笔记·ubuntu
raindayinrain12 小时前
深入理解Linux内核-页表,TLB,高速缓存,性能优化
linux·性能优化·高速缓存·页表·tlb
秣宇13 小时前
银河麒麟服务器操作系统关闭 Swap 分区
linux·运维·服务器·github·kylin
RisunJan13 小时前
Linux命令-usernetctl(已废弃 - 通过 usermode-helper 控制网络接口的包装器)
linux·运维·服务器
码农爱学习13 小时前
ClaudeCode搭配DeepSeek在Windows和Linux中的安装教程
linux·运维·windows
阿昭L13 小时前
Linux文件IO
linux