ARM Linux中断机制之中断的初始化
unsigned int irq, struct irq_desc *desc)
{
#ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
desc->handle_irq(irq, desc);//直接调用上层中断处理函数
#else
if (likely(desc->handle_irq))
desc->handle_irq(irq, desc);
else
__do_IRQ(irq);//通用中断处理函数,该函数最终调用desc->handle_irq(irq, desc);
#endif
}
上层中断处理函数
上层中断处理函数有5个分别为:handle_simple_irq(),handle_level_irq(),
handle_edge_irq(),handle_fasteoi_irq()以及handle_percpu_irq()。
这几个函数在文件kernel/irq/chip.c中实现。常用的有两个handle_level_irq(),和handle_edge_irq()。
这5个上层中断处理函数都是通过调用函数handle_IRQ_event()来做进一步处理。
irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
{
irqreturn_t ret, retval = IRQ_NONE;
unsigned int status = 0;
if (!(action->flags & IRQF_DISABLED))
local_irq_enable_in_hardirq();
do {
。。。。。。
ret = action->handler(irq, action->dev_id);//执行中断处理函数。
。。。。。。
retval |= ret;
action = action->next;
} while (action);//调用该中断线上的所有例程
if (status & IRQF_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
return retval;
}
void
handle_level_irq(unsigned int irq, struct irq_desc *desc)
{
struct irqaction *action;
irqreturn_t action_ret;
。。。。。。
desc = irq_remap_to_desc(irq, desc);
。。。。。。
action = desc->action;
action_ret = handle_IRQ_event(irq, action);
。。。。。。
}
void
handle_edge_irq(unsigned int irq, struct irq_desc *desc)
{
spin_lock(&desc->lock);
。。。。。。
desc = irq_remap_to_desc(irq, desc);
。。。。。。
desc->status |= IRQ_INPROGRESS;
do {
struct irqaction *action = desc->action;
。。。。。。
desc->status &= ~IRQ_PENDING;
spin_unlock(&desc->lock);
action_ret = handle_IRQ_event(irq, action);
if (!noirqdebug)
note_interrupt(irq, desc, action_ret);
spin_lock(&desc->lock);
//该函数与函数handle_level_irq不太一样的是,该函数多了一个循环。即如果在本次中断
//的处理过程中该中断线上又有中断产生,则再次执行该中断线上的处理例程
/*
以下是5个常用的中断线状态。
#define IRQ_INPROGRESS 1 /* 正在执行这个 IRQ 的一个处理程序 */
#define IRQ_DISABLED 2 /* 由设备驱动程序已经禁用了这条 IRQ 中断线 */
#define IRQ_PENDING 4 /* 一个 IRQ 已经出现在中断线上,且被应答,但还没有
为它提供服务 */
#define IRQ_REPLAY 8 /* 当 Linux 重新发送一个已被删除的 IRQ 时 */
#define IRQ_WAITING 32 /* 当对硬件设备进行探测时,设置这个状态以标记正在被
测试的 irq */
*/
} while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
desc->status &= ~IRQ_INPROGRESS;
out_unlock:
spin_unlock(&desc->lock);
}
ARMLinux中断机制初始 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)