2011-08-17 5 views
5

J'essaye de programmer un IRQ GPIO sur la carte d'évaluation AT91SAM9M10-EKES. J'ai réussi à enregistrer l'IRQ et l'IRQ fonctionne. Cependant, certaines interruptions sont manquées. J'envoie 26, et je ne reçois que 22.GPIO IRQ sur Linux embarqué basé sur ARM

Le code:

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

Ce n'est pas tout conducteur, mais c'est la partie réelle qui traite de l'IRQ. Si quelqu'un voit un problème dans le code, ou peut suggérer un moyen de savoir pourquoi je perds 4 interruptions, veuillez répondre. Je suis coincé sur ce pendant des heures ... :(

Merci. Ramon.

Répondre

4

Je suppose que vous déclenchez vos interruptions avec un système externe (peut-être un microcontrôleur ou quelque chose qui peut basculer le GPIOS) Comme je ne vois pas un vrai ack de l'interruption, je suppose que le système externe ne il faut que l'interruption soit gérée pour en déclencher une nouvelle. Printk est une fonction très lente et c'est pourquoi certaines interruptions peuvent vous échapper: une nouvelle peut être déclenchée pendant que vous manipulez la précédente.

Donc, je conseille de ne pas utiliser printk dans le gestionnaire. Si vous voulez réaliser quelque chose comme ceci, il vaudrait mieux utiliser une tasklet ou une workqueue comme moitié inférieure du gestionnaire d'interruption.

Je ne peux que recommander la lecture du chapitre 10 des pilotes de périphériques Linux.

Oh et en passant, votre gestionnaire IRQ ne doit pas renvoyer 0 mais IRQ_HANDLED.

+1

le printk est la raison !! Ça marche. Merci. – stdcall

+0

@ Longfield: Pouvez-vous s'il vous plaît répondre à ce http://stackoverflow.com/questions/24608817/interrupt-on-gpio-line-is-not-being-detected? –

1

Ok, en fait, le problème est que je les broches GPIO, tandis que les broches GPIO ne prennent pas en charge le drapeau de IRQF_TRIGGER_FALLING , ce qui est exactement ce dont j'ai besoin, donc probablement, le gestionnaire d'interruptions ne reconnaît pas le signal correctement Je trouve que j'ai besoin d'utiliser les broches externes pour IRQF_TRIGGER_FALLING active les IRQ

+0

Hey j'ai un problème similaire. Pouvez-vous s'il vous plaît regarder dans http://stackoverflow.com/questions/24608817/interrupt-on-gpio-line-is-not-being-detected –

Questions connexes