输入子系统-34

Posted 杨斌并

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了输入子系统-34相关的知识,希望对你有一定的参考价值。

输入子系统(一)

什么是输入子系统?

输入子系统是Linux专门做的一套框架来处理输入事件的,像鼠标,键盘,触摸屏这些都输入设备。但是这些输入设备的类型又都不是一样的,所以为了统一这些输入设备驱动标准应运而生的。
统一了以后,在节点/dev/input下面则匙我们输入设备的节点,如下图所示:

root@ubuntu:~# ls /dev/input/
by-id by-path evento event1
event2event3micemouseonouse1

这些节点对应的则是我们当前系统的输入设备,我们要怎么查看当前系统都有哪些输入设备呢?我们可以使用命令来查看:

cat /proc/bus/input/devices

如下图所示:

rk3399_mid:/storage/F0E9-334E # cat /proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="ff420030.pwm"
P: Phys=gpio-keys/remotectl
S: Sysfs=/devices/platform/ff420030.pwm/input/input0
U: Uniq=
H: Handlers=event0 cpufreq keychord
B: PROP=0
B: EV=3
B: KEY=10000000000 40008800 1e16c000000000 10004ffc

那么我们要怎么确定哪个设备对应哪个节点呢?这里教大家一个简单的方法,我们可以使用命令 hexdump 确定,hexdump命令是Linux下查看二进制文本的工具。这里我给大家举一个例子:
比如我想确定键盘对应的是哪个节点,我就可以使用命令:

hexdump /dev/input/event0或者
hexdump /dev/input/event1
或者hexdump /dev/input/event1
或者
·…

输入完一条命令以后,我们按键盘的上的按键,如果有数据打印出来,则证明当前我们查看的这个节点是键盘这个设备对应的节点。
比如,我现在在Ubuntu上输入命令:

hexdump /dev/input/event1

root@ubuntu:/home/topeet/ybb/android# hexdump /dev/input/event1
0000000 8975 60b4 0000 0000 08fa 000e 0000 0000
0000010 0004 0004 001c 0000 8975 60b4 0000 0000
0000020 08fa 000e 0000 0000 0001 001c 0000 0000
0000030 8975 60b4 0000 0000 08fa 000e 0000 0000
0000040 0000 0000 0000 0000 8982 60b4 0000 0000
0000050 fabe 0004 0000 0000 0004 0004 001d 0000

那么这些打印的信息都是什么意思呢?

  • 我们上报的数据要按照具体的格式上报给输入子系统的核心层,我们的应用就可以通过设备节点来获得按照具体格式上报来的数据了。
  • 封装数据是输入子系统的核心层来帮我们完成的,我们只需要按照指定的类型和这个类型对应的数据来上报给输入子系统的核心层即可。
  • 那我们要怎么指定类型呢?这个我们就需要先了解一下struct input_event这个结构体,这个结构体在include/uapi/linux/input.h文件中,如下图所示:
struct input_event {
    struct timeval time; //上报事件的时间
    _u16 type;//类型
    _u16 code;//编码
    _s32 value; //值
}
  • 这里我们需要注意的是,当我们的type不同的时候,code和value 所代表的意义也是不一样的。
  • 我们可以在这个h文件里面找到tyep的定义,每一个定义都是一个类型,如下图所示:
#define EV_SYN Ox00/*同步事件*/
#define EV_KEY Ox01/*按键事件*
#define EV_REL Ox02/*相对坐标事件*/
#define EV_ABS Ox03/*绝对坐标事供*/
#define EV_MSC Ox04/*杂项
#define Ev_sW ox05*开关事件*/
#define EV_LED Ox11/* LED*/
#define EV_SND Ox12 /* sound声音)*/
#define EV_REP Ox14/*重复事件*/
#define EV FF Ox15/产*压力事件*/
#define EV PWR Ox16*电源事件*/
#define EV FF STATUS ox17/*压力状态事件*/
  • 比如当tpye 等于EV_KEY的时候,那么code的值就为下面类型中的其中一个。include/uapi/linux/input-event-codes.h

#define EV_SYN			0x00
#define EV_KEY			0x01
#define EV_REL			0x02
#define EV_ABS			0x03
#define EV_MSC			0x04
#define EV_SW			0x05
#define EV_LED			0x11
#define EV_SND			0x12
#define EV_REP			0x14
#define EV_FF			0x15
#define EV_PWR			0x16
#define EV_FF_STATUS		0x17
#define EV_MAX			0x1f
#define EV_CNT			(EV_MAX+1)

/*
 * Synchronization events.
 */

#define SYN_REPORT		0
#define SYN_CONFIG		1
#define SYN_MT_REPORT		2
#define SYN_DROPPED		3
#define SYN_MAX			0xf
#define SYN_CNT			(SYN_MAX+1)

/*
 * Keys and buttons
 *
 * Most of the keys/buttons are modeled after USB HUT 1.12
 * (see http://www.usb.org/developers/hidpage).
 * Abbreviations in the comments:
 * AC - Application Control
 * AL - Application Launch Button
 * SC - System Control
 */

#define KEY_RESERVED		0
#define KEY_ESC			1
#define KEY_1			2
#define KEY_2			3
#define KEY_3			4
#define KEY_4			5
#define KEY_5			6
#define KEY_6			7
#define KEY_7			8
#define KEY_8			9
#define KEY_9			10
#define KEY_0			11
#define KEY_MINUS		12
#define KEY_EQUAL		13
#define KEY_BACKSPACE		14
#define KEY_TAB			15
#define KEY_Q			16
#define KEY_W			17
#define KEY_E			18
#define KEY_R			19
#define KEY_T			20
#define KEY_Y			21
#define KEY_U			22
#define KEY_I			23
#define KEY_O			24
#define KEY_P			25
#define KEY_LEFTBRACE		26
#define KEY_RIGHTBRACE		27
#define KEY_ENTER		28

  • 当我们键盘上的按键按下的时候,value如果为1,就代表按下,如果为0,就代表抬起,如果为2,就代码长按。

了解了这些概念以后,我们来看一下这个例子:
当我使用如下命令后,按下键盘上的回车按键,打印以下内容:

hexdump /dev/input/event1

root@ubuntu:/home/topeet/ybb/android# hexdump /dev/input/event1
0000000 8975 60b4 0000 0000 08fa 000e 0000 0000
0000010 0004 0004 001c 0000 8975 60b4 0000 0000
0000020 08fa 000e 0000 0000 0001 001c 0000 0000
0000030 8975 60b4 0000 0000 08fa 000e 0000 0000
0000040 0000 0000 0000 0000 8982 60b4 0000 0000
0000050 fabe 0004 0000 0000 0004 0004 001d 0000
  • 倒数第4列是type
  • 倒数第三列是code
  • 剩下的是value

代码

  • app.c (在Linux上运行)
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

int main(int argc, char * argv[]){
    int  fd;
    int  value;
    fd = open("/dev/input/event1", O_RDWR);
    struct input_event test_event;
    if (fd <0)
    {
        perror("open error \\n");
        return fd;
    }

    while (1)
    {
        read(fd, &test_event, sizeof(test_event));
        printf("type all is %#x \\n", test_event.type);
        if (test_event.type == EV_KEY)
        {
            printf("type KEY is %#x \\n", test_event.type);
            printf("type value is %#x \\n", test_event.value);
             printf("type code is %#x \\n", test_event.code);
        }
        
    }
    
    return 0;
}

gcc app.c -o app

./app

以上是关于输入子系统-34的主要内容,如果未能解决你的问题,请参考以下文章

VS Code配置snippets代码片段快速生成html模板,提高前端编写效率

VSCode自定义代码片段(vue主模板)

VSCode自定义代码片段——声明函数

VSCode自定义代码片段8——声明函数

VSCode自定义代码片段3——url大全

VSCode自定义代码片段3——url大全