|
输入系统
常见的输入设备有键盘、鼠标、遥控杆、书写板、触摸屏等等,用户通过这些输入设备与Linux系统进行数据交换。
内核中怎样表示一个输入设备
- // include/linux/input.h
- struct input_dev {
- const char *name; //设备名称
- const char *phys; //设备物理路径
- const char *uniq; //设备唯一标识码
- struct input_id id;
- unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
- unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //支持什么类型的输入事件
- unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; //支持按键输入事件的话,支持哪些按键(键盘)
- unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; //支持相对位移事件的话,支持哪些
- unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
- unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
- unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
- unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
- unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
- unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
-
- .......
-
- };
复制代码 查看所有的输入设备:查看输入设备的信息:- cat /proc/bus/input/devices
复制代码 得到如下信息:- [root@imx6ull:~]# cat /proc/bus/input/devices
- I: Bus=0019 Vendor=0000 Product=0000 Version=0000
- N: Name="20cc000.snvs:snvs-powerkey"
- P: Phys=snvs-pwrkey/input0
- S: Sysfs=/devices/soc0/soc/2000000.aips-bus/20cc000.snvs/20cc000.snvs:snvs-powerkey/input/input0
- U: Uniq=
- H: Handlers=kbd event0 evbug
- B: PROP=0
- B: EV=3
- B: KEY=100000 0 0 0
- I: Bus=0018 Vendor=dead Product=beef Version=28bb //设备ID(定义在input.h的struct input_id结构体)
- N: Name="goodix-ts" //名称
- P: Phys=input/ts //物理地址
- S: Sysfs=/devices/virtual/input/input1 //sys系统地址
- U: Uniq= //标识号(无)
- H: Handlers=event1 evbug
- B: PROP=2 //设备属性
- B: EV=b //支持何种输入事件
- B: KEY=1c00 0 0 0 0 0 0 0 0 0 0 //设备具有的键
- B: ABS=6e18000 0
- I: Bus=0019 Vendor=0001 Product=0001 Version=0100
- N: Name="gpio-keys"
- P: Phys=gpio-keys/input0
- S: Sysfs=/devices/soc0/gpio-keys/input/input2
- U: Uniq=
- H: Handlers=kbd event2 evbug
- B: PROP=0
- B: EV=3
- B: KEY=c
复制代码 APP可以获得什么数据
- // include/linux/input.h
- struct input_value {
- __u16 type; //当前数据的事件类型
- __u16 code; //当前事件类型下的哪一个事件
- __s32 value; //
- };
复制代码 Type的内容:- // include/uapi/linux/input-event-codes.h
- /*
- * Event types
- */
- #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)
复制代码 code的内容(以EV_KEY举例)- // include/uapi/linux/input-event-codes.h
- #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
复制代码 获取输入设备信息实例
两个ioctl的request参数说明(input.h)
request说明EVIOCGID返回输入设备IDEVIOCGBIT(ev,len)获取输入设备支持的事件类型列表ev值的说明:ev参数表示要获取的事件类型,它是一个整数值
- 当ev=0,表示要获取输入设备支持的所有事件类型列表,包括键盘事件、鼠标事件、相对事件、绝对事件、事件同步、杂项事件等。
- 当ev=1,表示要获取输入设备支持的键盘事件类型列表。
- 当ev=2,表示要获取输入设备支持的相对事件类型列表。
EVIOCGBIT的iotcl调用说明:必须使用- len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit);
- //len是evbit的实际读取大小,如果单独使用sizeof(evbit)得到len,将发生段错误
复制代码 源码:
[code]#include #include #include #include #include #include /* 用法:./get_input_info /dev/input/event0 */int main(int argc, char const **argv){ int fd; struct input_id id; int err; unsigned char byte; unsigned int evbit[2]; int i; int bit; unsigned int len; char *ev_names[] = { "EV_SYN ", "EV_KEY ", "EV_REL ", "EV_ABS ", "EV_MSC ", "EV_SW ", "NULL ", "NULL ", "NULL ", "NULL ", "NULL ", "NULL ", "NULL ", "NULL ", "NULL ", "NULL ", "NULL ", "EV_LED ", "EV_SND ", "NULL ", "EV_REP ", "EV_FF ", "EV_PWR ", }; if(argc != 2) { printf("Usage: %s \n", argv[0]); return -1; } fd = open(argv[1], O_RDWR); if(fd == -1) { printf("can not open %s\n", argv[1]); return -1; } err = ioctl(fd, EVIOCGID, &id); //返回输入设备ID if(err == 0) { printf("bustype = 0x%x\n", id.bustype ); printf("vendor = 0x%x\n", id.vendor ); printf("product = 0x%x\n", id.product ); printf("version = 0x%x\n", id.version ); } len = ioctl(fd, EVIOCGBIT(0,sizeof(evbit)), evbit); //返回输入事件类型 printf("support ev type:\n"); for(i = 0;i < len;i++) { byte = ((unsigned char *)evbit); for(bit = 0;bit < 8;bit++) { if(byte & (1 |
|