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

时间:2011-08-17 11:30:04

标签: linux-device-driver embedded-linux irq arm9 gpio

我正在尝试在AT91SAM9M10-EKES评估板上编程GPIO IRQ。 我成功注册了IRQ,IRQ正在运行。 但是,有些中断被遗漏了。我送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 个答案:

答案 0 :(得分:4)

我假设您正在使用外部系统(可能是微控制器或可以切换GPIOS的东西)触发中断。由于我没有看到真正的中断,我认为外部系统不会等待中断被处理以触发新的中断。

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

所以我建议不要在处理程序中使用printk。如果你想实现这样的东西,最好使用tasklet或workqueue作为中断处理程序的下半部分。

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

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

答案 1 :(得分:1)

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