一:Linux GPIO Key 实现方式
linux gpio key可以实现两种方式。
- 可以选择单个的gpio作为一个input event来上报,这样的方式的优点是按键比较独立,缺点是如果key比较多会生成比较多的input event。
- 正常的话可以定义gpio key, 给不同的gpio选择不同的键值,个人觉得这种方式比较正规,包括遥控按键的上报也是用这种方式。无论使用那种方式,通常只需要修改dts就可以了.
二:gpio-key 实现原理
gpio-key是基于input架构实现的通用gpio按键驱动,该驱动是基于platform_driver架构,实现了驱动和设备的分离,符合linux设备驱动模型的基本思想。
代码的驱动部分:
drivers/input/keyboard/gpio_keys.c
代码不需要我们修改,只需要解其中的实现流程就好。
主要修改的部分是dts文件
三:dts修改
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_keys>;
key-a {
label = "Key_A";
gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
gpio-key;
linux,code = <KEY_A>;
};
};
pinctrl_gpio_keys: gpio_keysgrp {
fsl,pins = <
MX6UL_PAD_SD1_DATA0__GPIO2_IO18 0x1f0b1/* key_in */
>;
};
MX6UL_PAD_SD1_DATA0__GPIO2_IO18引脚触发后,就可以在"/dev/input/event1"设置读取"A"。
四:/dev/input/event 读取方法
#define RECOVERY_KEY "/dev/input/event2"
#define RECOVERY_KEY_CODE 115
#define RECOVERY_KEY_PRESS 0
void recovery_key_press_timer(int sig)
{
if (SIGALRM == sig)
{
printf("alarm 6s.\n");
}
return;
}
static void read_recovery_key_event()
{
int fd = -1, ret = -1;
struct input_event ev;
fd = open(RECOVERY_KEY, O_RDONLY);
if (fd < 0)
{
printf("open RECOVERY_KEY event failed.\n");
return;
}
memset(&ev, 0, sizeof(struct input_event));
ret = read(fd, &ev, sizeof(struct input_event));
if (ret != sizeof(struct input_event))
{
printf("read RECOVERY_KEY event failed.\n");
close(fd);
}
if ((RECOVERY_KEY_CODE == ev.code) && (RECOVERY_KEY_PRESS == ev.value))
{
printf("recovery-key press.\n");
alarm(6);
}
else
{
printf("recovery-key release.\n");
alarm(0);
}
close(fd);
}
int main(int argc, char **argv)
{
int rc = 0;
signal(SIGALRM, recovery_key_press_timer);
while (1)
{
read_recovery_key_event();
}
}
五:shell检测
cat /dev/input/event0
点击按钮时显示如下信息: