【Linux应用编程笔记】输入设备

系列文章目录

【Linux应用编程笔记】GPIO

本系列使用的开发板为正点原子阿尔法IMX6ULL开发板,及根据正点原子所的提供教程学习

文章目录


做什么?

获取到输入设备输入的信息。

一、编写流程

输入设备:

能够产生输入事件的设备,也成为input设备,常见的输入设备有鼠标、键盘、触摸屏、遥控器、电脑画图板等,用户通过输入设备与系统交互。

1、input子系统

Linux系统为了同一管理这些输入设备,实现的一套能够兼容所有输入设备的框架,驱动开发基于input子系统的话,就可以屏幕硬件的差异,向应用层提供一套同一的接口

基于input子系统注册成功的输入设备,都会在/dev/input目录下生成对应的设备节点,设备节点的名称通常是eventX,通过读取这些设备节点就可以获取输入设备上报的数据。

2、读取数据的流程

  1. 打开/dev/input/eventx设备文件
  2. 发起读操作,如果没有数据就休眠(阻塞I/O)
  3. 有数据可读时,唤醒应用程序,读操作获取到数据返回
  4. 应用程序对数据进行解析

3、解析数据

  1. 首先发起读操作获取到的数据是一个struct input_event结构体类型数据
c 复制代码
struct input_event {
	 struct timeval time;//内核记录的上报的时间发生的时间
	 __u16 type;
	 __u16 code;
	 __s32 value;
};
type:描述发生了哪一种类型的事件,具体的宏定义在linux/input.h中EVent types
code:表示该类事件中的具体事件
value:随着code变化而变化,按键事件中的某一个按键时它就是键值,位移事件中的一个方向时它就是坐标值
以上的宏定义放在最后,太多了,放前面一会就看迷糊了。
  1. 数据同步
    同步事件类型:EV_SYN(0),同步事件用于实线同步操作、告知接收者本轮上报的数据已经完整。

由于应用程序读取输入设备上报的数据时,一次read操作只能读取一个struct input_event类型数据,对于触摸屏,一个触摸点至少包括了X坐标和Y坐标信息的情况来说,需要read多次才能将信息全部读完,这时就体现了同步的用处了。

所有的输入设备都需要上报同步事件,code通常是SYN_REPORT(0),value=0。

应用编程

c 复制代码
#include <stdio.h>
#include <stdlib.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[])
{
	 struct input_event in_ev = {0};
	 int fd = -1;
	 /* 校验传参 */
	 if (2 != argc) {
		 fprintf(stderr, "usage: %s <input-dev>\n", argv[0]);
		 exit(-1);
	 }
	 /* 打开文件 */
	 if (0 > (fd = open(argv[1], O_RDONLY))) {
		 perror("open error");
		 exit(-1);
	 }
	 for ( ; ; ) {
		 /* 循环读取数据 */
		 /*设备文件不同于普通文件,读写设备文件之前无需设置读写位置偏移量。*/
		 if (sizeof(struct input_event) != read(fd, &in_ev, sizeof(struct input_event))) {
			 perror("read error");
			 exit(-1);
	 	}
		 printf("type:%d code:%d value:%d\n",
		 in_ev.type, in_ev.code, in_ev.value);
	 }
}

如果不想查找设备节点,可以使用udev规则:通过设备的某些特定属性与设备节点匹配,通过与设备描述符中的信息匹配确定需求的设备节点,修改设备描述符需要在驱动中完成。

设备节点的名称无法指定,由系统动态分配。udev规则只对设备节点名称有效,实际的设备节点路径是由内核管理的,无法直接更改。

libudev库

二、宏定义

1、type

c 复制代码
/*
* 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)

2、code

c 复制代码
//按键事件
#define KEY_RESERVED 0
#define KEY_ESC 1 //ESC 键
#define KEY_1 2 //数字 1 键
#define KEY_2 3 //数字 2 键
#define KEY_TAB 15 //TAB 键
#define KEY_Q 16 //字母 Q 键
#define KEY_W 17 //字母 W 键
#define KEY_E 18 //字母 E 键
#define KEY_R 19 //字母 R 键
··· ···
c 复制代码
//相对位移事件
#define ABS_X 0x00 //X 轴坐标
#define ABS_Y 0x01 //Y 轴坐标
#define ABS_Z 0x02 //Z 轴坐标
#define ABS_RX 0x03
#define ABS_RY 0x04
#define ABS_RZ 0x05
#define ABS_THROTTLE 0x06
#define ABS_RUDDER 0x07
#define ABS_WHEEL 0x08
#define ABS_GAS 0x09
#define ABS_BRAKE 0x0a
#define ABS_HAT0X 0x10
#define ABS_HAT0Y 0x11
#define ABS_HAT1X 0x12
#define ABS_HAT1Y 0x13
#define ABS_HAT2X 0x14
#define ABS_HAT2Y 0x15
#define ABS_HAT3X 0x16
#define ABS_HAT3Y 0x17
#define ABS_PRESSURE 0x18 //按压力
#define ABS_DISTANCE 0x19
#define ABS_TILT_X 0x1a
#define ABS_TILT_Y 0x1b
#define ABS_TOOL_WIDTH 0x1c
#define ABS_VOLUME 0x20
#define ABS_MISC 0x28
#define ABS_MT_SLOT 0x2f/* MT slot being modified */
#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
#define ABS_MT_POSITION_X 0x35 /* Center X touch position */ //X 轴坐标
#define ABS_MT_POSITION_Y 0x36 /* Center Y touch position */ //Y 轴坐标
#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */
#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ ID
#define ABS_MT_PRESSURE 0x3a/* Pressure on contact area */ //按压力
#define ABS_MT_DISTANCE 0x3b /* Contact hover distance */
#define ABS_MT_TOOL_X 0x3c/* Center X tool position */
#define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
#define ABS_MAX 0x3f
#define ABS_CNT (ABS_MAX+1)
c 复制代码
//绝对位移事件
#define ABS_X 0x00 //X 轴
#define ABS_Y 0x01 //Y 轴
#define ABS_Z 0x02 //Z 轴
#define ABS_RX 0x03
#define ABS_RY 0x04
#define ABS_RZ 0x05
#define ABS_THROTTLE 0x06
#define ABS_RUDDER 0x07
#define ABS_WHEEL 0x08
#define ABS_GAS 0x09
#define ABS_BRAKE 0x0a
#define ABS_HAT0X 0x10
#define ABS_HAT0Y 0x11
#define ABS_HAT1X 0x12
#define ABS_HAT1Y 0x13
#define ABS_HAT2X 0x14
#define ABS_HAT2Y 0x15
#define ABS_HAT3X 0x16
#define ABS_HAT3Y 0x17
#define ABS_PRESSURE 0x18
#define ABS_DISTANCE 0x19
#define ABS_TILT_X 0x1a
#define ABS_TILT_Y 0x1b
#define ABS_TOOL_WIDTH 0x1c
......

3、数据同步

c 复制代码
/*
* 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)
相关推荐
准橙考典21 分钟前
怎么能更好的通过驾考呢?
人工智能·笔记·自动驾驶·汽车·学习方法
深圳市青牛科技实业有限公司1 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
hjjdebug2 小时前
linux 下 signal() 函数的用法,信号类型在哪里定义的?
linux·signal
其乐无涯2 小时前
服务器技术(一)--Linux基础入门
linux·运维·服务器
Diamond技术流2 小时前
从0开始学习Linux——网络配置
linux·运维·网络·学习·安全·centos
密码小丑2 小时前
11月4日(内网横向移动(一))
笔记
斑布斑布2 小时前
【linux学习2】linux基本命令行操作总结
linux·运维·服务器·学习
Spring_java_gg2 小时前
如何抵御 Linux 服务器黑客威胁和攻击
linux·服务器·网络·安全·web安全
✿ ༺ ོIT技术༻2 小时前
Linux:认识文件系统
linux·运维·服务器
Mr.谢尔比2 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理