1、我使用如下的代码申请对EINT4的处理:request_irq(IRQ_EINT4, Eint4_interrupt,0, "damtek_eint4_interrupt", NULL))
2、Eint4_interrupt函数的处理代码如下
static irqreturn_t Eint4_interrupt(int irqno, void *param)
{
disableEINT4();
printk("Eint4_interrupt +++ 0 \r\n");
g_audio_timer_eint4.expires = jiffies + (1);
mod_timer(&g_audio_timer_eint4, g_audio_timer_eint4.expires);
return IRQ_HANDLED;
}
3、audio_timer_handler_eint4函数的处理代码如下:
static void audio_timer_handler_eint4(unsigned long data)
{
disableEINT4();
printk("Eint4_interrupt +++ 1\r\n");
}
如果设置中断触发方式为,高触发之后,然后故意把中断拉高,此时会发现:Eint4_interrupt +++ 0 会不断的打印,
中断释放(拉低)之后,才会打印1句Eint4_interrupt +++ 1
然后,再次拉低中断之后,不会有任何打印。
问题:
1、为什么Eint4_interrupt中的disableEINT4();会不起作用?说明:disableEINT4()的代码,是直接配置中断的相关使能的寄存器。
2、为什么在保持高电平的状态时,会不进入audio_timer_handler_eint4函数。
3、如何做到,在中断保持高电平的状态,可以Disable中断?
------解决方案--------------------
感觉还是和你驱动对中断控制器的控制有关吧。
了解一下对应的中断控制器原理,包括触发方式,是否真的关闭了。
还有中断优先级问题,如果一直高点平,可能只是这个高优先级的触发 别的中断没有机会,只能等待,所以这个高优先级中断执行完别的才能执行。
------解决方案--------------------
1.首先寄存器初始化工作一般放在open或者probe函数中,你编写的中断叫中断上半部,linux对上半部要求快速完成,你可以把寄存器初始化代码放中断之前的open或者probe中
2.当中断信号一直是高电平,表示你一直向CPU提出中断请求,然后CPU相应后执行中断服务程序,而你的中断服务程序一开始就在寄存器初始化,这就是前面提到的中断服务程序要完成主要任务,把其他次重要任务放在下半部完成。
3.你的第三个问题应该也考虑到高电平时,中断程序不断执行吧。解释下,当保存高电平进入上半部后,你可以使用关指定中断线函数屏蔽这个中断,disable_irq(unsigned int irq)