linux GPIO Key
linux gpio key 实现方式
linux gpio key可以实现两种方式,如果key比较少的话,(1)可以选择单个的gpio作为一个input event来上报,这样的方式的优点是按键比较独立,缺点是如果key比较多会生成比较的input event (2) 正常的话可以定义gpio key, 给不同的gpio选择不同的键值,个人觉得这种方式比较正规,包括遥控按键的上报也是用这种方式。
gpio-key 实现原理
gpio-key是基于input架构实现的通用gpio按键驱动,该驱动是基于platform_driver架构,实现了驱动和设备的分离,符合linux设备驱动模型的基本思想。
代码的驱动部分:
drivers/input/keyboard/gpio_keys.c
这里基本不需要我们修改,只需要我们了解其中的实现流程就好。
代码的dts部分:
主要修改的部分是dts部分,借用网上通用代码。
gpio-keys {
compatible = "gpio-keys";
autorepeat;
pinctrl-names = "default";
pinctrl-0 = <&s8_keys>;
power {
gpios = <XXXXXX GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label = "GPIO Key Power";
debounce-interval = <20>;
};
home {
gpios = <YYYYY GPIO_ACTIVE_LOW>;
linux,code = <KEY_HOME>;
label = "GPIO Key Home";
debounce-interval = <20>;
};
};
&pinctrl {
pinctrl-names = "default";
buttons {
s8_keys: s8-keys {
rockchip,pins = <XXXX &pcfg_pull_up>,
<XXXXXXXX &pcfg_pull_up>;
};
}
1、节点名字为“gpio-keys”。
2、gpio-keys 节点的 compatible 属性值一定要设置为“gpio-keys”。
3、所有的 KEY 都是 gpio-keys 的子节点,每个子节点可以用如下属性描述自己:
gpios:KEY 所连接的 GPIO 信息。
interrupts:KEY 所使用 GPIO 中断信息,不是必须的,可以不写。
label:KEY 名字
linux,code:KEY 要模拟的按键可以直接填数字
可以直接填数字
gpio-key,wakeup:可以被唤醒
debounce-interval:消抖时间
以上就在linux driver端使能了key,接下来可以在hal层读取/dev/
/dev/input/eventX 读取key event的事件了
具体hal读取按键的几种方式,可看我的git源码
网上的 应用代码,没有select
#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();
}