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
相关推荐
雯宝2 小时前
mnt_init 函数
linux
律宏阔8 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔8 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴8 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千8 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei378 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei378 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei378 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
judezh8 小时前
api 容器一直 unhealthy?我把一个 Agent 运行时的健康检查逐条拆了,查出四个问题
运维·docker
GeW8 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux