创建 sysfs 设备节点
在开发项目应用过程中需要操作内核中GPIO, 除了应用层直接通过export方式操作外,还可以通过sysfs设备节点方式操作。
具体实现之前可以阅读下 kernel/Documentation/zh_CN/filesystems/sysfs.txt 中关于sysfs相关知识。
sysfs 简介:
sysfs 是一个最初基于 ramfs 且位于内存的文件系统。它提供导出内核数据结构及其属性,以及它们之间的关联到用户空间的方法。
sysfs 始终与 kobject 的底层结构紧密相关。请阅读Documentation/kobject.txt 文档以获得更多关于 kobject 接口的信息。
控制 gpio 来实现 led 驱动,创建一个设备节点 gpio_led,操作节点来控制 GPIO 的电平用以实现对 LED 灯操作,往节点写 1(echo 1 >)就拉高 GPIO 电平亮灯,往节点写 0(echo 0 >)就拉低 GPIO 电平灭灯。
echo 1 > sys 文件 led on xxx_store
echo 0 > sys 文件 led off
cat sys 文件 xxx_show
1. 创建 sys 文件;
2. 定义 xxx_store xxx_show;
添加节点
主要是调用 DEVICE_ATTR 宏这个接口来创建设备节点 gpio_led,这个接口函数在驱动中经常会使用到。
使用DEVICE_ATTR,可以实现驱动在sys目录自动创建文件,我们只需要实现show和store函数即可。然后在应用层就能通过cat和echo命令来对sys创建出来的文件进行读写驱动设备,实现交互。
DEVICE_ATTR的代码框架构成:
DEVICE_ATTR是一个宏,其定义在 include/linux/device.h文件:
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show,_store)
__ATTR宏定义在 include/linux/sysfs.h:
#define __ATTR(_name,_mode,_show,_store) { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
}
struct device_attribute 结构定义在 include/linux/device.h文件:
/* interface for exporting device attributes */
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
};
DEVICE_ATTR宏展开:
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
}
实际上我们在驱动中直接调用 DEVICE_ATTR 这个宏就可以了, 并且在 probe 函数中即可。
调用 device_create_file,device_create_file 定义在 drivers/base/core.c中,声明在include/linux/device.h中,device_create_file 返回 0 代表创建成功。
int device_create_file(struct device *dev, const struct device_attribute *attr)
可参考https://www.cnblogs.com/lifexy/p/9799778.html
添加具体的逻辑实现代码
主要是填充 DEVICE_ATTR这个接口的_show 和_store函数,我们在 shell 状态时,
cat命令时将会调用_show,echo命令时将会调用_store。
例如:
//读函数
static ssize_t demo_show(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", "this is demo");
}//写函数
static ssize_t demo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) {return size;
}
static DEVICE_ATTR(demo, 0664, demo_show, demo_store); //调用DEVICE_ATTR创建设备节点
//在 probe函数中调用:
device_create_file(&pdev->dev, &dev_attr_demo);
代码分析
DEVICE_ATTR 宏
1.创建并初始化一个 struct device_attribute#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
//创建一个struct device_attribute 类型的对象名字叫dev_attr_demo ##字符串连接符
//例如
static DEVICE_ATTR(demo, 0664, demo_show, demo_store);
__ATTR(_name, _mode, _show, _store)#define __ATTR(_name, _mode, _show, _store) { \
.attr = {.name = __stringify(_name), \
.mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
.show = _show, \
.store = _store, \
}struct device_attribute dev_attr_demo= {
.attr = { .name ="demo" .mode=0664 },
.show = demo_show,
.store = demo_store
}struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};2.创建文件
int device_create_file(struct device *device,
const struct device_attribute *entry);
3.删除文件
void device_remove_file(struct device *dev,
const struct device_attribute *attr);
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgjbafi
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13