您的位置:首页 > 运维架构 > Linux

linux 内核对中断标志的处理(SRCPND 清除)分析

2009-09-02 21:35 876 查看
我所使用的内核是2.4.20-8。问题出现在request_irq后立即产生中断,分析后发现原因是上次的中断申请标志没有被清除所导致的。经过查看源代码(如代码段1.0)发现只有在 do_IRQ(……)函数中清除中断标志,而这个函数是中断开放时才被调用。因此我们不能忽略申请中断后,所产生的每一次中断。

view plaincopy to clipboardprint?
代码段 1.0
static void s3c2410_mask_ack_irq(unsigned int irq)
{
INTMSK |= (1 << irq);
SRCPND = (1 << irq);
INTPND = (1 << irq);
}

for (irq=0; irq < NORMAL_IRQ_OFFSET; irq++) {
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
irq_desc[irq].mask_ack = s3c2410_mask_ack_irq;
irq_desc[irq].mask = s3c2410_mask_irq;
irq_desc[irq].unmask = s3c2410_unmask_irq;
}

asmlinkage void do_IRQ(……)
{
…………
spin_lock(&irq_controller_lock);
desc->mask_ack(irq);
spin_unlock(&irq_controller_lock);
…………
}
代码段 1.0
static void s3c2410_mask_ack_irq(unsigned int irq)
{
INTMSK |= (1 << irq);
SRCPND = (1 << irq);
INTPND = (1 << irq);
}

for (irq=0; irq < NORMAL_IRQ_OFFSET; irq++) {
irq_desc[irq].valid = 1;
irq_desc[irq].probe_ok = 1;
irq_desc[irq].mask_ack = s3c2410_mask_ack_irq;
irq_desc[irq].mask = s3c2410_mask_irq;
irq_desc[irq].unmask = s3c2410_unmask_irq;
}

asmlinkage void do_IRQ(……)
{
…………
spin_lock(&irq_controller_lock);
desc->mask_ack(irq);
spin_unlock(&irq_controller_lock);
…………
}

那么上面我们遇到的问题该怎么解决呢?

方法一:在调用request_irq()之前,调用enable_irq()开放中断。让系统的默认中断处理,处理掉这个要丢弃的中断。

方法二:对寄存器SRCPND直接进行清除操作,从2410的手册中我们可以知道,只要往对应位写入1就可以将其清零。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: