i.mx28平台下,io中断会导致系统死机,废了不少周折,还没完全明白,先在这记个之前的调试步骤。
1.问题的出现:在设备驱动中,自己写的中断处理函数里,没有做任何业务处理,只是简单的进入,就return IRQ_HANDLED,多中断几次,系统就死机,表现为应用软件的printf都无打印,控制台也没法操作;
2.跟踪内核的中断处理调用过程:mxs_gpio_irq_handler(arch/arm/plat_mxs/gpio.c)->handle_level_irq(kernel/irq/chip.c)->handle_IRQ_event(kernel/irq/handle.c)->调用设备驱动中的响应函数。
3.handle_level_irq()函数中的主要做了mask_ack_irq 和 handle_IRQ_event两个操作,前者将是把io中断状态寄存器的相应位清除掉。
4.handle_IRQ_event()函数主要工作就是调用设备驱动的响应函数,但在调用这个响应函数之前,内核先判断了相应中断设置的flags标志是否被设置为了IRQF_DISABLED,如果未设置,则调用local_irq_enable_in_handirq()宏,而这个宏中调用 了treace_handirqs_on()和raw_local_irq_enable()两个函数,raw_local_irq_enable中带了asm的混合编码:
__asm__ __volatile__( \
"mrs %0, cpsr @ local_irq_enable\n" \
" bic %0, %0, #128\n" \
" msr cpsr_c, %0" \
: "=r" (temp) \
: \
: "memory", "cc"); \
,查了下汇编格式,并通过前后将cpsr寄存器的值读取出来,确定这些语句的操作就是将arm核的cpsr程序状态寄存器的IRQ中断启用(不禁止),以允许在处理用户的中断处理函数时,系统能够响应更高优先级的中断。
5.由于中断中用printk打印出信息的办法,中断很不容易导致死机,为了调试方便,利用一个io脚点灯的方法,逐步确认了,程序就是跑了上面的raw_local_irq_enable后,死机的。但,在死机之前,也是按这个流程能正常中断很多次。
6.综上,猜测,有可能是因为开了中断后,真的又来了新的别的中断,这个原因直接导致了死机。
7.另一个疑惑,local_irq_enable_in_handirqirq的宏定义如下:
#ifdef CONFIG_LOCKDEP
# define local_irq_enable_in_hardirq() do { } while (0)
#else
# define local_irq_enable_in_hardirq() local_irq_enable()
#endif
其中,CONFIG_LOCKDEP配置,是默认为=n的,但在menuconfig中又找不到配置项,这个宏到底都规定了哪些操作呢?如果把它配置为=y,不就可以在中断的时候不开中断标志了嘛,那样就不会有这个死机的问题啦。但有什么别的负面影响呢?!
待解。。。
2011.8.27:不要去改CONFIG_LOCKDEP配置;
a.request_irq时,不带IRQF_DISABLED标志,中断很容易就死机;
b.request_irq时,带IRQF_DISABLED标志(快速中断,响应期间不允许处理器中断),偶尔会死机;
c.将handle_IRQ_event中的local_irq_enable_in_hardirq()删去,中断未再发现死机;
新的疑惑:以上c所述,在2.6.31版本中,在中断处理期间有开中断操作,而在2.6.35中压根都没有这句,不知道在哪个版本中删掉了,把这一句删掉不是会影响其它中断的效率吗?!
阅读(3181) | 评论(0) | 转发(0) |