实际项目过程中应用层需要操作内核中GPIO, 除了应用层直接通过export方式操作,具体操作方法[Linux驱动炼成记] 02-用户空间控制GPIO, 还可以通过sysfs设备节点方式操作
具体实现之前可以阅读下 kernel/Documentation/zh_CN/filesystems/sysfs.txt 中关于sysfs相关知识。kernel 4.9
中部分文档已有中文翻译版本
sysfs 是一个最初基于 ramfs 且位于内存的文件系统。它提供导出内核数据结构及其属性,以及它们之间的关联到用户空间的方法。
sysfs 始终与 kobject 的底层结构紧密相关。请阅读Documentation/kobject.txt 文档以获得更多关于 kobject 接口的信息。
这里以按键为例 ,按键的DTS配置如下:
gpio_keypad{
compatible = "gpio_keypad";
status = "okay";
scan_period = <20>;
key_num = <7>;
key_name = "xxxx";
key_code = <115 116 >;
key_pin = <&gpio GPIOZ_3 GPIO_ACTIVE_LOW>,
<&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>;
interrupts = <0 70 1 0 71 2>;
interrupt-names = "irq_keyup", "irq_keydown";
};按键的处理函数以Amlogic中 drivers/amlogic/input/keyboard/gpio_keypad.c 为主
驱动程序模型定义的 device_attribute 结构体如下:
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);
};
int device_create_file(struct device *, const struct device_attribute *);
//按键中sysfs的创建具体实现
ret = device_create_file(dev,&dev_attr_key_trigger_tool);
if (ret){
dev_err(dev, "Failed to device create file: %d\n",ret);
}定义设备属性,通过辅助宏DEVICE_ATTR创建
DEVICE_ATTR宏原型
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
// 按键中具体实现, 相当于在 /sys/devices/platform/gpio_keypad/key_trigger_tool 创建了key_trigger_tool设备节点
static DEVICE_ATTR(key_trigger_tool,S_IRUSR,key_attribute_trigger,NULL);
//设备属性读函数
static ssize_t key_attribute_trigger(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct device_node *node = dev->of_node;
int value = 0;
int key_trigger_pin;
//获取按键DTS中GPIO的描述信息
struct gpio_desc *desc = of_get_named_gpiod_flags(node,"key_pin",1,NULL);
//描述信息转为GPIO引脚编号
key_trigger_pin = desc_to_gpio(desc);
//获取GPIO高低电平
value = gpio_get_value(key_trigger_pin);
//pr_info("%s, key trigger get gpio value : %d pin : %d\n", __func__,value,key_trigger_pin);
//返回GPIO状态
return snprintf(buf,PAGE_SIZE,"%d\n",value);
}到这里为止,驱动中的按键的设备节点已经创建,应用层完全可以操作设备节点
//获取按键的状态
cat /sys/devices/platform/gpio_keypad/key_trigger_tool
执行这条命令之后,就会调用驱动中key_attribute_trigger函数,返回按键GPIO的状态值 其内核中 Documentation/driver-model/device.txt也有类似的例子参考。