sysfs_create_group创建sysfs接口

在调试驱动,可能需要对驱动里的某些变量进行读写,或函数调用。可通过sysfs接口创建驱动对应的属性,使得可以在用户空间通过sysfs接口的show和store函数与硬件交互;

Syss接口可通过sysfs_create_group()来创建,如果设备驱动要创建,需要用到函数宏DEVICE_ATTR;

另外总线对应BUS_ATTR、设备驱动对应DRIVER_ATTR、类(class)对应CLASS_ATTR,均在kernel/include/linux/device.h下定义:

1 1 //下面的show和store只是简单举例 2 2 static ssize_t gpio_show(struct device *d, struct device_attribute*attr, char *buf) 3 3 { 4 4 printk("gpio_show()\n"); 5 5 returnpr_info("store\n"); 6 6 } 7 7 8 8 static ssize_t gpio_store(struct device *d, struct device_attribute *attr,const char *buf,size_t count) 9 9 { 1010 printk("gpio_store()\n"); 1111 returnpr_info("store\n"); 1212 } 1313 1414 //用DEVICE_ATTR宏创建属性gpio文件,如果show()或是store()没有功能,就以NULL代替 1515 static DEVICE_ATTR(gpio, S_IWUSR |S_IRUGO, gpio_show, gpio_store); 1616 1717 //属性结构体数组最后一项必须以NULL结尾。 1818 static struct attribute *gpio_attrs[] = { 1919 &dev_attr_gpio.attr, 2020 NULL 2121 };

DEVICE_ATTR:

DEVICE_ATTR 的定义DEVICE_ATTR(_name,_mode, _show, _store);可知这里gpio是name,mode是S_IWUSR |S_IRUGO,读操作_show是gpio_show函数,写操作_store 是gpio_store函数;

因为:

11 #define DEVICE_ATTR(_name, _mode, _show, _store) \ 22 struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

device_attribute:

11 /* interface for exporting device attributes */ 22 struct device_attribute { 33 struct attribute attr; 44 ssize_t (*show)(struct device *dev, struct device_attribute *attr, 55 char *buf); 66 ssize_t (*store)(struct device *dev, struct device_attribute *attr, 77 const char *buf, size_t count); 88 };

Mode是权限位,在kernel/include/uapi/linux/stat.h;

1 1 #define S_IRWXU 00700 //用户可读写和执行 2 2 #define S_IRUSR 00400//用户可读 3 3 #define S_IWUSR 00200//用户可写 4 4 #define S_IXUSR 00100//用户可执行 5 5 6 6 #define S_IRWXG 00070//用户组可读写和执行 7 7 #define S_IRGRP 00040//用户组可读 8 8 #define S_IWGRP 00020//用户组可写 9 9 #define S_IXGRP 00010//用户组可执行 1010 1111 #define S_IRWXO 00007//其他可读写和执行 1212 #define S_IROTH 00004//其他可读 1313 #define S_IWOTH 00002//其他可写 1414 #define S_IXOTH 00001//其他可执行

device_attribute结构体

为了使对属性的读写变得有意义,一般将attribute结构嵌入到其他数据结构中。子系统通常都会定义自己的属性结构,并且提供添加和删除属性文件的包装函数,比如设备属性结构体定义:

11 /* interface for exporting device attributes */ 22 struct device_attribute { 33 struct attribute attr; 44 ssize_t (*show)(structdevice *dev, struct device_attribute *attr, 55 char*buf); 66 ssize_t (*store)(structdevice *dev, struct device_attribute *attr, 77 const char *buf, size_t count); 88 };

2.     定义attribute属性结构体数组到属性组中:

1 1 static const struct attribute_group gpio_attr_grp = { 2 2 .attrs = gpio_attrs, 3 3 } 4 4 我们这里只有一个属性结构体数组只有一个成员,可以有多个,比如: 5 5 static struct attribute *gpio_keys_attrs[] = { 6 6 &dev_attr_keys.attr, 7 7 &dev_attr_switches.attr, 8 8 &dev_attr_disabled_keys.attr, 9 9 &dev_attr_disabled_switches.attr, 1010 &dev_attr_test.attr, 1111 NULL, 1212 };

属性attribute结构体定义:

11 struct attribute { 22 const char *name; 33 umode_t mode; 44 #ifdef CONFIG_DEBUG_LOCK_ALLOC 55 bool ignore_lockdep:1; 66 struct lock_class_key *key; 77 struct lock_class_key skey; 88 #endif 99 };

创建sysfs接口后,就可以在adb shell 终端查看到和操作接口了。当我们将数据 echo 到接口中时,在用户空间完成了一次 write 操作,对应到 kernel ,调用了驱动中的”store”。当我们cat一个接口时则会调用”show” 。这样就建立了 android 层到 kernel 的桥梁,操作的细节在”show”和”store” 中完成的。

3.     创建属性文件的sysfs接口:

11 ret = sysfs_create_group(&pdev->dev.kobj,&gpio_attr_grp); 22 sysfs_create_group()在kobj目录下创建一个属性集合,并显示集合中的属性文件。如果文件已存在,会报错。 33 44 //删除接口 55 sysfs_remove_group(&pdev->dev.kobj,&gpio_keys_attr_group); 66 sysfs_remove_group()在kobj目录下删除一个属性集合,并删除集合中的属性文件
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

swap空间的增减方法

(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap