Activer l'interruption mais pas d'ISR

10

Je voudrais savoir ce qui se passe si une interruption est activée (ex: interruption d'arbitrage perdue dans le module CAN du LPC1778 de NXP), mais aucun ISR n'a été défini pour l'interruption.

Lorsqu'une telle interruption se produit, je sais que le drapeau d'interruption respectif sera défini, mais comme je n'ai défini aucun ISR, aucune adresse de décalage de vecteur d'interruption ne sera stockée pour le transfert de contrôle pour une telle interruption et le contrôle passera donc en arrière. à la routine principale, et je peux réinitialiser le drapeau d'interruption en l'interrogeant dans la routine principale (c'est ce que je pense). Y aura-t-il une latence lorsque le CPU découvrira qu'il n'y a pas d'ISR pour sauter?

Toute solution sur ce qui pourrait arriver peut vraiment m'aider.

Merci.

Mettre à jour:

J'ai activé l'interruption CAN sur mon uC, mais je n'ai pas défini d'ISR. Lorsque j'ai effectué un test de bouclage interne, le code est entré dans une boucle infinie. Voici le code de démontage de la boucle infinie en cours d'exécution sur LPC1778:

B       .
ENDP

Alors oui, si vous utilisez des interruptions, utilisez l'ISR.

AlphaGoku
la source
3
Vous n'avez pas besoin d'activer l'interruption pour pouvoir rechercher des indicateurs dans votre fonction principale. Si la condition qui définit l'indicateur se produit, cet indicateur sera défini, que vous ayez ou non activé l'interruption associée.
brhans
Vous dites qu'un indicateur d'interruption d'arbitrage de bus perdu sera défini même si je n'active pas "l'interruption d'arbitrage de bus perdue" (bien qu'il n'y ait pas de registre d'état qui puisse indiquer que l'arbitrage de bus a été perdu à l'exception du registre d'état d'interruption)?
AlphaGoku
Oui. Dans chaque MCU avec lequel j'ai travaillé, les drapeaux d'interruption sont définis chaque fois que la condition qui doit les définir se produit. L'activation de l'interruption fait que la MCU est dirigée vers le gestionnaire lorsque le drapeau associé est défini et la désactivation de l'interruption fait qu'elle ignore le drapeau et non le vecteur vers le gestionnaire même si le drapeau est défini . La désactivation / l'activation de l'interruption affecte uniquement le comportement du gestionnaire de saut d'interruption, et non le comportement de définition d'indicateur.
brhans
Wow, c'est quelque chose que je ne savais pas. Merci beaucoup. Ainsi, chaque pilote doit périodiquement également vérifier les registres d'état des interruptions et les réinitialiser même si les interruptions n'ont pas été activées :)
AlphaGoku
@AkshayImmanuelD uniquement si cela est important. Si l'interruption est toujours désactivée et que rien d'autre ne se soucie du drapeau, qu'il soit défini ou effacé est sans importance.
hobbs

Réponses:

17

S'il n'y a pas d'ISR défini, l'emplacement de l'instruction de saut dans le vecteur d'interruption sera soit nul, il peut s'agir d'un saut vers une routine d'exception, il peut sauter au début du programme, ou il peut contenir un "retour de interrompre "(par exemple RTI).

Voici un démontage d'une table d'interruption pour un processeur ATMega 16 montrant trois interruptions inutilisées vectorisées à une routine qui gère de tels cas (il peut simplement entrer dans une boucle infinie), et un vecteur légitime.

  28:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  2c:   0c 94 5c 00     jmp 0xb8    ; 0xb8 <__vector_11>   // <-- ISR
  30:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  34:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>

Laquelle des méthodes décrites précédemment pour gérer un ISR manquant dépendra à la fois de l'architecture du microcontrôleur et du compilateur. Dans le cas d'une instruction RTI ou équivalente, elle retournera immédiatement à l'application. Cependant, si l'interruption est déclenchée par niveau plutôt que déclenchée par front, cela provoquera probablement à nouveau le déclenchement de l'interruption, vous vous retrouverez donc dans une boucle infinie.

Je pense que cela peut dépendre de l'architecture de la puce si les interruptions internes (par exemple, un caractère reçu par un UART) sont considérées comme déclenchées par le niveau ou déclenchées par les bords. Les interruptions externes peuvent généralement être configurées comme l'une ou l'autre.

Il existe également un autre cas, parfois plusieurs interruptions sont regroupées et utilisent le même vecteur. Cela était particulièrement vrai pour les processeurs plus anciens qui n'avaient peut-être eu que quelques interruptions. Dans ce cas, la cause de l'interruption a été déterminée en interrogeant l'état des registres d'interruption, ce qui est un peu comme ce que vous proposez.

Mais c'est une mauvaise pratique dans tous les cas d'avoir des interruptions dans un système et aucun ISR défini. Ne le fais pas.

tcrosley
la source
2
...., ou il peut être indéfini.
Wouter van Ooijen
@WoutervanOoijen, c'est ce que je voulais dire par le vecteur d'interruption étant nul.
tcrosley
1
Les registres d'état ne peuvent pas indiquer quelques erreurs comme celle que j'ai mentionnée ci-dessus. Mais de telles erreurs ont une interruption. J'ai donc pensé à activer l'interruption juste pour identifier l'erreur et ne pas utiliser de code ISR. En simulant le LPC1778 en utilisant Keil, je n'ai eu aucune exception, donc je suppose que l'UC doit utiliser le RTI comme vous l'
avez
1
Quelque chose à savoir - si vous activez une interruption, mais que votre gestionnaire n'efface pas l'indicateur (ou qu'il n'y a pas de gestionnaire et que le comportement par défaut est un simple retour), vous constaterez très probablement que votre MCU se terminera pour toujours coincé dans une boucle d'interruption.
brhans
1
Les interruptions PIO sur l'ATSAM3X8E peuvent être déclenchées par front, mais la condition d'interruption une fois définie ne sera pas effacée tant que vous n'aurez pas lu l'ISR (registre d'état d'interruption) dans le gestionnaire d'interruption - résultant en la boucle @brhans mentionnée.
Simon Wright
1

Cela dépend de votre MCU, du compilateur et du reste du code.

Selon mon expérience:

  1. AVR - par défaut si vous ne spécifiez pas d'ISR, alors le vecteur d'interruption en flash sera 0x0000, ce qui signifie que votre application passera en reset chaque fois que cette interruption se produira.

    Si vous avez vraiment besoin de l'interruption, mais n'avez pas besoin du gestionnaire (par exemple, utilisez le mode de mise hors tension à faible bruit ADC et utilisez l'interruption uniquement pour réveiller le MCU), vous devez utiliser la macro EMPTY_INTERRUPT

  2. NXP Kinetis (ARM) - tous les vecteurs pointent par défaut vers un gestionnaire par défaut qui a un point d'arrêt, le CPU s'arrêtera simplement et le dira à votre débogueur.

filo
la source