Linux 内核驱动--多点触摸接口【转】

简介:

转自:http://blog.csdn.net/joard_yang/article/details/6225937

译自:linux-2.6.31.14/Documentation/input/multi-touch-protocol.txt

简介

  为了使用功能强大的多点触控设备,就需要一种方案去上报用户层所需的详细的手指触摸数据。这个文档所描述的多点触控协议可以让内核驱动程序向用户层上报任意多指的数据信息。

  使用说明

  单点触摸信息是以ABS承载并按一定顺序发送,如BTN_TOUCH、ABS_X、ABS_Y、SYNC。而多点触摸信息则是以ABS_MT承载并按一定顺序发送,如ABS_MT_POSITION_X、ABS_MT_POSITION_Y,然后通过调用input_mt_sync()产生一个 SYN_MT_REPORT event来标记一个点的结束,告诉接收方接收当前手指的信息并准备接收其它手指的触控信息。最后调用 input_sync()函数上报触摸信息开始动作并告诉接收方开始接收下一系列多点触摸信息。

   协议定义了一系列ABS_MT事件,这些事件被分为几大类,充许只应用其中的一部份,多点触摸最小的事件集中应包括ABS_MT_TOUCH_MAJOR、ABS_MT_POSITION_X和 ABS_MT_POSITION_Y,以此来实现多点触摸。如果设备支持ABS_MT_WIDTH_MAJOR这个事件,那么此事件可以提供手指触摸接触面积大小。触摸方向等信息可以由ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION提供。ABS_MT_TOOL_TYPE提供触摸设备的类别,如手或是笔或是其它。最后有些设备可能会支持ABS_MT_TRACKING_ID,用来支持硬件跟踪多点信息,即该点属于哪一条线等。

下面是两点触摸支持的最小事件集序列:

ABS_MT_TOUCH_MAJOR 
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT      //上报第一个点
ABS_MT_TOUCH_MAJOR
ABS_MT_POSITION_X
ABS_MT_POSITION_Y
SYN_MT_REPORT      //上报第二个点
SYN_REPORT         //开始动作

Event 原语

“接触”一词用来描述一个物体直接碰到另一个物体的表面。

ABS_MT_TOUCH_MAJOR描述了主接触面的长轴,它和X,Y同一个单位,如果一个面的分辨率为X*Y,则ABS_MT_TOUCH_MAJOR的最大值为sqrt(X^2+Y^2)

ABS_MT_TOUCH_MINOR描述了接触面的短轴,如果接触面是圆形,它可以不用。

ABS_MT_WIDTH_MAJOR描述了接触工具的长轴

ABS_MT_WIDTH_MINOR描述了接触工具的短轴

ABS_MT_TOUCH_MAJOR := max(X, Y) 
ABS_MT_TOUCH_MINOR := min(X, Y)
ABS_MT_ORIENTATION := bool(X > Y)

以上四个参数可以用来生成额外的触摸信息,如ABS_MT_TOUCH_MAJOR/ABS_MT_WIDTH_MAJOR的比率可以用来描述压力。

ABS_MT_ORIENTATION

ABS_MT_POSITION_X接触面的中心点X坐标

ABS_MT_POSITION_Y接触面的中心点Y坐标

ABS_MT_TOOL_TYPE描述接触工具类型,很多内核驱动无法区分此参数如手指及笔,如果是这样,该参数可以不用,协议目前支持MT_TOOL_FINGER和MT_TOOL_PEN两种类型。

ABS_MT_BLOB_ID形状集ID,集合几个点以描述一个形状,很多驱动没有形状属性,此参数可以不用。

ABS_MT_TRACKING_ID描述了从接触开始到释放的整个过程的集合,如果设备不支持,此参数可是不用。

  触摸轨迹

  仅有少数设备可以明触的标识真实的 trackingID,多数情况下 trackingID只能来标识一次触摸动作的过程。

  手势

  多点触摸指定的应用是创建手势动作, TOUCH和 WIDTH参数经常用来区别手指的压力和手指间的距离,另外 MINOR类的参数可以用来区别设备的接触面的大小(点接触还是面接触),ORIENTATION可以产生旋转事件。

参考代码:

(1)注册多点触摸设备

ts->input_dev = input_allocate_device();
        if (ts->input_dev == NULL) {
                ret = -ENOMEM;
                printk(KERN_ERR "Failed to allocate input device/n");
                goto err_input_dev_alloc_failed;
        }
        ts->input_dev->name = "MT-touchscreen";
        set_bit(EV_SYN, ts->input_dev->evbit);
        set_bit(EV_KEY, ts->input_dev->evbit);
        set_bit(EV_ABS, ts->input_dev->evbit);
        set_bit(BTN_TOUCH, ts->input_dev->keybit);
        
        max_x=0x77b;
        max_y=0xb38;
        input_set_abs_params(ts->input_dev, ABS_X, 0, max_x, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_Y, 0, max_y, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, max_x, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
        input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
        ret = input_register_device(ts->input_dev);
        if (ret) {
                printk(KERN_ERR "Unable to register %s input device/n", ts->input_dev->name);
                goto err_input_register_device_failed;
        }

(2) 报点

for(i=0;i<finger;i++){
    input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
    input_report_abs(ts->input_dev, ABS_MT_POSITION_X, ts->x[i]);
    input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, ts->y[i]);
    input_mt_sync(ts->input_dev);
    ts->upsend=0;
}
if(finger){
    input_sync(ts->input_dev);

}else{
    if(!ts->upsend){
        input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
        input_mt_sync(ts->input_dev);
        input_sync(ts->input_dev);
        ts->upsend=1;
    }
}

 

另外一篇介绍多点触控的文章

 

 使用说明

    任何一个手指的触控数据都是打包成 ABS event 包按顺序发送,只有 ABS_MT event包能作为多点触控数据被识别,调用 input_mt_sync()函数可以产生一个 SYN_MT_REPORT event ,这个函数接收并处理当前手指的信息并准备接收其它手指的触控信息。最后调用 input_sync()函数上报 EV_SYN/SYN_REPORT

    event 完成一个包的开始处理并准备处理下一个包。

    协议定义了 ABS_MT事件的属性,这些事件被分为几大类,充许只应用其中的一部份,多点触摸最小的事件集中应包括 ABS_MT_POSITION_X和 ABS_MT_POSITION_X,这两个事件用来描述多点触摸中手指的触摸轨迹。如果设备支持这两个事件,那么 ABS_MT_TOUCH_MAJOR和 ABS_MT_WIDTH_MAJOR 分别被用来提供手指的大小和触摸面积大小。

    TOUCH 和 WIDTH参数给出了个,想想如果一个手指按在玻璃上,透过玻璃你将看到两个区域,一个是手指与玻璃接触的区域,用 ABS_MT_TOUCH_MAJOR描述,一个是手指本身大小的区域, ABS_MT_WIDTH_MAJOR描述, 手指与玻璃接触的面积要小于手指本身的大小,通过这两个参数,可以换算出手指的压力。也可通过 ABS_MT_PRESSURE参数直接提供手指的压力。

    除了 MAJOR这个参数,还可以提供一个 MINOR参数,手指可以被认为是一个椭圆, MAJOR和 MINOR可以认为是这个椭圆的长轴和短轴,椭圆的中心可以被 ORIENTATION这个参数描述。

    ABS_MT_TOOL_TYPE参数用来描述触摸工具的类型(手指,触控笔等)。不同的设备可能有一些其它的信息需要传递到用户层。比如 ABS_MT_BLOB_ID用来描述长方形的边的集合,目前仅有少数设备可以被支持, ABS_MT_TRACKING_ID事件用来向上层报告硬件所采集的手指的触摸轨迹。

    下面是两指触摸的最小事件集 :

    ABS_MT_POSITION_X

    ABS_MT_POSITION_Y

    SYN_MT_REPORT //上报第一指坐标数据

    ABS_MT_POSITION_X

    ABS_MT_POSITION_Y

    SYN_MT_REPORT//上报第二指坐标数据

    SYN_REPORT

    完成一次上报

    协议解析

    “触摸”这个词用来描述工具(手指,笔,等)直接接触触摸屏表面。

    ABS_MT_TOUCH_MAJOR

    接触面的长轴。

    ABS_MT_TOUCH_MINOR

    接触面的短轴,如果是圆形接触面,这个参数可以省略。

    ABS_MT_WIDTH_MAJOR

    接触工具的长轴。

    ABS_MT_WIDTH_MINOR

    接触工具的切面的短轴,如果是圆形,此参数可以省略。

    上面的四个参数用来描术接触面的一些附加信息, ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR的比值可以用来反应接触时的压力值。

    ABS_MT_PRESSURE

    接触工具对接触面的压力大小,可以用来代替上面的四个参数。

    ABS_MT_ORIENTATION

    描述随圆的转动趋势,这是一个抽相值,O值表示接触面在平行与触摸屏的Y轴,向左是负值,向右是正值,如果完全平行于X轴,则上向返回最大值。如果接触面是圆形,则可以忽略这个参数。如果内核不能获得这个参数有有效值,但可以区分接触面的长短轴,这个功能还是可以被部份支持,在一些设备中, ABS_MT_ORIENTATION 的值只能是 0和1。

    ABS_MT_POSITION_X

    接触面的形心的X坐标值。

    ABS_MT_POSITION_Y

    接触面的形心的Y坐标值。

    ABS_MT_TOOL_TYPE

    触摸工具的类型

    ABS_MT_BLOB_ID

    用来标识多边形的边的集合,大多数内核不支持这个参数。

    ABS_MT_TRACKING_ID

    仅有少数设备支持,用来区别一个触摸动作的周期。

    计算方法

    一些设备将触摸面作为一个矩形上报,可以通过下面这些公式来计算出协议中所需要的信息。

    ABS_MT_TOUCH_MAJOR := max(X, Y)

    ABS_MT_TOUCH_MINOR := min(X, Y)

    ABS_MT_ORIENTATION := bool(X 》 Y)

    ABS_MT_ORIENTATION的取值范围为0至1,用来标识矩形接触面偏向X轴或Y轴的程度。

    触摸轨迹

    仅有少数设备可以明触的标识真实的 trackingID,多数情况下 trackingID只能来标识一次触摸动作的过程。

    手势

    多点触摸指定的应用是创建手势动作, TOUCH和 WIDTH参数经常用来区别手指的压力和手指间的距离,另外 MINOR类的参数可以用来区别设备的接触面的大小(点接触还是面接触) ,ORIENTATION可以产生旋转事件。

    说明:

    为了完作支持己有的应用,多点触控驱动应上报单点触控相应的 event,另外,所有的触控事件需要通过 input子系统向上传递。

    目前内核只有 bcm5974这么一个驱动支持多点触控,可以以此为例设计你的驱动。

    1) ABS_MT_APPROACH_X和 ABS_MT_APPROACH_Y在不同的触摸设备中可以有不同的意义。

    2)这个协议需要补充。

    3)多点触控的驱动尚没不成熟,到目前为此( 2009年4月) ,多点触控协议还没有 merged到内核主开发分支。










本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/5107990.html,如需转载请自行联系原作者

相关文章
|
安全 网络协议 Linux
深入理解Linux内核模块:加载机制、参数传递与实战开发
本文深入解析了Linux内核模块的加载机制、参数传递方式及实战开发技巧。内容涵盖模块基础概念、加载与卸载流程、生命周期管理、参数配置方法,并通过“Hello World”模块和字符设备驱动实例,带领读者逐步掌握模块开发技能。同时,介绍了调试手段、常见问题排查、开发规范及高级特性,如内核线程、模块间通信与性能优化策略。适合希望深入理解Linux内核机制、提升系统编程能力的技术人员阅读与实践。
1076 1
|
监控 Ubuntu Linux
什么Linux,Linux内核及Linux操作系统
上面只是简单的介绍了一下Linux操作系统的几个核心组件,其实Linux的整体架构要复杂的多。单纯从Linux内核的角度,它要管理CPU、内存、网卡、硬盘和输入输出等设备,因此内核本身分为进程调度,内存管理,虚拟文件系统,网络接口等4个核心子系统。
1167 0
|
Web App开发 缓存 Rust
|
Ubuntu 安全 Linux
Ubuntu 发行版更新 Linux 内核,修复 17 个安全漏洞
本地攻击者可以利用上述漏洞,攻击 Ubuntu 22.10、Ubuntu 22.04、Ubuntu 20.04 LTS 发行版,导致拒绝服务(系统崩溃)或执行任意代码。
|
12月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
1085 1
二、Linux文本处理与文件操作核心命令
|
12月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
794 137
|
12月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
1728 58
|
11月前
|
存储 安全 Linux
Linux卡在emergency mode怎么办?xfs_repair 命令轻松解决
Linux虚拟机遇紧急模式?别慌!多因磁盘挂载失败。本文教你通过日志定位问题,用`xfs_repair`等工具修复文件系统,三步快速恢复。掌握查日志、修磁盘、验重启,轻松应对紧急模式,保障系统稳定运行。
1669 2
|
Unix Linux 程序员
Linux文本搜索工具grep命令使用指南
以上就是对Linux环境下强大工具 `grep` 的基础到进阶功能介绍。它不仅能够执行简单文字查询任务还能够处理复杂文字处理任务,并且支持强大而灵活地正则表达规范来增加查询精度与效率。无论您是程序员、数据分析师还是系统管理员,在日常工作中熟练运用该命令都将极大提升您处理和分析数据效率。
920 16