2011-08-17 89 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