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 //下面的show和store只是简单举例
2 static ssize_t gpio_show(struct device *d, struct device_attribute*attr, char *buf)
3 {
4 printk("gpio_show()n");
5 returnpr_info("storen");
6 }
7
8 static ssize_t gpio_store(struct device *d, struct device_attribute *attr,const char *buf,size_t count)
9 {
10 printk("gpio_store()n");
11 returnpr_info("storen");
12 }
13
14 //用DEVICE_ATTR宏创建属性gpio文件,如果show()或是store()没有功能,就以NULL代替
15 static DEVICE_ATTR(gpio, S_IWUSR |S_IRUGO, gpio_show, gpio_store);
16
17 //属性结构体数组最后一项必须以NULL结尾。
18 static struct attribute *gpio_attrs[] = {
19 &dev_attr_gpio.attr,
20 NULL
21 };
DEVICE_ATTR:
DEVICE_ATTR 的定义DEVICE_ATTR(_name,_mode, _show, _store);可知这里gpio是name,mode是S_IWUSR |S_IRUGO,读操作_show是gpio_show函数,写操作_store 是gpio_store函数;
因为:
1 #define DEVICE_ATTR(_name, _mode, _show, _store)
2 struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
device_attribute:
1 /* interface for exporting device attributes */
2 struct device_attribute {
3 struct attribute attr;
4 ssize_t (*show)(struct device *dev, struct device_attribute *attr,
5 char *buf);
6 ssize_t (*store)(struct device *dev, struct device_attribute *attr,
7 const char *buf, size_t count);
8 };
Mode是权限位,在kernel/include/uapi/linux/stat.h;
1 #define S_IRWXU 00700 //用户可读写和执行
2 #define S_IRUSR 00400//用户可读
3 #define S_IWUSR 00200//用户可写
4 #define S_IXUSR 00100//用户可执行
5
6 #define S_IRWXG 00070//用户组可读写和执行
7 #define S_IRGRP 00040//用户组可读
8 #define S_IWGRP 00020//用户组可写
9 #define S_IXGRP 00010//用户组可执行
10
11 #define S_IRWXO 00007//其他可读写和执行
12 #define S_IROTH 00004//其他可读
13 #define S_IWOTH 00002//其他可写
14 #define S_IXOTH 00001//其他可执行
device_attribute结构体
为了使对属性的读写变得有意义,一般将attribute结构嵌入到其他数据结构中。子系统通常都会定义自己的属性结构,并且提供添加和删除属性文件的包装函数,比如设备属性结构体定义:
1 /* interface for exporting device attributes */
2 struct device_attribute {
3 struct attribute attr;
4 ssize_t (*show)(structdevice *dev, struct device_attribute *attr,
5 char*buf);
6 ssize_t (*store)(structdevice *dev, struct device_attribute *attr,
7 const char *buf, size_t count);
8 };
2. 定义attribute属性结构体数组到属性组中:
1 static const struct attribute_group gpio_attr_grp = {
2 .attrs = gpio_attrs,
3 }
4 我们这里只有一个属性结构体数组只有一个成员,可以有多个,比如:
5 static struct attribute *gpio_keys_attrs[] = {
6 &dev_attr_keys.attr,
7 &dev_attr_switches.attr,
8 &dev_attr_disabled_keys.attr,
9 &dev_attr_disabled_switches.attr,
10 &dev_attr_test.attr,
11 NULL,
12 };
属性attribute结构体定义:
1 struct attribute {
2 const char *name;
3 umode_t mode;
4 #ifdef CONFIG_DEBUG_LOCK_ALLOC
5 bool ignore_lockdep:1;
6 struct lock_class_key *key;
7 struct lock_class_key skey;
8 #endif
9 };
创建sysfs接口后,就可以在adb shell 终端查看到和操作接口了。当我们将数据 echo 到接口中时,在用户空间完成了一次 write 操作,对应到 kernel ,调用了驱动中的”store”。当我们cat一个接口时则会调用”show” 。这样就建立了 android 层到 kernel 的桥梁,操作的细节在”show”和”store” 中完成的。
3. 创建属性文件的sysfs接口:
1 ret = sysfs_create_group(&pdev->dev.kobj,&gpio_attr_grp);
2 sysfs_create_group()在kobj目录下创建一个属性集合,并显示集合中的属性文件。如果文件已存在,会报错。
3
4 //删除接口
5 sysfs_remove_group(&pdev->dev.kobj,&gpio_keys_attr_group);
6 sysfs_remove_group()在kobj目录下删除一个属性集合,并删除集合中的属性文件
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- phpMyAdmin 渗透利用总结
- 【C++简明教程】C++基本语法
- 【多目标跟踪】搞不懂MOT数据集,会跑代码有啥用!
- 手工 - 内网信息收集
- 使用ffmpeg压缩视频之烦和fun
- 一文学会 Web Service漏洞挖掘!
- 【实战项目代码分享】计算机视觉入门教程&实战项目代码
- Linux部署DNS服务器
- 【C++简明教程】C++简介与环境配置
- PDF 的各种操作,我用 Python 来实现(附网站和操作指导)
- Python中map()函数用法
- 谈谈不同思路下造就的不同产品与公司形态
- OpenCV 处理中文路径、绘制中文文字的烦恼,这里通通帮你解决!
- 如何快速分析大型系统架构?
- Linux小技巧、文件查找、修改、读取