Linux输入设备读取ioctl(EVIOCGKEY())与读取(input_event)

Mer*_*rcy 5 c linux keyboard ioctl keyboard-events

我所有的代码都基于linuxjournal.com上的一篇文章, 这是我基于我的代码编写的文章

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

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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,此代码均有效,但当我按“ a”时除外。

根据输入。hKEY_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);
}
Run Code Online (Sandbox Code Playgroud)

当我按下“ a”键时,上面的代码给出了该打印结果。类型1代码30值1

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

如果有人可以帮助我找出为什么EVIOCGKEY()返回错误的键值的原因,我将不胜感激。谢谢!

Mer*_*rcy 5

好的,我找出了问题所在。

我的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;