嵌入式系统内核配置gpio 作为按键来输入

嵌入式系统内核配置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作为按键功能应用层的使用方式及内核的配置方法。

 

你可能感兴趣的:(嵌入式系统)