linux驱动开发:MT协议

因为需要做ctp的驱动,然而又需要学习其他衍生的东西。 因为我们的ctp是支持MT的,所以我们需要研究下多点触摸协议.

这部分的资料网上有,但原汁原味的资料还是在内核目录下 doc/input/mt_touch下面。

协议分为A,B两类。
For devices handling anonymous contacts (type A), the protocoldescribes how to send the raw data for all contacts to the receiver.
Fordevices capable of tracking identifiable contacts (type B), the protocoldescribes how to send updates for individual contacts via event slots.
多点触摸的触摸数据被用单独的ABS_MT event的包顺序发送,这些包不会被 ST(single touch)所识别。所以多点触摸协议可以在ST Protocol的基础上实现。
A类:在每个包的结束需调用 input_mt_sync(),声明一次数据的结束,调用它会发出一个SYN_MT_REPORT事件。来提示接收器接收数据,并准备下一次数据的接收.不能被区分和追踪.
A类设备的内核驱动:需要生成全部的匿名接触数据,一次性上报所有数据,将事件过滤和手指跟踪留给用户空间处理。
可以用ABS_MT_TOUCH_MAJOR和ABS_MT_WIDTH_MAJOR这两个消息上报触摸面积的信息
想象一下,有个人的手指头压着一片玻璃,我们从玻璃这边看手指头。
可以看到2个区域,中间的区域是实际压着的部分,外面那个区域是手指头在玻璃上的投影。
中间区域的直径 就是ABS_MT_TOUCH_MAJOR。
外面大得区域的直径 就是ABS_MT_WIDTH_MAJOR。
现在想象一下,压的力气变大一些,里面的区域就会变大,
ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR 的值就能反映压力的大小,
这个值通常是小于1的。
对于支持压力检测的设备来说,ABS_MT_PRESSURE可以用来替代按压面积,上报压力。
作为MAJOR的补充,触摸点的椭圆形的形状,还可以用MINOR来说明。
MAJOR和MINOR分别表示最长的方向和短一些的那个方向。
最后也可以用ORIENTATION来说明这个椭圆的方位,是不是水平的
对于type A类型的设备而言,触摸点形状的更多特征还可以使用ABS_MT_BLOB_ID消息进行通知。

B类:在传送包开始前需调用input_mt_slot(),调用它会发出一个ABS_MT_SLOT事件,提示接收器接收数据,并更新指定槽的数据。假设支持5点触摸,你同时按下3个点,CTPM会更新这三个点对应槽的数据,以此来区分多个点。
与A类协议的差别:B类协议可通过可被识别的ID来减少发送到用户空间的数据量。需要 ABS_MT_TRACKING_ID,由硬件或者从原始数据中得到.一个非负数的跟踪被认为是一个contact。只有变化的数据被传播,硬件有能力追踪并区分触摸点.用户空间根据接收到的MT(MultiTouch)消息,应用程序更新当前slot的相关属性。
ABS_MT_TOOL_TYPE 和 ABS_MT_TRACKING_ID 会被 input core 在暗地里处理。
因此驱动程序应该调用 input_mt_report_slot_state()
当多点数据包传送完毕后,需要使用input_sync()作为一次数据的结束。这提示接收器接收自上一次上报结束后所产生的所有 事件 和 包,并准备接收下一次的数据和包。

A协议两点触摸消息上报:

ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
SYN_MT_REPORT
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_MT_REPORT
SYN_REPORT
B类协议两点触摸消息上报举例:

ABS_MT_SLOT 0
ABS_MT_TRACKING_ID 45
ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
ABS_MT_SLOT 1
ABS_MT_TRACKING_ID 46
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_REPORT


消息含义

ABS_MT_TOUCH_MAJOR:
触摸点椭圆形最长的那个方向的直径。
这个长度应该是触摸表面的长度单位,
如果触摸表面的X是Y的几倍(矩形),
那么ABS_MT_TOUCH_MAJOR的长度最长为 ( x平方 + y平方 )开根号,也就是对角线的长度。

ABS_MT_TOUCH_MINOR:
触摸点椭圆形短一点的那个方向的直径,如果是圆形,ABS_MT_TOUCH_MINOR可以省略。

ABS_MT_WIDTH_MAJOR:
以触摸面的长度单位为单位的触摸工具,在触摸面上的最长的长度, 这个长度可以理解为触摸工具本身的长度。
触摸点和触摸工具的水平方向假设是一致的
ABS_MT_WIDTH_MINOR:
以触摸面的长度单位为单位的触摸工具,在触摸面上的短一点的长度。如果是圆形可以省略
ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR 的比值用来估计压力的大小。
这些宽度信息也可以用于识别手指还是手掌。(手掌比手指要宽)
ABS_MT_PRESSURE:
触摸点的压力大小,可以是任意衡量单位。对于能够测量压力的设备,可以用来替代TOUCH 和 WIDTH
ABS_MT_DISTANCE:
手指头距离触摸屏表面的距离,以触摸面的长度单位为单位。0意味着已经接触到触摸屏。大于0的数是指手指头在触摸屏上面的高度
ABS_MT_ORIENTATION:
椭圆形触摸点的方向(水平还是垂直)。
它的值应该是有符号的、和旋转方向有关、90度为一个周期的。
取值范围是有符号的,取值范围可以任意定,
但0应该表示为长轴沿着Y方向,负数表示逆时针旋转了,正数表示顺时针旋转了。
长轴方向如果完全变成X方向,那么值就变成最大的了。
如果触摸点的形状是圆形,或者得不到形状信息,可以不上报ABS_MT_ORIENTATION这个消息。
如果设备只能检测到是水平或者是垂直信息,那么ABS_MT_ORIENTATION的值就应该是0或者1。
ABS_MT_POSITION_X:
触摸中心x坐标
ABS_MT_POSITION_Y:
触摸中心y坐标
ABS_MT_TOOL_TYPE:
触摸工具类型,很多内核驱动都不能区分是什么触摸工具,比如是手指还是笔。
如果是这样的内核驱动,那么应该省略掉这个消息。
目前的多点触摸协议支持 MT_TOOL_FINGER 和 MT_TOOL_PEN。
对于 type B 类型的设备,这个消息是在 input core 处理的,
因此驱动程序应该调用 input_mt_report_slot_state() 上报触摸工具的类型。

ABS_MT_BLOB_ID:
将多个坐标消息组合成一个BLOB_ID,用于描述触摸点的形状。
多个点的信息按照一定顺序上报,能够形成一个代表触摸点形状的多边形。
这个是针对 type A 的更底层的信息打包,不要和 高级的 TRACKING ID 弄混了。
大部分 type A 的设备并不支持这个功能,所以驱动程序忽略掉这个消息也没有关系
ABS_MT_TRACKING_ID:
TRACKING ID用来追踪和识别压下到提起期间的某一个触摸点。
TRACKING ID的取值范围应该是足够大的,用于更方便区分是哪一个触摸点。
对于 type B 类型的设备,这个消息是 input core 内部处理的,
驱动程序应该调用 input_mt_report_slot_state() 来告诉input core当前slot是否是无效了

你可能感兴趣的:(内核学习,多点触摸,linux驱动开发)