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

相关推荐
石像鬼₧魂石13 小时前
如何使用Kali Linux自带字典进行密码破解?
linux·运维·服务器
JiMoKuangXiangQu13 小时前
Linux 时间子系统 (1):基础框架概述
linux·timer·时间子系统·timekeeping
天选之女wow13 小时前
【Hard——Day8】65.有效数字、68.文本左右对齐、76.最小覆盖子串
linux·运维·redis·算法·leetcode
精英的英14 小时前
【嵌入式Linux开发】如何在Windows上开发Linux ARM版本QT程序
linux·arm开发·windows
咯哦哦哦哦14 小时前
linux patchelf工具 用法
linux·vscode·编辑器·gcc
努力的小帅14 小时前
Linux_进程控制(Linux入门到精通)
linux·网络·shell·进程创建·linux入门
睡觉然后上课14 小时前
如何让虚拟机运行速度翻倍
linux·arm开发·windows
喜欢你,还有大家14 小时前
DaemonSet && service && ingress的
linux·架构·kubernetes
咸鱼の猫15 小时前
用samba服务器将虚拟机的Ubuntu(磁盘)映射到本地电脑实现文件互传
linux·服务器·ubuntu
小年糕是糕手15 小时前
【C++】C++入门 -- inline、nullptr
linux·开发语言·jvm·数据结构·c++·算法·排序算法