1 前言
上一篇文章介绍了Android Input子系统,Touchscreen是典型的输入设备,有个大神同事专门做过TP,写了一篇总结文章,但是格式方面不是很好,我再整理一下发出来。
Android Input子系统介绍
微信公众号 Android Input子系统介绍链接
下面介绍,手机触摸屏调试中如何优化触摸屏响应速度思路,给没有接触过初学者一个方向。
2 触摸屏的响应速度分为几个阶段去优化
阶段1: 从手指触发到触摸屏电容表面->触摸屏表面的信号处理;
阶段2:平台侧响应来自触摸屏器件的IRQ信号,进而退出CPU idle;
阶段3:开始进入到触摸屏驱动注册到平台IRQ的入口函数内,接着执行触摸屏中断函数内的工作队列,进而调用I2C平台端的控制器和触摸屏通信,完成input事件的上报
3 举例:Rockchip平台
分析方法:
抓取ftrace:
<idle>-0 [000] d.h2 439.249389: irq_handler_entry: irq=303 name=GSL3673
<idle>-0 [000] d.h5 439.249406: clk_disable: pclk_gpio7
<idle>-0 [000] d.h3 439.249424: workqueue_queue_work: work struct=c48ddc18 function=gsl3673_ts_worker workqueue=c49dda00 req_cpu=4 cpu=4294967295
<idle>-0 [000] d.h3 439.249430: workqueue_activate_work: work struct c48ddc18
<idle>-0 [000] dnh2 439.249473: irq_handler_exit: irq=303 ret=handled
kworker/u8:3-169 [000] ...1 439.249586: workqueue_execute_start: work struct c48ddc18: function gsl3673_ts_worker
kworker/u8:3-169 [000] d..3 439.249607: clk_enable: pclk_i2c4
kworker/u8:3-169 [000] d.h1 439.249637: irq_handler_entry: irq=36 name=ff160000.i2c
kworker/u8:3-169 [000] d.h1 439.249652: irq_handler_exit: irq=36 ret=handled
<idle>-0 [000] d.h2 439.249713: irq_handler_entry: irq=36 name=ff160000.i2c
<idle>-0 [000] d.h2 439.249727: irq_handler_exit: irq=36 ret=handled
<idle>-0 [000] d.h2 439.249743: irq_handler_entry: irq=36 name=ff160000.i2c
<idle>-0 [000] dnh2 439.249782: irq_handler_exit: irq=36 ret=handled
kworker/u8:3-169 [000] d..3 439.249866: clk_disable: pclk_i2c4
kworker/u8:3-169 [000] d..3 439.249889: clk_enable: pclk_i2c4
kworker/u8:3-169 [000] d.h1 439.249917: irq_handler_entry: irq=36 name=ff160000.i2c
kworker/u8:3-169 [000] d.h1 439.249937: irq_handler_exit: irq=36 ret=handled
<idle>-0 [000] d.h2 439.250766: irq_handler_entry: irq=36 name=ff160000.i2c
<idle>-0 [000] d.h2 439.250791: irq_handler_exit: irq=36 ret=handled
<idle>-0 [000] d.h2 439.251091: irq_handler_entry: irq=36 name=ff160000.i2c
<idle>-0 [000] d.h2 439.251107: irq_handler_exit: irq=36 ret=handled
<idle>-0 [000] d.h2 439.251134: irq_handler_entry: irq=36 name=ff160000.i2c
<idle>-0 [000] dnh2 439.251178: irq_handler_exit: irq=36 ret=handled
kworker/u8:3-169 [000] d..3 439.251256: clk_disable: pclk_i2c4
kworker/u8:3-169 [000] d..4 439.251383: clk_enable: pclk_gpio7
kworker/u8:3-169 [000] ...1 439.251402: workqueue_execute_end: work struct c48ddc18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
3.1 分析
阶段1是属于touchscreen芯片厂家比较擅长的,具体调试手段这里不进行描述,这里主要分析阶段二和阶段三的执行时间。
阶段1是属于touchscreen芯片厂家比较擅长的,具体调试手段这里不进行描述,这里主要分析阶段二和阶段三的执行时间。
1、阶段二-开始触发中断到进入中断服务函数时间
1.1、idle进程响应,触摸屏的IRQ入口开始的时间点是439.249389
-0 [000] d.h2 439.249389: irq_handler_entry: irq=303 name=GSL3673
1.2 、触摸屏的IRQ入口开始的结束点是439.249473
-0 [000] dnh2 439.249473: irq_handler_exit: irq=303 ret=handled
2、阶段三-中断工作队列函数运行时间
IRQ函数内调度了工作队列和绑定的一个work,线程号是169,ps 可以看到kworker
工作队列上work执行开始的时间点是:
kworker/u8:3-169 [000] …1 439.249586: workqueue_execute_start: work struct c48ddc18: function gsl3673_ts_worker
工作队列上work执结束的时间点是:
kworker/u8:3-169 [000] …1 439.251402: workqueue_execute_end: work struct c48ddc18
4、I2C4控制器的耗时,不分析。
3.2 总结:所以阶段3耗时:439.251402-439.249389=2.1ms
通过谷歌浏览器分析:
平均间隔1.76MS,这里是工作队列的执行时间而已。
4示波器测试
整个过程可以使用示波器来追踪,如何追踪呢?
4.1 阶段1
触摸屏表面单体放置硬币,探头,快速点击测试触摸屏,对比TX信号触发的波形,以及测试触摸屏IRQ的输出时间,可以计算出平均时延。
4.2 阶段2,阶段3
可以在代码入口和出口,加入GPIO翻转方式去获取波形时间
总结:
通过ftrace来分析触摸屏的阶段3的耗时latency,举一反三,可以加入日志CPU IDLE的耗时。
5 代码测试
也可以在驱动代码中加入
trace_printk(" trace gpc func is enter %s",__func__);
1
去追踪是哪里导致耗时过长
经验举例:
我就碰到一种情况,就是高通平台坑很多,为了达到省电目的,经常CPU idle的时候关闭一些系统电源,导致退出CPU idle都需要一定(ms)时间,接着才能进入到IRQ入口;也就阶段2就耗费9MS左右。
然后阶段3,在首次启动的时候也同样存在I2C控制器和外设交互的时候latency耗时过长;