基于 ARM 的嵌入式 Linux 上的 GPIO IRQ

5

我正在尝试在AT91SAM9M10-EKES评估板上编写GPIO中断请求。

我已成功注册了中断请求,并且中断请求正在工作。

然而,有一些中断被错过了。我发送了26个中断请求,但只收到了22个。

以下是代码:

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个中断的方法,请回复。我已经卡在这里几个小时了...:( 谢谢。 Ramon.
2个回答

4
我假设您是通过外部系统(可能是微控制器或其他可以切换GPIOS的设备)触发中断。由于我没有看到对中断的真正确认,我认为外部系统不会等待中断被处理,而是可能会触发一个新的中断。 printk是一个非常慢的函数,这就是为什么您可能会错过一些中断:在您处理前一个中断时,可能会触发一个新中断。
因此,我建议不要在处理程序中使用printk。如果您想实现类似功能,最好使用tasklet或workqueue作为中断处理程序的底半部分。
我只能推荐阅读《Linux设备驱动程序》第10章。
哦,顺便说一下,您的IRQ处理程序不应返回0,而应返回IRQ_HANDLED。

1

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接