一、应用程序APP
,访问驱动程序/dev/input/enent1
流程:
假设用户程序直接访问 /dev/input/event0
设备节点,或者使用 tslib 访问设备节点,数据的流程如下:
SIGIO
信号;“struct input_event”结构体
。/* The event structure itself */
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
三、驱动程序同步通知方式
所谓同步,就是“你慢我等你”。
fd = open("/dev/input/event1", O_RDWR | O_NONBLOCK);
设置驱动程序为“O_NONBLOCK”表示“非阻塞”。APP 调用 read 函数读取数据时,如果驱动程序中有数据,那么 APP 的 read函数会返回数据。如果驱动程序中没有数据,APP会阻塞。
#include
#include
#include
#include
int main()
{
const char *inputDevicePath = "/dev/input/event0";
int inputDeviceFd = open(inputDevicePath, O_RDONLY);
if (inputDeviceFd == -1)
{
perror("Failed to open input device");
return 1;
}
struct input_event event;
while (1)
{
ssize_t bytesRead = read(inputDeviceFd, &event, sizeof(event));
if (bytesRead == -1)
{
perror("Failed to read input event");
break;
}
if (bytesRead == sizeof(event))
{
// 处理输入设备事件
printf("Event type: %d, code: %d, value: %d\n", event.type, event.code, event.value);
}
}
close(inputDeviceFd);
return 0;
}
四、驱动程序异步通知方式
所谓异步通知,就是 APP 可以忙自己的事,当驱动程序用数据时它会主动给APP 发信号,这会导致 APP 执行信号处理函数。
驱动程序发信号流程:
struct input_event event;
应用程序要做的事情有这几件:
void my_sig_handler(int sig)
{
struct input_event event;
while (read(fd, &event, sizeof(event)) == sizeof(event))
{
printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);
}
}
signal(SIGIO, my_sig_handler);
fd = open("/dev/input/event0", O_RDWR);
fcntl(fd, F_SETOWN, getpid());
flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | FASYNC);
驱动程序的信号发给APP的关键是:APP 要把自己的pid告诉驱动。 APP 收到后,执行信号处理函数。
参考链接:
Linux中如何获取输入设备(如触摸屏、按键等)的事件信息