Linux的Sysfs 接口

一、sysfs接口

在linux系统中,用户空间访问驱动程序一般是以"设备文件"的方式通过"read/write/ioctl"访问,还有一种方式,可以通过echo的方式来直接控制硬件或者修改驱动,也能为底层驱动提供一个接口便于应用层调用,非常简单。

例如:

复制代码
//打开
echo 1 > /sys/class/my/sensor/my_attr

//关闭
echo 0 > /sys/class/my/sensor/my_attr

二、sysfs接口创建

本文以在sys/class目录下创建节点为例

1、使用DEVICE_ATTR声明一个sys节点

复制代码
static DEVICE_ATTR(led_status, 0600, led_status_show, led_status_store);
static DEVICE_ATTR(my_attr, S_IRUGO | S_IWUSR, my_attr_show, my_attr_store);

my_attr:在sys接口中显示的节点名字

S_IRUGO | S_IWUSR:表示操作这个节点的权限

my_attr_show:使用cat命令查看sys接口时调用的函数

my_attr_store:使用echo命令往sys接口写入内容时调用的函数

2、完成sys节点的读写函数

复制代码
//执行 cat /sys/...时会调用
static ssize_t my_attr_show(struct device *dev, struct device_attribute *attr, char *buf)
{
    int len=-1;
    // 将 mode 的值转换为字符串格式
    len += snprintf(buf, PAGE_SIZE, "%d\n", mode);
    return len;
        return 0;
}

//节点写入内容时,会调用该函数
static ssize_t my_attr_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
 switch (buf[0])//写入的内容会存放到buf中
    {
        case '0':
            mode = 0;
           
            break;

        case '1':
            mode = 1;
           
            break;

        default:
             printk(KERN_INFO "%s: unsupported parameter: %c\n", __func__, buf[0]);
    }

    
    return count;
}

3、创建接口

复制代码
int add_sysfs_interfaces(struct device *dev)
{
         int result;
         struct class *my_class;
        
         my_class = class_create(THIS_MODULE, "my");
         if (IS_ERR(my_class)) {
                 pr_err("Failed to create class\n");
                 return PTR_ERR(my_class);
    }
        
         dev = device_create(my_class, NULL, MKDEV(0, 0), NULL, "sensor");
         result = device_create_file(dev, &dev_attr_my_attr);
         if (result) {
                 pr_err("Failed to create sysfs file\n");
                 class_destroy(my_class);
                 return result;
    }
         return 0;
}

这段代码是一个函数,用于在sysfs文件系统中创建一个名为"sensor"的设备,并添加一个名为"dev_attr_my_attr"的属性文件。

函数的实现逻辑如下:

  1. 创建一个名为"my"的设备类(class)对象,使用class_create()函数进行创建。

  2. 使用device_create()函数基于"my_class"类创建一个名为"sensor"的设备(dev)。

  3. 使用device_create_file()函数为设备添加一个名为"dev_attr_my_attr"的属性文件。

4、在probe函数中调用add_sysfs_interfaces(dev);函数注册sysfs接口

复制代码
static int probe(struct i2c_client *client)
{
        struct device *dev = &client->dev;
        struct device_node *node = dev->of_node;
       
         add_sysfs_interfaces(dev);
}

三、创建结果

1.查看节点:ls查看,会看到我们自己创建的节点my

2.echo写入

复制代码
echo 1 > /sys/class/my/sensor/my_attr

3.cat 查看

复制代码
cat /sys/class/my/sensor/my_attr
相关推荐
寒水馨5 分钟前
Linux下载、安装llama.cpp-b10068(附安装包llama-b10068-bin-ubuntu-vulkan-x64.tar.gz)
linux·ubuntu·llm·llama·本地部署·llama.cpp·推理引擎
玖玥拾3 小时前
Unity 3D 笔记(十四)Unity/C# Socket 网络笔记3
服务器·网络·unity·c#
ziguo11223 小时前
C/C++ 错误处理全解:从 errno 到 C++ 异常
linux·c语言·c++·windows·visual studio
三8444 小时前
使用Samba/NFS实现文件共享/自动挂载共享目录/autofs自动挂载服务
linux·服务器·网络
高铭杰5 小时前
万物皆可KV(2)SurrealDB 存储布局分析
linux·服务器
万事可爱^5 小时前
Claude 新发布的 Opus 5,系统提示语删了 80%,半价还能逼近 Fable 5
android·服务器·数据库·人工智能·claude
玖玥拾5 小时前
Unity 3D 笔记(十七)Unity/C# Socket 网络笔记6
服务器·网络·unity·c#
Jerry小杰5 小时前
运维神器|单端口搞定多台内网SSH!frp端口复用终极教程
运维·ssh
无小道5 小时前
深入解析操作系统文件缓冲区:页缓存、基数树与f_pos的协同设计
linux·缓存·文件缓冲区
Python私教6 小时前
Blender模型导入Godot完整教程:GLB、BLEND与继承场景怎么选
运维·godot·blender