Simple gestionnaire d'interruption: request_irq retourne le code d'erreur -22
Je suis en train d'écrire un simple module de noyau, qui pourrait enregistrer une interruption et le gérer.
Cependant, lorsque j'essaie d'enregistrer d'interruption par l'appel de la request_irq fonction,
il retourne le code d'erreur -22 :
ERREUR: Ne peut pas demander IRQ 30 - code -22 , EIO 5 , EINVAL 22
Je crois, ce code d'erreur est égale à EINVAL (argument non valide)
S'il vous plaît dites-moi, ce que je fais de mal. Voici un module:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <asm/exception.h>
#include <asm/mach/irq.h>
void int068_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
printk("Interrupt should be handled there\n");
}
static int __init
clcdint_init(void)
{
unsigned int irq;
unsigned int irqflags;
int ret;
irq=68;
irqflags=IRQF_SHARED | IRQF_NO_SUSPEND;
ret = request_irq(irq, int068_interrupt,
irqflags, "clcdint-int068", NULL);
if (ret!=0) {
printk("ERROR: Cannot request IRQ %d", irq);
printk(" - code %d , EIO %d , EINVAL %d\n", ret, EIO, EINVAL);
}
printk("CLCDINT_INIT\n");
return 0;
}
module_init(clcdint_init);
static void __exit
clcdint_exit(void)
{
unsigned int irq;
irq=68;
free_irq(irq, NULL);
printk("CLCDINT_EXIT\n");
}
module_exit(clcdint_exit);
OriginalL'auteur Jake Badlands | 2013-03-06
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas passer NULL contexte (dernière paramètres de la request_irq ()) lors du traitement, une même ligne d'interruption (IRQF_SHARED drapeau est sur).
De comprendre pourquoi considérez le scénario suivant: vous avez deux identiques cartes réseau de partage de la même IRQ. Le même pilote va passer le même gestionnaire d'interruption de la fonction, le même numéro d'irq et la même description. Il n'y a aucun moyen de distinguer les deux cas de l'enregistrement, sauf via le paramètre de contexte.
Donc, par précaution, vous ne pouvez pas passer NULL contexte paramètre si vous passez par la IRQF_SHARED drapeau.
irqflags=IRQF_NO_SUSPEND;
, c'est finalement le travail!Même après l'application de la modification mentionnée dans le dernier commentaire, je suis toujours le même message d'erreur ("ERREUR: Impossible de demande d'IRQ 68 - code -22 , EIO 5 , EINVAL 22"). Savez-vous quelle peut en être la cause? (btw, je suis en utilisant la version de kernel 2.6.32, de sorte que certains de ces fichiers n'existe pas ici, c'est peut-être pertinent)
Le problème a à voir avec le numéro d'IRQ. Après avoir regardé webopedia.com/quick_ref/IRQnumbers.asp et de changer le numéro d'IRQ à 10, au lieu 0f 68, tout fonctionne.
chers gby, Actuellement je suis en train d'essayer de partager mon gestionnaire d'interruption d'une ligne d'interruption, et la modification de cette valeur NULL à-dire 1 vraiment travaillé. Remercier votre beaucoup pour cette. (corrigez-moi si je me trompe!) Dans ce cas, j'ai besoin de désactiver l'interruption aussi dans lors de l'écriture de mon nouveau gestionnaire d'interruption de programme, pourriez-vous svp me guider comment le faire.
le noyau Linux IRQ infrastructure normalement des appels de votre gestionnaire d'interruption avec interruption masqué automatiquement et démasque lorsque votre gestionnaire se termine. Si vous souhaitez l'IRQ de rester masqué après le gestionnaire d'interruption de fonction, vous pouvez appeler disable_irq_nosync (), mais veuillez noter que ce partage de la ligne d'interruption est probablement une mauvaise idée (vous auriez du blocage des interruptions à tous les appareils partagent la même ligne)
OriginalL'auteur gby
irqflags
a un type deunsigned int
, mais à l'origine il avait typelong
.Essayer la déclaration suivante, il sera certainement le travail:
request_irq(irq, int068_interrupt,IRQF_SHARED | IRQF_NO_SUSPEND, "clcdint-int068", NULL);
OriginalL'auteur Deval Vekaria