gpt4 book ai didi

Linux 输入设备事件,如何检索初始状态

转载 作者:IT王子 更新时间:2023-10-29 00:46:35 24 4
gpt4 key购买 nike

我正在使用 gpio-keys设备驱动程序,用于处理运行 Linux 的嵌入式设备中的某些按钮。用户空间中的应用程序只需打开 /dev/input/eventX 并循环读取输入事件。

我的问题是如何获得按钮的初始状态。有一个 ioctl 调用 (EVIOCGKEY) 可用于此,但是如果我先检查它然后开始从 /dev/input/eventX 读取,则没有保证状态在两者之间没有变化的方法。

有什么建议吗?

最佳答案

evdev 设备 queue events直到你 read() 它们,所以在大多数情况下打开设备,执行 ioctl() 并立即开始从它读取事件应该工作。如果驱动程序从队列中删除了一些事件,它 sends you a SYN_DROPPED event ,因此您可以检测发生这种情况的情况。 The libevdev documentation对应该如何处理这种情况有一些想法;按照我的阅读方式,您应该简单地重试,即删除所有未决事件,然后重做 ioctl() 直到没有更多的 SYN_DROPPED 事件。

我使用这段代码来验证这种方法是否有效:

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <string.h>

#define EVDEV "/dev/input/event9"

int main(int argc, char **argv) {
unsigned char key_states[KEY_MAX/8 + 1];
struct input_event evt;
int fd;

memset(key_states, 0, sizeof(key_states));
fd = open(EVDEV, O_RDWR);
ioctl(fd, EVIOCGKEY(sizeof(key_states)), key_states);

// Create some inconsistency
printf("Type (lots) now to make evdev drop events from the queue\n");
sleep(5);
printf("\n");

while(read(fd, &evt, sizeof(struct input_event)) > 0) {
if(evt.type == EV_SYN && evt.code == SYN_DROPPED) {
printf("Received SYN_DROPPED. Restart.\n");
fsync(fd);
ioctl(fd, EVIOCGKEY(sizeof(key_states)), key_states);
}
else if(evt.type == EV_KEY) {
// Ignore repetitions
if(evt.value > 1) continue;

key_states[evt.code / 8] ^= 1 << (evt.code % 8);
if((key_states[evt.code / 8] >> (evt.code % 8)) & 1 != evt.value) {
printf("Inconsistency detected: Keycode %d is reported as %d, but %d is stored\n", evt.code, evt.value,
(key_states[evt.code / 8] >> (evt.code % 8)) & 1);
}
}
}
}

启动后,程序特意等了5秒。在那段时间敲一些键来填充缓冲区。在我的系统上,我需要输入大约 70 个字符才能触发 SYN_DROPPEDEV_KEY 处理代码检查事件是否与 EVIOCGKEY ioctl 报告的状态一致。

关于Linux 输入设备事件,如何检索初始状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27063833/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com