【问题标题】:Linux input device reading ioctl(EVIOCGKEY()) versus read(input_event)Linux 输入设备读取 ioctl(EVIOCGKEY()) 与 read(input_event)
【发布时间】:2014-05-28 21:54:19
【问题描述】:

我所有的代码都是基于来自 linuxjournal.com 的一篇文章 here is the article I based my code on

我正在编写一个嵌入式应用程序,并试图从键盘读取击键。
这是我正在使用的代码

uint8_t key_b[KEY_MAX/8 + 1];
memset(key_b, 0, sizeof(key_b));
ioctl(fd, EVIOCGKEY(sizeof(key_b)), key_b);

for (yalv = 0; yalv < KEY_MAX; yalv++) {
    if (test_bit(yalv, key_b)) {
        /* the bit is set in the key state */
        printf("  Key 0x%02x ", yalv);
        switch ( yalv)
        {
        case KEY_RESERVED :
            printf(" (Reserved)\n");
            break;
        case KEY_ESC :
            printf(" (Escape)\n");
            break;
        /* other keys / buttons not shown */
        case BTN_STYLUS2 :
            printf(" (2nd Stylus Button )\n");
            break;
        case KEY_1:
            printf("The key 1 was pressed");
            break;
        case KEY_2:
            printf("The key 2 was pressed");
            break;
        case KEY_A:
            printf("The key A was pressed");
            break;
        default:
            printf(" (Unknown key)\n");
        }
    }
}

在大多数情况下,此代码都有效,除非我按“a”。

根据 input.h KEY_A 设置为值 30。但是当我在键盘上按“a”时,它返回值 102 而不是 30。我已经测试了键盘上的其他键,并且似乎键 1-6 返回了 KEY_1、KEY_2 等的预期值,但之后返回的值不正确。

我尝试直接从 /dev/input/eventX 文件中读取偶数。并且事件中返回的代码是预期的。

size_t rb;
/* the events (up to 64 at once) */
struct input_event ev[64];
int yalv;
int keybrdToCapture;

    if((keybrdToCapture = open(EVENT2, O_RDONLY)) == -1) {
    perror("opening device");
    exit(EXIT_FAILURE);
    printf("L2\n");
}

rb=read(keybrdToCapture,ev,sizeof(struct input_event)*64);

for (yalv = 0; yalv < (int) (rb / sizeof(struct input_event)); yalv++)
{
    printf("yalv is %d\n", yalv);
    if (EV_KEY == ev[yalv].type)
        printf("type %d code %d value %d\n",ev[yalv].type,ev[yalv].code, ev[yalv].value);
}

当我按下“a”键时,上面的代码会打印出来。 类型 1 代码 30 值 1

此时您可能想知道为什么我不简单地读取输入事件来读取键盘输入。这是因为 read() 是一个阻塞函数。虽然 ioctl() 没有阻塞。

如果有人能帮我弄清楚为什么 EVIOCGKEY() 返回不正确的键值,我将不胜感激。谢谢!

【问题讨论】:

    标签: c linux keyboard keyboard-events ioctl


    【解决方案1】:

    好的,我知道问题出在哪里了。

    我的 test_bit() 宏写错了。
    基本上,key_b[] 逐位表示键的状态。这意味着如果 KEY_A 被按下,那么第 30 位将被设置为 1。在这种情况下,第 30 位将在 key_b[3] 中显示为值 0x40。

    这里还有几个示例,说明每个键如何映射到 key_b[]。

    • KEY_1 = 2 在 key_b 中表示为 --> key_b[0] = 0x04;
    • KEY_2 = 3 在 key_b 中表示为 --> key_b[0] = 0x08;
    • KEY_3 = 4 在 key_b 中表示为 --> key_b[0] = 0x10;
    • KEY_4 = 5 在 key_b 中表示为 --> key_b[0] = 0x20;
    • KEY_5 = 6 在 key_b 中表示为 --> key_b[0] = 0x40;
    • KEY_6 = 7 在 key_b 中表示为 --> key_b[0] = 0x80;
    • KEY_7 = 8 在 key_b 中表示为 --> key_b[1] = 0x01;
    • KEY_8 = 9 在 key_b 中表示为 --> key_b[1] = 0x02;
    • KEY_9 = 10 在 key_b 中表示为 --> key_b[2] = 0x04;
    • KEY_0 = 11 在 key_b 中表示为 --> key_b[3] = 0x08;

    【讨论】:

    • 您应该在问题中显示旧宏(以使其更完整),然后在您的答案中显示更新。
    • 请分享您的宏我有兴趣在我的机器上尝试此代码
    猜你喜欢
    • 2019-03-10
    • 1970-01-01
    • 2013-10-22
    • 2020-03-11
    • 2015-02-03
    • 1970-01-01
    • 2013-03-26
    • 2011-05-01
    • 2016-03-25
    相关资源
    最近更新 更多