Android上电容屏上报数据的时间稳定性探索

最近看Android 5的sensor HAL层有些发现。

以下链接中关于事件的时间戳(timestamp)有一些描述,需要思考一下。

https://source.android.com/devices/sensors/hal-interface.html

翻译过来的大概意思如下:

timestamp: 该成员为事件的时间戳,单位为纳秒(nanoseconds)。它用于表示事件发生的时间(可能是计步器检测到用户走了一步,或者是加速计测量到了一个数据),而不是事件的上报时间。timestamp 必须和elapsedRealtimeNano 时钟同步,对于工作在continuous模式的传感器而言,其抖动(时基误差)必须很小。为了满足CDD的要求,时间戳过滤在某些时候是必要的,因为仅仅使用SoC的中断时间作为时间戳会有很大的抖动性(时基误差),而仅仅使用传感器芯片时间来设置时间戳会导致和elapsedRealtimeNano 时钟失去同步,因为传感器芯片时钟会漂移。


先前在一个项目中为电容屏的报点时间纠结了好些时日,一直想办法解决报点不均匀的事情。当时的情况是:电容屏芯片对每个点都以中断方式通知AP,电容屏的报点频率是均匀的,从示波器来看,中断引脚发生中断的频率也是均匀的。但是上层应用得到的事件却不均匀。

看了上述关于时间戳的描述后,推测当时的问题应该处在kernel中。因为上层判断均匀与否完全基于时间戳信息,而时间戳是由kernel中的input系统对每个上报动作附加进去的。电容屏驱动中对上报动作的处理一般是用中断底半部的方式来完成的,它们多由work_queue方式实现,这就注定了这个上报动作实际发生的时机带有不缺定性,从而导致时间戳的不缺定。

现在看来解决的办法或许可以这样:

对电容屏的中断处理采用中断+轮询方式,即发生一次中断后以固定频率轮询数据。一般的电容屏芯片都有相关的标志位能够确认当前是否有数据。因此可以用轮询模式。如果电容屏芯片是以电平方式而不是边沿方式触发中断的,则轮询更易实现。

而驱动要做的仅仅是用某种机制让这个轮询的频率相当精确,从而可保证上报的时间戳不会抖动。

不要使用单点中断方式,因为从硬件发生中断到中断被处理,乃至底半部被调用到,中间有诸多的时间不确定性。

甚至,或许可以这么做:来做一个软件的FIFO,把数据先放到这里,因为电容屏的上报频率一般50HZ就可以下了,所以可以将数据先做个缓冲,缓冲100~200ms的数据就可以了(5~10个点)。然后另起一个线程,以准确的固定频率从这个FIFO中拿数据并上报。这个设计思路是假设进FIFO的数据在时间间隔上有轻微抖动,但是我们可以让出FIFO的数据在时间上是间隔稳定的。





你可能感兴趣的:(Linux)