2011-08-17 12 views
5

Estoy tratando de programar una IRQ GPIO en la placa de evaluación AT91SAM9M10-EKES. Logré registrar la IRQ con éxito, y la IRQ está funcionando. Sin embargo, algunas interrupciones se pierden. Voy a enviar a 26 años, y sólo obtengo 22.GPIO IRQ en ARM basado en Linux incorporado

El código:

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

Esto no es todo el conductor, pero esta es la parte real que se ocupa de la IRQ. Si alguien ve un problema en el código o puede sugerir una forma de saber por qué pierdo 4 interrupciones, responda. Estoy atascado en esto por horas ... :(

Gracias. Ramón.

Respuesta

4

Supongo que está activando las interrupciones con un sistema externo (tal vez un microcontrolador o algo que pueda alternar la GPIOS). Como no veo una respuesta real de la interrupción, supongo que el sistema externo no para que la interrupción se maneje para quizás disparar una nueva.

printk es una función muy lenta y es por eso que puede omitir algunas interrupciones: una nueva puede activarse mientras todavía está manejando la anterior.

Así que aconsejo no usar printk en el controlador. Si desea lograr algo como esto, sería mejor usar un tasklet o una workqueue como la mitad inferior del manejador de interrupciones.

Solo puedo recomendar la lectura del Capítulo 10 de los Controladores de dispositivos Linux.

Ah, y dicho sea de paso, su manejador de IRQ no debería devolver 0 sino IRQ_HANDLED.

+1

¡la impresión es la razón! funciona. Gracias. – stdcall

+0

@Longfield: ¿Puedes responder a este http://stackoverflow.com/questions/24608817/interrupt-on-gpio-line-is-not-being-detected? –

1

Ok, en realidad, el problema es que he utilizado los pines GPIO, mientras que los pines GPIO no son compatibles con la bandera IRQF_TRIGGER_FALLING , que es exactamente lo que necesito. Probablemente, el controlador de interrupciones no reconoce la señal correctamente. Descubrí que necesito usar los pines externos para IRQF_TRIGGER_FALLING habilita IRQ.

+0

Hola, tengo un problema similar. ¿Puedes mirar en http://stackoverflow.com/questions/24608817/interrupt-on-gpio-line-is-not-being-detected –

Cuestiones relacionadas