输入设备应用编程

输入设备应用编程

基于正点原子I.mx6u ALPHA V2.1开发板,记录自己的学习过程

1、如何找到输入设备对应的文件

在Linux中所有的输入设备都会在==/dev/input/==中,使用od命令后,再操作相应的输入设备,会在终端打印信息若,成功打印信息,这就是输入设备对应的文件

#方法一:
sudo od -x /dev/input/xxx
#方法二:在这个文件里可以看到所有注册的input
cat /proc/bus/input/devices

2、读取设备的流程

  1. 应用程序打开/dev/input/event0 设备文件;
  2. 应用程序发起读操作(譬如调用 read),如果没有数据可读则会进入休眠(阻塞 I/O 情况下);
  3. 当有数据可读时,应用程序会被唤醒,读操作获取到数据返回;
  4. 应用程序对读取到的数据进行解析。

##3、 解析数据

每一次 read 操作获取的都是一个 struct input_event 结构体类型数据

#include <linux/input.h>
struct input_event {
struct timeval time;
	__u16 type;				//type 用于描述发生了哪一种类型的事件(对事件的分类)
	__u16 code;				//表示该类事件中的哪一个具体事件
	__s32 value;			//内核每次上报事件都会向应用层发送一个数据 value
};


#include "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)

数据同步:上面我们提到了同步事件类型 EV_SYN, 同步事件用于实现同步操作、告知接收者本轮上报的数据已
经完整。应用程序读取输入设备上报的数据时,一次 read 操作只能读取一个 struct input_event 类型数据,譬如对于触摸屏来说,一个触摸点的信息包含了 X 坐标、 Y 坐标以及其它信息, 对于这样情况,应用程序需
要执行多次 read 操作才能把一个触摸点的信息全部读取出来, 这样才能得到触摸点的完整信息。
那么应用程序如何得知本轮已经读取到完整的数据了呢?其实这就是通过同步事件来实现的, 内核将
本轮需要上报、发送给接收者的数据全部上报完毕后,接着会上报一个同步事件,以告知应用程序本轮数据
已经完整、 可以进行同步了。

4、触摸屏应用编程

触摸屏属于绝对位移设备(type=ev_ABS),分为单点触摸和多点触摸两种。单点触摸的code以ABS_XXX命名;多点触摸的code以ABS_MT_XXX命名

触摸屏设备除了上报绝对位移事件之外,还可以上报按键类事件和同步类事件。 当手指点击触摸屏或手指从触
摸屏离开时,此时就会上报按键类事件, 用于描述按下触摸屏和松开触摸屏; 具体的按键事件为BTN_TOUCH(code=0x14a,也就是 330) ,当然,手指在触摸屏上滑动不会上报 BTN_TOUCH 事件。

单点触摸设备事件上报顺序

# 点击触摸屏时
BTN_TOUCH
ABS_X
ABS_Y
SYN_REPORT
# 滑动
ABS_X
ABS_Y
SYN_REPORT
# 松开
BTN_TOUCH
SYN_REPORT

多点触摸

多点触摸设备使用多点触摸(MT)协议上报各个触摸点的数据, MT 协议分为两种类型: Type A 和 Type B, 主要使用Type B,每个触摸点会与ABS_MT_SLOT(47) 事件关联,ABS_MT_TRACTKING_ID 事件则用于触摸点的创建、替换和销毁工作

获取触摸屏信息

#include <sys/ioctl.h>

int ioctl(int fd, unsigned long request, ...);

在 input.h 头文件有一些宏定义

#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo)

通过这个宏可以获取到触摸屏 slot(slot<0>表示触摸点 0、 slot<1>表示触摸点 1、 slot<2>表示触摸点 2,以此类推!)的取值范围, 可以看到使用该宏需要传入一个 abs 参数,该参数表示为一个 ABS_XXX 绝对位移事件,譬如 EVIOCGABS(ABS_MT_SLOT)表示获取触摸屏的 slot 信息,此时 ioctl()函数的第三个参数是
一个 struct input_absinfo *的指针,指向一个 struct input_absinfo 对象,调用 ioctl()会将获取到的信息写入到
struct input_absinfo 对象中。

struct input_absinfo {
	__s32 value; //最新的报告值
	__s32 minimum; //最小值
	__s32 maximum; //最大值
	__s32 fuzz;
	__s32 flat;
	__s32 resolution;
};

//获取触摸屏支持的最大触摸点数
max_slots = info.maximum + 1 - info.minimum;
__s32 fuzz;
__s32 flat;
__s32 resolution;

};

//获取触摸屏支持的最大触摸点数
max_slots = info.maximum + 1 - info.minimum;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值