web-dev-qa-db-fra.com

Que se passe-t-il lorsqu'un ISR est en cours d'exécution et qu'une autre interruption se produit?

Que se passe-t-il si un ISR est en cours d'exécution et qu'une autre interruption se produit? La première interruption est-elle interrompue? La deuxième interruption sera-t-elle ignorée? Ou se déclenchera-t-il lorsque le premier ISR sera terminé?

MODIFIER J'ai oublié de l'inclure dans la question (mais je l'ai inclus dans les balises) que je voulais demander comment cela fonctionnait sur les AVR d'Atmel.

20
BenjiWiebe

Normalement, une routine de service d'interruption continue jusqu'à ce qu'elle soit terminée sans être interrompue elle-même dans la plupart des systèmes. Cependant, si nous avons un système plus grand, où plusieurs périphériques peuvent interrompre le microprocesseur, un problème priorité peut survenir.

Si vous définissez également le indicateur d'activation d'interruption dans l'interruption en cours, vous pouvez autoriser d'autres interruptions qui sont une priorité plus élevée que celle en cours d'exécution. Cette "interruption d'une interruption" est appelée une interruption imbriquée. Il est géré en arrêtant l'exécution de la routine de service d'origine et en stockant une autre séquence de registres sur la pile. Ceci est similaire à sous-programmes imbriqués. En raison de la décrémentation automatique du pointeur de pile par chaque interruption et de l'incrémentation subséquente par l'instruction RETOUR, la première routine de service d'interruption est reprise une fois la deuxième interruption terminée, et les interruptions sont traitées dans le bon ordre. Les interruptions peuvent être imbriquées à n'importe quelle profondeur, limitée uniquement par la quantité de mémoire disponible pour la pile.

Par exemple, dans le diagramme suivant, le thread A est en cours d'exécution. L'interruption IRQx provoque l'exécution du gestionnaire d'interruption Intx, qui est préempté par IRQy et son gestionnaire Inty. Inty renvoie un événement provoquant l'exécution du thread B; Intx renvoie un événement provoquant l'exécution du thread C.

enter image description hereRéf Image

Pour les interruptions matérielles, Chips de contrôleur d'interruption prioritaire (PIC) sont des puces matérielles conçues pour simplifier la tâche d'un périphérique présentant sa propre adresse au CPU. Le PIC évalue également la priorité des appareils qui lui sont connectés. Les PIC modernes peuvent également être programmés pour empêcher la génération d'interruptions inférieures au niveau souhaité.

MISE À JOUR: Fonctionnement de l'interruption imbriquée sur les AVR Atmel

Le matériel AVR efface le indicateur d'interruption global dans [~ # ~] sreg [~ # ~] avant d'entrer un vecteur d'interruption. Par conséquent, les interruptions restent normalement désactivées à l'intérieur du gestionnaire jusqu'à ce que le gestionnaire se termine, où l'instruction RETI (qui est émise par le compilateur dans le cadre de l'épilogue de la fonction normale pour un gestionnaire d'interruption) finira par activer d'autres interruptions. Pour cette raison, les gestionnaires d'interruption ne s'imbriquent pas normalement. Pour la plupart des gestionnaires d'interruptions, c'est le comportement souhaité, pour certains, il est même nécessaire pour empêcher interruptions infiniment récursives (comme UART interruptions, ou level- déclenché des interruptions externes).

Dans de rares cas, cependant interruptions imbriquées peut être souhaité en réactivant le drapeau d'interruption global le plus tôt possible dans le gestionnaire d'interruption, afin de ne pas différer autre interruption plus que nécessaire. Cela pourrait être fait en utilisant une instruction sei () juste au début du gestionnaire d'interruption, mais cela laisse encore peu d'instructions dans le prologue de la fonction générée par le compilateur pour fonctionner avec les interruptions globales désactivées. Le compilateur peut être chargé d'insérer une instruction SEI juste au début d'un gestionnaire d'interruption en déclarant le gestionnaire de la manière suivante:

ISR(XXX_vect, ISR_NOBLOCK)
{
  ...
}

où XXX_vect est le nom d'un vecteur d'interruption valide pour le type MCU.

Jetez également un œil à ceci Note d'application pour plus d'informations sur les interruptions sur les AVR Atmel.

27
gbudan

La façon dont interrompt le travail:

  1. Le code définit le bit "Global Interrupt Enable"; sans elle, aucune interruption ne se produira.

  2. Quand quelque chose arrive à provoquer une interruption, un indicateur est défini.

  3. Lorsque l'indicateur d'interruption est remarqué, le bit "Global Interrupt Enable" est effacé.

  4. L'ISR approprié est exécuté.

  5. Le bit "Global Interrupt Enable" est réinitialisé.

  6. Les choses reviennent maintenant à l'étape 2, sauf si un indicateur d'interruption est déjà défini pendant l'ISR; puis les choses reviennent à l'étape 3.

Donc, pour répondre à la question: lorsque le premier ISR est terminé, le deuxième ISR sera exécuté.

J'espère que cela t'aides!

5
BenjiWiebe