Linux学习第43天:Linux 多点电容触摸屏实验:难忘记第一次牵你手的温存

Linux版本号4.1.15   芯片I.MX6ULL                                    大叔学Linux    品人间百味  思文短情长 


       人都是性情中人,如果把学习当做自己的女朋友,对她细致入微、掏心掏肺、有耐心有恒心,终会修成正果。

        而我们本节需要学习的电容触摸屏的驱动开发,就相当于你第一次牵手未来另一半的温存。真正学会学懂,等真正用到的时候才知道会有多香多甜多心满意足。

         本章主要学习触摸屏的驱动开发,需要学习的主要内容包括电容触摸屏的驱动框架简介、硬件原理分析以及驱动的开发与测试。本节内容重点学习本章的第一节电容触摸屏的驱动框架,其余内容将在下一节进行学习。

        本章的思维导图内容如下:

一、Linux下电容触摸屏驱动框架简介

1、多点触摸(MT)协议详解

①、电容屏 IIC接口  IIC设备驱动
②、中断获取触摸信息 中断驱动框架

③、是否触摸  绝对位置 input子系统
④、电容触摸屏不需要校准

        多点电容触摸协议

        MT协议两种类型:typeA 、typeB(常用 硬件追踪)

        ABS_MT事件多点触控:

ABS_MT_SLOT :触摸点ID
ABS_MT_POSITION_X 、 ABS_MT_POSITION_Y :触摸点坐标

ABS_MT_TRACKING_ID:Type B 设备区分触摸点

        input_mt_slot()函数:Type B 设备  区分哪一个触摸点

void input_mt_slot(struct input_dev *dev, int slot)//slot 当前上报的哪个触摸点

触发ABS_MT_SLOT事件。

        input_sync()函数来标识多点触摸信息传输完成,告诉接收者处理之前累计的所有消息,并且准备好下一次接收。

        Type B 设备驱动需要给每个识别出来的触摸点分配一个 slot,后面使用这个 slot 来上报触
摸点信息。

        可以通过 slot 的 ABS_MT_TRACKING_ID 来新增、替换或删除触摸点。一个非负数的 ID 表示一个有效的触摸点, -1 这个 ID 表示未使用 slot。一个以前不存在的 ID 表示这是一个新加的触摸点,一个 ID 如果再也不存在了就表示删除了。

        有些设备识别或追踪的触摸点信息要比他上报的多,这些设备驱动应该给硬件上报的每个触摸点分配一个 Type B 的 slot。一旦检测到某一个 slot 关联的触摸点 ID 发生了变化,驱动就应该改变这个 slot 的 ABS_MT_TRACKING_ID,使这个 slot 失效。如果硬件设备追踪到了比他正在上报的还要多的触摸点,那么驱动程序应该发送 BTN_TOOL_*TAP 消息,并且调用
input_mt_report_pointer_emulation()函数,将此函数的第二个参数 use_count 设置为 false。
 

2、TypeA触摸点信息上报时序

1 ABS_MT_POSITION_X x[0]
2 ABS_MT_POSITION_Y y[0]
3 SYN_MT_REPORT//上报 SYN_MT_REPORT 事件,通过调用 input_mt_sync 函数来实现。
4 ABS_MT_POSITION_X x[1]
5 ABS_MT_POSITION_Y y[1]
6 SYN_MT_REPORT
7 SYN_REPORT//上报 SYN_REPORT 事件,通过调用 input_sync 函数实现。

3、TypeB触摸点信息上报时序

1 ABS_MT_SLOT 0/*每次上报一个触摸点坐
标之前要先使用input_mt_slot函数上报当前触摸点SLOT*/
2 ABS_MT_TRACKING_ID 45/*每个 SLOT 必须关联一个 ABS_MT_TRACKING_ID,通过
修改 SLOT 关联的 ABS_MT_TRACKING_ID 来完成对触摸点的添加、替换或删除。具体用到的函数input_mt_report_slot_state*/
3 ABS_MT_POSITION_X x[0]
4 ABS_MT_POSITION_Y y[0]
5 ABS_MT_SLOT 1
6 ABS_MT_TRACKING_ID 46
7 ABS_MT_POSITION_X x[1]
8 ABS_MT_POSITION_Y y[1]
9 SYN_REPORT

        触摸点移除:

1 ABS_MT_TRACKING_ID -1/*input_mt_report_slot_state 设置active为false*/
2 SYN_REPORT

4、MT其他事件的使用

ABS_MT_POSITION_X 和ABS_MT_POSITION_Y:上报触摸点

ABS_MT_TOUCH_MAJOR 和 ABS_MT_WIDTH_MAJOR :上报触摸面积

ABS_MT_TOOL_TYPE 事件用于上报触摸工具类型:

MT_TOOL_FINGER(手指)、 MT_TOOL_PEN(笔)和 MT_TOOL_PALM(手掌)
于Type B类型,事件由input子系统内核处理。上报此类事件,由函数

input_mt_report_slot_state完成。

5、多点触摸所使用到的API函数

1)、input_mt_init_slots函数

用于初始化 MT 的输入 slots:

int input_mt_init_slots( struct input_dev *dev,
unsigned int num_slots,
unsigned int flags)

2)、input_mt_slot函数

        用于产生 ABS_MT_SLOT 事件,告诉内核当前上报的是哪个触摸点的坐标数据:

void input_mt_slot(struct input_dev *dev,
int slot)

3)、input_mt_report_slot_state函数

        用于 Type B 类型,用于产生 ABS_MT_TRACKING_ID 和 ABS_MT_TOOL_TYPE
事 件 , ABS_MT_TRACKING_ID 事 件 给 slot 关 联 一 个 ABS_MT_TRACKING_ID ,
ABS_MT_TOOL_TYPE 事 件 指 定 触 摸 类 型 ( 是 笔 还 是 手 指 等 )。

void input_mt_report_slot_state( struct input_dev *dev,
unsigned int tool_type,
bool active)/*true,连续触摸,input 子系统内核会自动分配一个 ABS_MT_TRACKING_ID 给 slot。
false,触摸点抬起,表示某个触摸点无效了, input 子系统内核会分配一个-1 给 slot,表示触摸
点溢出。*/

4)、input_report_abs函数

        上报触摸点坐标信息:

void input_report_abs( struct input_dev *dev,
unsigned int code,/*要上报的是什么数据,可以设置为 ABS_MT_POSITION_X 或 ABS_MT_POSITION_Y,
也就是 X 轴或者 Y 轴坐标数据。*/
int value)/*具体的 X 轴或 Y 轴坐标数据值。*/

5)、input_mt_report_pointer_emulation函数

        如果追踪到的触摸点数量多于当前上报的数量,驱动程序使用 BTN_TOOL_TAP 事件来通知用户空间当前追踪到的触摸点总数量,然后调用 input_mt_report_pointer_emulation 函数将
use_count 参数设置为 false。否则的话将 use_count 参数设置为 true,表示当前的触摸点数量(此
函数会获取到具体的触摸点数量,不需要用户给出):

void input_mt_report_pointer_emulation(struct input_dev *dev,
bool use_count)

6、多点电容触摸驱动框架

1)、I2C驱动框架

1 /* 设备树匹配表 */
2 static const struct i2c_device_id xxx_ts_id[] = {
3 { "xxx", 0, },
4 { /* sentinel */ }
5 };
6
7 /* 设备树匹配表 */
8 static const struct of_device_id xxx_of_match[] = {
9 { .compatible = "xxx", },
10 { /* sentinel */ }
11 };
12
13 /* i2c 驱动结构体 */
14 static struct i2c_driver ft5x06_ts_driver = {
15 .driver = {
16 .owner = THIS_MODULE,
17 .name = "edt_ft5x06",
18 .of_match_table = of_match_ptr(xxx_of_match),
19 },
20 .id_table = xxx_ts_id,
21 .probe = xxx_ts_probe,
原子哥在线教学:www.yuanzige.com 论坛:www.openedv.com
1511
I.MX6U 嵌入式 Linux 驱动开发指南
22 .remove = xxx_ts_remove,
23 };
24
25 /*
26 * @description : 驱动入口函数
27 * @param : 无
28 * @return : 无
29 */
30 static int __init xxx_init(void)
31 {
32 int ret = 0;
33
34 ret = i2c_add_driver(&xxx_ts_driver);
35
36 return ret;
37 }
38
39 /*
40 * @description : 驱动出口函数
41 * @param : 无
42 * @return : 无
43 */
44 static void __exit xxx_exit(void)
45 {
46 i2c_del_driver(&ft5x06_ts_driver);
47 }
48
49 module_init(xxx_init);
50 module_exit(xxx_exit);
51 MODULE_LICENSE("GPL");
52 MODULE_AUTHOR("zuozhongkai");

        当设备树中触摸IC的设备节点和驱动匹配以后,xxx_ts_probe函数就会执行。可以在此函数中初始化触摸IC,中断和input子系统。

2)、初始化触摸IC、中断和input子系统

1 static int xxx_ts_probe(struct i2c_client *client, const struct
i2c_device_id *id)
2 {
3 struct input_dev *input;
4
5 /* 1、初始化 I2C */
6 ......
7
8 /* 2,申请中断, */
9 devm_request_threaded_irq(&client->dev, client->irq, NULL,
10 xxx_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
11 client->name, &xxx);
12 ......
13
14 /* 3, input 设备申请与初始化 */
15 input = devm_input_allocate_device(&client->dev);
16
17 input->name = client->name;
18 input->id.bustype = BUS_I2C;
19 input->dev.parent = &client->dev;
20 ......
21
22 /* 4,初始化 input 和 MT */
23 __set_bit(EV_ABS, input->evbit);
24 __set_bit(BTN_TOUCH, input->keybit);
25
26 input_set_abs_params(input, ABS_X, 0, width, 0, 0);
27 input_set_abs_params(input, ABS_Y, 0, height, 0, 0);
28 input_set_abs_params(input, ABS_MT_POSITION_X,0, width, 0, 0);
29 input_set_abs_params(input, ABS_MT_POSITION_Y,0, height, 0, 0);
30 input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0);
31 ......
32
33 /* 5,注册 input_dev */
34 input_register_device(input);
35 ......
36 }

        devm_request_threaded_irq 函数特点:

①、用于申请中断。

②、此函数的作用是中断线程化。

③、使用“ devm_”前缀的函数申请到的资源可以由系统自动释放,不需要我们手动处理。
        多点电容屏的触摸坐标为绝对值,因此需要上报 EV_ABS 事件。触摸屏有按下和抬起之分,因此需要上报 BTN_TOUCH 按键。

3)、上报坐标信息

1 static irqreturn_t xxx_handler(int irq, void *dev_id)
2 {
3
4 int num; /* 触摸点数量 */
5 int x[n], y[n]; /* 保存坐标值 */
6
7 /* 1、从触摸芯片获取各个触摸点坐标值 */
8 ......
9
10 /* 2、上报每一个触摸点坐标 */
11 for (i = 0; i < num; i++) {
12 input_mt_slot(input, id);
13 input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
14 input_report_abs(input, ABS_MT_POSITION_X, x[i]);
15 input_report_abs(input, ABS_MT_POSITION_Y, y[i]);
16 }
17 ......
18
19 input_sync(input);
20 ......
21
22 return IRQ_HANDLED;
23 }

        每一轮触摸点坐标上报完毕以后就调用一次 input_sync 函数发送一个SYN_REPORT 事件。

        以下内容将在下一节笔记中更新。

二、硬件原理图分析

三、实验程序编写

1、修改设备树

1)、添加FT5426所使用的IO

2)、添加FT5426节点

2、编写多点电容触摸驱动

四、运行测试

1、编译驱动程序

2、运行测试

3、将驱动添加到内核中

1)、将驱动文件放到合适的位置

2)、修改对应的Makefile

五、tslib移植与使用

1、tslib移植

1)、获取tslib源码

2)、修改tslib源码所属用户

3)、ubuntu工具安装

4)、编译tslib

5)、配置tslib

6)、tslib测试

六、使用内核自带的驱动

1、修改edt-ft5x06.c

2、使能内核自带的FT5X06驱动

3、修改设备树

七、4.3.寸屏触摸驱动实验

1、修改设备树pinctrl_tsc节点内容

2、在设备树的i2c2节点下添加tgt9147子节点

3、修改设备树的lcdif节点

4、编译GT9147驱动文件

八、总结


本文为参考正点原子开发板配套教程整理而得,仅用于学习交流使用,不得用于商业用途。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/155744.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(swjtu西南交大)数据库实验(概念数据库设计及逻辑关系转换):音乐软件数据管理系统

一、实体型及属性 &#xff08;20分&#xff09; 用户&#xff08;账号&#xff0c;用户名&#xff0c;密码&#xff0c;性别&#xff0c;生日&#xff0c;地区&#xff0c;手机号&#xff0c;个性签名&#xff0c;信息修改审核客服&#xff09; 歌手&#xff08;歌手号&#…

C++模拟实现——红黑树封装set和map

一、红黑树迭代器的实现 基本的框架和实现链表的迭代器思路是一样的&#xff0c;都是对指针进行封装处理&#xff0c;然后实现一些基本的运算符重载&#xff0c;最重要的是operator&#xff0c;需要不递归的实现走中序的规则&#xff0c;这里只实现那最核心的几个基本功能&…

第一次参加算法比赛是什么感受?

大家好&#xff0c;我是怒码少年小码。 冬日暖阳&#xff0c;好日常在。今天中午在食堂干饭的时候&#xff0c;我的手机&#x1f4f1;收到了一条收货信息。 阿&#xff1f;什么玩意儿&#xff1f;我又买啥了&#xff1f; 个败家玩意&#xff0c;我都准备好叨叨我自己&#x…

msvcp120.dll缺失的解决方法与作用介绍

大家好&#xff01;我是小编。今天&#xff0c;我想和大家分享一下关于“找不到msvcp120.dll无法继续执行代码的5个解决方法”的话题。 首先&#xff0c;让我们来了解一下msvcp120.dll的作用。msvcp120.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;它…

高防CDN如何预防攻击?

现在网络攻击事件越来越多&#xff0c;而且愈发凶猛&#xff0c;为了保障互联网业务能稳定正常的运行&#xff0c;市场上出现了很多高防产品&#xff0c;例如高防服务器、高防IP、高防CDN等等。其中究竟高防CDN怎么防攻击&#xff0c;能防哪些攻击&#xff1f;高防CDN如何实现防…

matlab-BP神经网络的训练参数大全

本文部分图文来自《老饼讲解-BP神经网络》bp.bbbdata.com 本文列兴趣MATLAB神经网络工具箱中&#xff0c;训练参数trainParam的各个参数与意义 以方便在使用matlab工具箱时&#xff0c;用于查阅 一、matlab神经网络工具箱trainParam的参数列表 trainParam中的各个具体参数如下…

4.2 Windows驱动开发:内核中进程线程与模块

内核进程线程和模块是操作系统内核中非常重要的概念。它们是操作系统的核心部分&#xff0c;用于管理系统资源和处理系统请求。在驱动安全开发中&#xff0c;理解内核进程线程和模块的概念对于编写安全的内核驱动程序至关重要。 内核进程是在操作系统内核中运行的程序。每个进…

对象分配规则

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

函数有返回类型,但函数体未返回类型,程序崩溃问题记录

问题 使用类指针调用函数时&#xff0c;程序崩溃。 问题定位&#xff1a; name new nameSetting;name->setName("helloworld");qDebug().noquote() << name->getName();原因 class nameSetting { public:nameSetting();QString setName(const QStri…

GB28181视频监控国标平台EasyGBS如何进行服务迁移?

视频流媒体安防监控国标GB28181平台EasyGBS视频能力丰富&#xff0c;部署灵活&#xff0c;既能作为业务平台使用&#xff0c;也能作为安防监控视频能力层被业务管理平台调用。国标GB28181视频EasyGBS平台可提供流媒体接入、处理、转发等服务&#xff0c;支持内网、公网的安防视…

golang学习笔记——接口和继承比较1

继承 Go 语言的设计之初&#xff0c;就不打算支持面向对象的编程特性&#xff0c;因此 Go 不支持面向对象的三大特性之一——继承。但是 Go 可以通过组合的思想去实现 “继承”。继承是面向对象的三大特性之一&#xff0c;继承是从已有的类中派生出新的类&#xff0c;新的类能…

【Django使用】4大模块50页md文档,第4篇:Django请求与响应和cookie与session

当你考虑开发现代化、高效且可扩展的网站和Web应用时&#xff0c;Django是一个强大的选择。Django是一个流行的开源Python Web框架&#xff0c;它提供了一个坚实的基础&#xff0c;帮助开发者快速构建功能丰富且高度定制的Web应用 Django全套笔记地址&#xff1a; 请移步这里 …

Unity中Shader的PBR的基础知识与理论

文章目录 前言一、什么是PBR二、什么是PBS在这里插入图片描述 三、PBS的核心理论1、物质的光学特性&#xff08;Substance Optical Properties&#xff09;2、微平面理论&#xff08;Microfacet Theory&#xff09;3、能量守恒&#xff08;Energy Conservation&#xff09;4、菲…

7 Redis的PipeLine

PipeLine的作用是批量执行命令 redis的性能瓶颈基本上是网络 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.…

【数据结构】队列详解

Hello everybody!今天给大家讲讲队列的相关知识。队列&#xff0c;属于一种数据结构。从字面意思上理解&#xff0c;就像是排队一样&#xff0c;在食堂中&#xff0c;先排队的人自然就先买到饭。队列也是如此&#xff0c;先入队列的数据自然就先出队列。希望大家可以通过这篇文…

C语言生成dll与lib文件

环境要求 新建一个空白项目&#xff0c;可以是exe的&#xff0c;也可以直接是dll的&#xff0c;也可以是啥都没有的空项目&#xff0c;推荐创建空项目&#xff0c;项目创建好以后进行配置&#xff0c;共两步 第一步&#xff0c;打开项目属性 第二步&#xff0c;设置配置类型…

使用Python处理ADC激光测距数据并绘制为图片(二)

使用Python处理ADC激光测距数据并绘制为图片 说明一、定义全局变量变二、保存和清空原始数据三、拆分原始数据为键值对四、获取标题、FigText、更新统计信息文件五、生成图片六、处理原始数据文件七、主函数入口八、测试结果 说明 1. 主要是将ADC激光测距叠加后的1024Byte数据绘…

哪个才是最适合你的 Web UI 自动化测试框架

最近&#xff0c;项目上出于系统性稳定性、减少测试工作量考虑&#xff0c;打算在 Web 前端引入 BDD。由于上一个项目写了一定的 Cucumber 代码&#xff08;BDD 测试框架之一&#xff09;&#xff0c;这个框架选型的责任便落到了我的肩膀上了。 在我们进行框架选型的时候&#…

【SA8295P 源码分析 (三)】132 - GMSL2 协议分析 之 GPIO/SPI/I2C/UART 等通迅控制协议带宽消耗计算

【SA8295P 源码分析】132 - GMSL2 协议分析 之 GPIO/SPI/I2C/UART 等通迅控制协议带宽消耗计算 一、GPIO 透传带宽消耗计算二、SPI 通迅带宽消耗计算三、I2C 通迅带宽消耗计算四、UART 通迅带宽消耗计算系列文章汇总见:《【SA8295P 源码分析 (三)】Camera 模块 文章链接汇总 -…

如何做好前端单元测试?字节5年测试老司机是这样说的!

近几年&#xff0c;前端发展越来越迅猛&#xff0c;各类框架层出不穷&#xff0c;前端实现的业务逻辑也越来越复杂&#xff0c;前端单元测试也越来越受重视&#xff0c;包括百度在内的一些大厂在面试中也会问到单元测试相关的题目。那么前端应该如何做好单元测试&#xff1f; 什…