嵌入式系统内核配置gpio 作为按键来输入.
想修改一下启动logo的背景,这很简单,
1. 找到logo 对应的ppm 文件,修改背景,存储,重新make 生成内核.
2. 将内核及uboot,rootfs 等用烧录工具烧录到flash盘中,然后再升级到系统中,发现按键都不响应了。
gpio 作为按键来使用, 每个按键对应着一个gpio , 当按钮按下时,内核应该发出对应按键keycode被按下事件.
同样,当按键弹起,内核也会发出该健弹起事件.
查看了一下代码, 输入事件是如下定义的
struct input_event {
struct timeval time;
__u16 type; //事件类型,我们关心按键事件
__u16 code; //每一个IO对应一个key code
__s32 value; // 是按下还是抬起
};
再看看gpio口上层(应用层)是如何作为按键来使用的!
a. 从一个文件描述符中读数据(事件数据),分析事件内容后返回什么事件发生,若无事件将被挂起!
void gpio_get_key(int &which)
{
int event_len = sizeof(struct input_event);
struct input_event event;
if(read(gpiokey_fd, &event, event_len) == event_len) {
if(event.type == EV_KEY) {
#ifdef _GPIO_TEST_
printf("event.code:%d, event.value:%d\n",event.code, event.value);
#endif
gStartCode = event.code;
if(event.value == 1) // key press, 也有其它值
{
switch(event.code)
{
case KEY_CODE1:
printf("key code1!\n");
which = 1;
break;
case KEY_CODE2:
printf("key code2!\n");
which = 2;
break;
case KEY_CODE3:
printf("key code3!\n");
which = 3;
break;
case KEY_CODE4:
printf("key code4!\n");
which = 4;
break;
default:
which = 0;
break;
}
}
else if(event.value == 0)
{
switch(event.code)
{
case KEY_CODE4:
printf("key code4 release!\n");
which = 5;
break;
default:
which = 0;
break;
}
}
}
}
}
b. 文件描述符gpiokey_fd 的来历。
gpiokey_fd = open(GPIOKEY_EVENT_PATH, O_RDONLY);
if(gpiokey_fd < 0) {
perror("open gpiokey_event error");
return -1;
}
#define GPIOKEY_EVENT_PATH "/dev/input/event2"
#define KEY_CODE1 171
#define KEY_CODE2 172
#define KEY_CODE3 173
#define KEY_CODE4 174
分析:
gpio作为键盘输入,需要配置使能gpio中断功能, 将这些有中断功能的gpio统一管理
内核发现有gpio 按下后,会形成事件丢到/dev/input/event2设备下
可是现在查看根本没有/dev/input/event2 设备,所以gpiokey_fd 打开失败是-1, 后面read也不会成功.
那么为什么没有这个设备呢?
a. 检查dts 文件,已经在gpio_keys 中配置了gpio引脚, key_code 值,激活方式等,这些没有改变过,应该是好的
b. 检查内核配置文件.config 它需要把gpio-key驱动编译到内核,只要 CONFIG_KEYBOARD_GPIO=y 就可以了.
可以手工直接更改,也可以用make menuconfig来配置.
一看果然是缺这一项
这样对内核配置及对应的内核功能又增加了一层认识!
.config 中 CONFIG_KEYBOARD_GPIO 大概是按如下方式影响代码编译的.
.config 中CONFIG_KEYBOARD_GPIO=y 将影响到
./include/generated/autoconf.h:380:#define CONFIG_KEYBOARD_GPIO 1
将影响到代码生成:
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
本文描述了嵌入式系统gpio作为按键功能应用层的使用方式及内核的配置方法。