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
相关推荐
奋斗的蛋黄8 小时前
网络卡顿运维排查方案:从客户端到服务器的全链路处理
运维·服务器·网络
wanhengidc9 小时前
云手机搬砖 尤弥尔传奇自动化操作
运维·服务器·arm开发·安全·智能手机·自动化
图图图图爱睡觉10 小时前
主机跟虚拟机ip一直Ping不通,并且虚拟机使用ifconfig命令时,ens33没有ipv4地址,只有ipv6地址
服务器·网络·tcp/ip
deephub10 小时前
FastMCP 入门:用 Python 快速搭建 MCP 服务器接入 LLM
服务器·人工智能·python·大语言模型·mcp
lhxcc_fly10 小时前
Linux网络--8、NAT,代理,网络穿透
linux·服务器·网络·nat
摇滚侠10 小时前
Spring Boot3零基础教程,Spring Boot 应用打包成 exe 可执行文件,笔记91 笔记92 笔记93
linux·spring boot·笔记
wow_DG10 小时前
【运维✨】云服务器公网 IP 迷雾:为什么本机看不到那个地址?
运维·服务器·tcp/ip
yuanManGan11 小时前
走进Linux的世界:初识操作系统(Operator System)
android·linux·运维
i_am_a_div_日积月累_11 小时前
jenkins打包报错
运维·rust·jenkins·jenkins打包报错
一个处女座的暖男程序猿11 小时前
2G2核服务器安装ES
服务器·elasticsearch·jenkins