2011-08-17 26 views
5

Próbuję zaprogramować przerwanie GPIO na tablicy ewaluacyjnej AT91SAM9M10-EKES. Pomyślnie zarejestrowałem IRQ, a IRQ działa. Jednak niektóre przerwania są pomijane. Wysyłam 26, a ja się tylko 22.GPIO IRQ na opartym na ARM wbudowanym systemie Linux

kodu:

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); 

To nie jest cała kierowcą, ale jest to rzeczywista część, która zajmuje się IRQ. Jeśli ktoś zauważy problem z kodem lub może zasugerować, w jaki sposób mogę stracić 4 przerwania, odpowiedz. Utknąłem na to godzinami ... :(

Dzięki. Ramon.

Odpowiedz

4

Zakładam, że uruchamiasz swoje przerwania z systemem zewnętrznym (może mikrokontrolerem lub czymś, co może przełączać GPIOS). Ponieważ nie widzę prawdziwego potwierdzenia przerwania, zakładam, że system zewnętrzny nie waży to, aby przerwać obsługę, może wywołać nową.

printk to funkcja bardzo powolna, dlatego można pominąć niektóre przerywniki: nowy może zostać uruchomiony, gdy nadal będziesz obsługiwać poprzednią.

Tak więc radziłbym nie używać polecenia printk w programie obsługi. Jeśli chcesz osiągnąć coś takiego, lepiej byłoby użyć bloku zadań lub elementu roboczego jako dolnej połowy obsługi przerwań.

Mogę tylko polecić lekturę rozdziału 10 sterowników urządzeń Linux.

A tak przy okazji, twój przerywnik IRQ nie powinien zwracać 0, ale IRQ_HANDLED.

+1

the printk jest powodem !! to działa. dzięki. – stdcall

+0

@Longfield: Czy możesz odpowiedzieć na to http://stackoverflow.com/questions/24608817/interrupt-on-gpio-line-is-not-being-detected? –

1

Ok, faktycznie, problem jest to, że użyłem piny GPIO, natomiast piny GPIO nie obsługuje flagę IRQF_TRIGGER_FALLING więc jest to dokładnie to, czego potrzebuję, więc prawdopodobnie przerywnik nie rozpozna poprawnie sygnału Okazało się, że muszę użyć zewnętrznych pinów, aby IRQF_TRIGGER_FALLING włączał IRQ.

+0

Hej, mam podobny problem. Czy możesz spojrzeć na http://stackoverflow.com/questions/24608817/interrupt-on-gpio-line-is-not-being-detected –