触摸屏手势切歌,为什么造成了音乐卡顿爆音

之前某客户报了一个问题,说是灭屏状态下通过触摸屏(Touch Pannel,简称TP)手势切换上一首下一首音乐时,会出现卡顿、爆音的现象。第一感觉是TP驱动有什么缺陷导致,但由于TP驱动是由触摸屏厂商提供参考代码,客户自己又加上了一些修改,并且他们认为该驱动问题不大,因此希望我们AP侧能先从正面看一下,能否查到音乐卡顿爆音的原因。以下是对此次问题处理过程的简要记录。

 

  • 切歌爆音/卡顿,通过log找到线索,是因为kernel alsa音频驱动产生了XRUN,具体为pcm buffer undderrun,是由于用户空间没有及时写数据到kernel pcm buffer导致。

  • 但平时切歌是没有问题的,只有手势唤醒切歌时才有问题,可推论用户空间音频服务本身出现问题的可能性很小,而重点怀疑是kernel把系统性能降低导致。

  • cat /proc/interrupts,观察手势唤醒前后的TP中断数,发现有10000+的中断,明显过多。

  • review TP驱动代码,suspend时为了手势唤醒功能,把中断类型由下降沿触发改为低电平触发,但在中断处理程序中既没有将触发电平反转,也没有重新设置为下降沿触发。而手势唤醒时触摸屏中断脚会输出长达200ms以上的低电平,导致中断长时间频繁产生,拖住了系统。

  • 再review代码,发现TP驱动在resume时启动了一个work去做实际resume动作,再在这个work中把中断切换成下降沿触发。可见代码还是有考虑唤醒后将中断方式由电平触发切换回边沿触发的,但是执行时机太晚了。

  • 解决方案是,手势唤醒中断产生后,在中断处理函数中及时把中断由电平触发切回边沿触发。

 

在这个问题处理过程中,客户还问了一个问题:

Q:TP驱动在request_irq时,有定义IRQF_ONESHOT这个标志,这个不能保证相同的中断只会执行一次吗(比如电平触发方式下)?

A:首先,IRQF_ONESHOT这个中断标志的意义是,如果调用 request_threaded_irq(irq, handler, thread_fn, flags, name, dev)时设置了这个标志,则Linux中断系统会保证在thread_fn执行后才开中断。在request_irq上使用该标志是多余的。

include\linux\interrupt.h 
* IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.

* Used by threaded interrupts which need to keep the

* irq line disabled until the threaded handler has been run.

其次,Linux执行上半部中断处理函数时,默认就是关中断的,执行完成后会开中断。即使在request_threaded_irq中设置了IRQF_ONESHOT,也只是将开中断这个动作推迟到了thread_fn执行后,开启中断后,如果硬件中断条件仍满足,则会继续产生下一次中断。

posted @ 2021-05-15 17:51  bigfish99  阅读(536)  评论(0编辑  收藏  举报