2011-08-17 95 views
5

我正在试图编写AT91SAM9M10-EKES评估板上的GPIO IRQ。 我成功注册了IRQ,并且IRQ正在工作。 但是,有些中断错过了。我送26,而我得到的只有22基于ARM的嵌入式Linux上的GPIO IRQ

代码:

static irqreturn_t wiegand_interrupt(int irq, void *dev_id){ 
    atomic_inc(&counter); 
    printk(KERN_WARNING "IRQ recieved, counting... %d\n",atomic_read(&counter)); 
    return 0; 
} 
irq1 = gpio_to_irq(AT91_PIN_PA21); 
if (irq1 < 0) { 
    err = irq1; 
    printk("Unable to get irq number for GPIO %d, error %d\n",AT91_PIN_PA21, err); 
    goto fail; 
} 

err = request_irq(irq1,wiegand_interrupt,0 ,"wiegand",NULL); 

irq2 = gpio_to_irq(AT91_PIN_PA20); 
if (irq2 < 0) { 
    err = irq2; 
    printk("Unable to get irq number for GPIO %d, error %d\n",AT91_PIN_PA21, err); 
    goto fail; 
} 

err = request_irq(irq2,wiegand_interrupt,0 ,"wiegand",NULL); 

这是不是整个驱动器,但是这是与IRQ涉及实际的一部分。 如果有人在代码中看到问题,或者可以建议一种方法来知道为什么我会丢失4个中断,请回复。我卡在这几个小时... :(

感谢。 拉蒙。

回答

4

我假设你正在触发你的中断与外部系统(可能是一个微控制器或可以切换GPIOS的东西)。由于我没有看到一个真正的中断ack,我假设外部系统不wa它的中断处理可能触发一个新的。

printk是一个非常慢的函数,这就是为什么你可能会错过一些中断:当你还在处理前一个中断时,可能会触发一个新中断。

所以我建议不要在处理程序中使用printk。如果你想实现这样的事情,最好使用一个tasklet或一个工作队列作为中断处理程序的下半部分。

我只能推荐阅读Linux设备驱动程序的第10章。

哦,顺便说一下,你的IRQ处理程序不应该返回0,而是返回IRQ_HANDLED。

+1

printk是原因!有用。谢谢。 – stdcall 2011-08-18 14:40:19

1

好吧,实际上,问题是,我使用的GPIO引脚,而GPIO引脚不支持IRQF_TRIGGER_FALLING标志,这正是我所需要的,所以可能中断处理程序不能正确识别信号 我发现我需要使用IRQF_TRIGGER_FALLING的外部引脚来启用IRQ's

+0

嘿,我有类似的问题。你可以请看看http://stackoverflow.com/questions/24608817/interrupt-on-gpio-line-is-not-being-detected – 2014-07-07 11:12:26