我所使用的内核是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就可以将其清零。