第二章:触摸屏驱动架构概览
做驱动调优,首先得搞清楚你面对的是什么。触摸屏驱动看起来就是个“上报坐标”的模块,但里面的门道不少。我个人习惯把驱动架构拆成三层来看,这样排查问题会清晰很多。
2.1 三层驱动模型
智能座舱的触摸屏驱动,说白了就是下面这张图的结构。你想想看,从手指点到屏幕,到应用层响应,中间经过了三个关卡。
这三层各司其职,每一层都可能成为性能瓶颈。我遇到过不少案例,问题出在硬件接口层,大家却跑到上层去调参数,折腾半天没效果。
2.2 硬件接口层详解
这一层是驱动和芯片的“翻译官”。常见的通信接口有 I²C、SPI 和 USB。座舱里用得最多的是 I²C 和 SPI。
| 接口类型 | 典型速率 | 适用场景 | 调优关注点 |
|---|---|---|---|
| I²C | 400 kHz ~ 1 MHz | 中低端座舱、电容屏 | 时钟频率、ACK 超时、中断延迟 |
| SPI | 10 MHz ~ 50 MHz | 高端座舱、多点触控 | 时钟极性、相位、DMA 传输 |
| USB | 12 Mbps(全速) | 外接触摸屏、调试 | 端点轮询间隔、传输缓冲区 |
我的经验: 调 I²C 时,先检查中断触发方式。我遇到过因为中断被其他高优先级设备抢占,导致触摸数据读取延迟超过 10 ms 的情况。改成边缘触发 + 线程化中断后,问题就解决了。
2.3 核心处理层
这一层是“大脑”。原始数据进来,经过滤波、校准、追踪,最后变成稳定的触摸事件。嗯,这里要注意,滤波算法选不好,反而会引入延迟。
常见的滤波方式有:
- 均值滤波:简单粗暴,但会引入固定延迟(窗口大小 × 采样间隔)
- 中值滤波:抗噪能力强,适合去除毛刺,但计算量大
- 卡尔曼滤波:动态效果好,适合快速滑动场景,但参数调起来麻烦
我曾经在一个项目中,为了追求平滑度,把均值滤波窗口设到了 5。结果滑动时明显感觉“粘手”。后来改成自适应窗口——静止时用大窗口,滑动时用小窗口,效果好了很多。
2.4 事件上报层
这一层负责把处理好的数据“递”给上层。Linux 内核里用的是 Input 子系统,多点触控遵循 MT Protocol B 协议。
上报流程大致是:
- 调用
input_mt_slot()设置当前槽位 - 调用
input_mt_report_slot_state()报告触摸状态 - 调用
input_report_abs()上报 X/Y 坐标 - 调用
input_sync()同步事件
关键点: 上报频率不是越高越好。我见过有人把上报频率调到 200 Hz,结果 CPU 占用率飙升,反而导致系统卡顿。座舱场景下,100 Hz 左右通常就够用了。
2.5 驱动调优的切入点
了解了三层架构,调优就有了方向。我个人习惯按下面的优先级来排查:
| 优先级 | 排查层 | 常见问题 | 快速验证方法 |
|---|---|---|---|
| 高 | 硬件接口层 | 中断延迟、总线速率不足 | 用示波器抓 I²C/SPI 波形 |
| 中 | 核心处理层 | 滤波窗口过大、校准算法耗时 | 加时间戳日志,看每步耗时 |
| 低 | 事件上报层 | 上报频率不匹配、同步丢失 | 用 getevent 工具查看事件流 |
避坑指南: 我曾经一上来就调核心处理层的算法,折腾了两天没效果。后来发现是 I²C 总线被其他设备占用了,导致触摸数据读取间隔不稳定。记住,先排查硬件接口层,再动上层逻辑。
2.6 本章小结
触摸屏驱动架构并不复杂,但每一层都有它的脾气。硬件接口层决定了数据能不能“拿得到”,核心处理层决定了数据“好不好用”,事件上报层决定了数据“传得顺不顺”。
后面几章,我会带着大家深入每一层,讲讲具体的调优方法和实战案例。嗯,先从硬件接口层开始吧。