今天调试音频应用程序的时候,出了个很诡异的问题,之前的环境是音频ALSA和SD-WIFI一起工作,现在产品样板回来了,换成了音频ALSA和SPI转USB的WIFI,本以为不需要任何改动,谁知道一放音乐只会响那么一声内核就死掉了,一直重复刚才播出的那一小段声音。
刚一开始,真没想出来什么问题,怀疑过应用程序死锁,怀疑过电压不稳定,毕竟是新的板子。后来将内核恢复到之前的版本(不带SPI的),就是可以的。那问题肯定出在SPI上,是电压吗?还是别的?
经同事指点,问题很可能出在DMA的中断上面。我们的SoC总共有两个DMA控制器,各8通道,之前SD和ALSA(I2S的控制器DMA中断)分别挂载DMA1和DMA2上面,而SPI和I2S一同挂在DMA2上,也就是申请DMA中断的时候,是同一个中断号,所以这个就要涉及到中断申请的注意点了。
有关中断申请的基础知识。
- IRQ注册函数:(头文件在:<include/linux/interrupt.h>)
- int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *dev_name, void *dev_id);
其中:
(对于触发方式,可以指定为:IRQ_TRIGGER_RISING、IRQ_TRIGGER_FALLING、IRQ_TRIGGER_HIGH、IRQ_TRIGGER_LOW)
IRQ释放函数:
- void free_irq(unsigned int irq,void *dev_id);(一般在退出设备或关闭设备时调用)
打开一个IRQ:
- void enable_irq(unsigned int irq);(允许该IRQ产生中断)
关闭一个IRQ:
- void disable_irq(unsigned int irq);(禁止该IRQ产生中断)
那么,很自然的去查了下SPI申请的DMA中断,果然那边申请的时候设置的参数为IRQF_DISABLED。所以将其改为共享中断,然后再各自的中断函数当中通过读取DMA的中断标志位,去判断是否是自己模块的中断,如果不是,则立即返回IRQ_HANDLED。
阅读(1601) | 评论(2) | 转发(0) |