输入子系统-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的主要内容,如果未能解决你的问题,请参考以下文章