arm linux 下中断流程简要分析中断处理流程
__raw_readl(S3C2410_INTMSK);
mask |= 1UL < irqno;/*mask掉对应的中断号*/
__raw_writel(mask, S3C2410_INTMSK);/*写MASK寄存器*/
}
改函数仅仅是把MASK寄存器中对应的中断mask掉,即不再响应该中断
arch/arm/mach-s3c2410/Irq.c:
static inline void
s3c_irq_ack(unsigned int irqno)
{
unsigned long bitval = 1UL < (irqno - IRQ_EINT0);
/*清除pending寄存器的相应位*/
__raw_writel(bitval, S3C2410_SRCPND);
__raw_writel(bitval, S3C2410_INTPND);
}
由上面这两个函数可以看出来mask_ack_irq的作用是先mask掉该中断,并清除pending位,中断被mask掉后系统就不再响应了, 而pending位被清掉说明系统中该中断没有触发。一般在中断处理完后都要清pending位, 要不然系统会认为该中断又被触发了。
handle_edge_irq()里调用的unmask函数,其实就是打开相应的中断,让系统响应这个中断,代码就不列出来了。
接下来中断看handle_IRQ_event(),它才是真正的中断处理函数。
kernel/irq/handle.c:
/
* handle_IRQ_event - irq action chain handler
* @irq:the interrupt number
* @regs:pointer to a register structure
* @action:the interrupt action chain for this irq
*
* Handles the action chain of an irq event
*/
irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
struct irqaction *action)
{
irqreturn_t ret, retval = IRQ_NONE;
unsigned int status = 0;
handle_dynamic_tick(action);
/*下面这个if判断:当执行action操作时是否可以打开中断*/
if (!(action->flags & IRQF_DISABLED))
local_irq_enable_in_hardirq();/*打开中断*/
do {
/*
*中断handler,也就是我们通过request_irq注册的中断函数,对于IRQ_WDT就是
* s3c2410wdt_irq
*/
ret = action->handler(irq, action->dev_id, regs);
if (ret == IRQ_HANDLED)
status |= action->flags;
retval |= ret;
action = action->next; /*记得吗,如果该中断可以共享的话,它就不为NULL*/
} while (action);
if (status & IRQF_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
return retval;
}
该函数主要就是调用了action的handler函数,也就是我们用request_irq注册的中断例程。这里需要注意的是:如果我们注册中断的时候指明可以共享的话,则必须在我们的中断例程里判断当前产生的中断是否就是我们自己的中断,这可以通过传进来的参数来判断(该参数就是我们注册时提供的)。
OK,到这里整个中断的流程就大致分析完了。
armlinux中断处 相关文章:
- ARM linux的中断处理过程(11-09)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)