yuyy1989 发表于 2025-9-16 19:13

【STM32MP257学习笔记】5.按键输入检测

输入设备种类繁多Linux 系统为了统一管理这些输入设备,实现了一套能兼容所有输入设备的框架:input 子系统,使用 input 子系统驱动的输入设备可以通过统一的数据结构提交给内核,该数据结构包括输入的时间、类型、代号以及具体的键值或坐标,而内则通过/dev/input 目录下的文件接口传递给用户空间。通过下面的命令可以查看当前系统支持的输入设备
cat /proc/bus/input/devices
这个开发板上有两个按键,当按键有动作时会产生输入事件,通过读取/dev/input/event0就能知道哪个按键产生了什么样的动作。在开发 input 子系统驱动时,常常会使用 evtest 工具进行测试,运行 evtest 工具,它列出了系统当前可用的/dev/input/event0输入事件文件,并且列出了这些事件对应的设备名,点击按键可以看到如下输出

在内核源码的/include/uapi/linux/input.h 文件中有着输入事件的结构体定义
struct input_event {
    struct timeval time;
    __u16 type;
    __u16 code;
    __s32 value;
};time:该变量用于记录事件产生的时间戳,既 evtest 输出的 time 值
type:输入设备的事件类型。系统常用的默认类型有 EV_KEY、 EV_REL 和 EV_ABS,分别用于表示按键状态改变事件、相对坐标改变事件及绝对坐标改变事件, EV_SYN 用于分隔事件,无特别意义。
code:事件代号,它以更精确的方式表示事件。例如在 EV_KEY 事件类型中, code 的值常用于表示键盘上具体的按键
value:事件的值。对于 EV_KEY 事件类型,当按键按下时,该值为 1;按键松开时,该值为 0
/dev/input/event*的事件编号与设备的联系不是固定的,它通常按系统检测到设备的先后顺序安排 event 文件的编号,这对编写应用程序控制不太方便,我们可以通过/dev/input/by-path目录查看具体的硬件设备

编程实现通过按键切换LED状态
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <linux/input.h>
#include <linux/input-event-codes.h>

#define KEY_PATH "/dev/input/by-path/platform-gpio-keys-event"
#define LED_PATH_BRI "/sys/class/leds/blue:heartbeat/brightness"

int main(int argc,char **argv)
{
    int keyfd,ledfd;
    u_int8_t ledstate = 0;
    struct input_event event;
    keyfd = open(KEY_PATH,O_RDONLY);
    if(keyfd < 0)
    {
      printf("input event open failed\n");
      return -1;
    }
    ledfd = open(LED_PATH_BRI,O_RDWR);
    if(ledfd < 0)
    {
      printf("led file open failed\n");
      return -1;
    }
    while(1)
    {
      if(read(keyfd, &event, sizeof(event)) == sizeof(event))
      {
            if(event.type != EV_SYN)
            {
                printf("input event code:%d value:%d\n",event.code,event.value);
                if(event.code == BTN_1 && event.value == 0)
                {
                  ledstate = !ledstate;
                  write(ledfd,ledstate==0?"0":"1",1);
                }
                else if(event.code == KEY_WAKEUP && event.value == 0)
                  break;
            }
      }
    }
    close(keyfd);
    close(ledfd);
    printf("test finish\n");
    return 0;
}运行效果


地瓜patch 发表于 2025-10-14 16:56

/dev/input/event0事件通过哪个参数来识别触发的按键编号

星辰大海不退缩 发表于 2025-10-14 22:00

按键输入检测很不错的案例
页: [1]
查看完整版本: 【STM32MP257学习笔记】5.按键输入检测