Interruptions interruption d'autres interruptions sur Arduino?

j'ai un Arduino Uno (génial petit appareil!). Il y a deux interruptions; appelons-les 0 et 1. J'attache un handler pour interrompre 0 et un autre pour interrompre 1, en utilisant attachInterrupt() : http://www.arduino.cc/en/Reference/AttachInterrupt.

Interrompre 0 est déclenché et il appelle son gestionnaire, qui fait un certain nombre crunching. Si interrompre 0'gestionnaire est toujours en cours d'exécution lors de l' interrompre 1 est déclenchée, ce qui va arriver?

Va interrompre 1 interrompre interrompre 0, ou va interrompre 1 attendre jusqu'à interrompre 0'gestionnaire est effectuée en cours d'exécution?

veuillez noter que cette question se rapporte spécifiquement à Arduino.

22
demandé sur Peter Mortensen 2011-02-25 01:34:32

3 réponses

sur le matériel Arduino (alias AVR), les interruptions imbriquées ne se produisent que si vous créez intentionnellement les conditions permettant qu'elles se produisent.

avr-lib:

le matériel AVR efface le drapeau d'interruption global dans SREG avant d'entrer un vecteur d'interruption. Ainsi, normalement les interruptions resteront désactivées à l'intérieur du gestionnaire jusqu'à la sortie du gestionnaire, où L'instruction RETI (qui est émise par le compilateur dans le cadre de la fonction épilogue normale pour un interruption handler) va éventuellement réactiver d'autres interruptions. Pour cette raison, les manipulateurs d'interruption ne nichent normalement pas. Pour la plupart des gestionnaires d'interruptions, c'est le comportement désiré, pour certains il est même nécessaire afin d'éviter des interruptions infiniment récurrentes (comme des interruptions UART, ou des interruptions externes déclenchées par le niveau). Dans de rares cas, bien qu'il puisse être souhaitable de réactiver le drapeau d'interruption global le plus tôt possible dans le gestionnaire d'interruption, afin de ne pas reporter d'autres interruption de plus que ce qui est absolument 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 des interruptions globales désactivées.

(source: http://linux.die.net/man/3/avr_interrupts)

25
répondu gpcz 2011-02-24 22:44:58

Va interrompre 1 interruption d'interruption 0, ou s'interrompent 1 attendre jusqu'à ce que l'interruption 0 gestionnaire est effectuée en cours d'exécution?

à moins que vous ne réactiviez spécifiquement les interruptions dans un ISR (routine D'interruption de Service), alors ce qui est en cours d'exécution est terminé, plus une instruction de code machine de plus, avant l'entretien de la prochaine interruption.

Plus interrupts définit un drapeau à l'intérieur du processeur, qui est vérifié entre les instructions, pour voir si l'interruption doit être réparé. Les drapeaux sont vérifiés par ordre de priorité. Sur le Uno qui est:

 1  Reset 
 2  External Interrupt Request 0  (pin D2)          (INT0_vect)
 3  External Interrupt Request 1  (pin D3)          (INT1_vect)
 4  Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
 5  Pin Change Interrupt Request 1 (pins A0 to A5)  (PCINT1_vect)
 6  Pin Change Interrupt Request 2 (pins D0 to D7)  (PCINT2_vect)
 7  Watchdog Time-out Interrupt                     (WDT_vect)
 8  Timer/Counter2 Compare Match A                  (TIMER2_COMPA_vect)
 9  Timer/Counter2 Compare Match B                  (TIMER2_COMPB_vect)
10  Timer/Counter2 Overflow                         (TIMER2_OVF_vect)
11  Timer/Counter1 Capture Event                    (TIMER1_CAPT_vect)
12  Timer/Counter1 Compare Match A                  (TIMER1_COMPA_vect)
13  Timer/Counter1 Compare Match B                  (TIMER1_COMPB_vect)
14  Timer/Counter1 Overflow                         (TIMER1_OVF_vect)
15  Timer/Counter0 Compare Match A                  (TIMER0_COMPA_vect)
16  Timer/Counter0 Compare Match B                  (TIMER0_COMPB_vect)
17  Timer/Counter0 Overflow                         (TIMER0_OVF_vect)
18  SPI Serial Transfer Complete                    (SPI_STC_vect)
19  USART Rx Complete                               (USART_RX_vect)
20  USART, Data Register Empty                      (USART_UDRE_vect)
21  USART, Tx Complete                              (USART_TX_vect)
22  ADC Conversion Complete                         (ADC_vect)
23  EEPROM Ready                                    (EE_READY_vect)
24  Analog Comparator                               (ANALOG_COMP_vect)
25  2-wire Serial Interface  (I2C)                  (TWI_vect)
26  Store Program Memory Ready                      (SPM_READY_vect)

(notez que la réinitialisation ne peut pas être masquée).

il est possible Qu'une interruption de faible intensité soit en cours (p. ex. TIMER0_OVF_vect). Pendant que c'est occupé à faire son travail, plusieurs autres événements d'interruption peuvent se produire (et définir les bits correspondants dans le CPU). Ils seront traités dans l'ordre ci-dessus, pas dans l'ordre dans lequel ils se trouvent en fait dans temps.

il y a des registres matériels qui peuvent être écrits, pour annuler une interruption en attente - c'est-à-dire pour effacer le drapeau.


la raison de mentionner "une instruction de code machine de plus" est que le processeur est conçu pour garantir que lorsqu'il passe d'interruptions non activées à des interruptions activées, une instruction de plus est toujours exécutée.

Cela vous permet d'écrire du code comme ceci:

  interrupts ();             // guarantees next instruction executed
  sleep_cpu ();              // sleep now

sans cela, un interruption peut se produire avant d'aller dormir. Ce qui signifie que vous ne vous réveillez jamais, parce que vous comptiez sur l'interruption qui se produisait cours sommeil, pas avant.


comme C'est merveilleusement idiot de Freescale et Atmel d'utiliser les mêmes noms d'instructions, mais avec des significations inversées

C'est pourquoi je préfère les mnémoniques de interrupts et noInterrupts parce que l'intention est très claire. Ils sont mis en oeuvre par les définit dans le noyau de fichiers à inclure.

4
répondu Nick Gammon 2016-03-07 06:47:25

je vais laisser ma réponse à cette vieille question, parce que la réponse approuvée est périmée.

Docs mentionnez que les interruptions arduino ont la priorité:

si votre sketch utilise plusieurs ISRs, un seul peut fonctionner à la fois, les autres interruptions seront exécutées après que l'actuel se termine dans un ordre qui dépend de la priorité qu'ils ont.

Il fournit également un lien pour plus d'info:

Pour en savoir plus informations sur les interruptions, voir notes de Nick Gammon.

Selon les sections Quelle est la priorité d'interruption? et les interruptions peuvent-elles se produire lorsque les interruptions sont désactivées? nous pouvons conclure que:

  1. les Interruptions sont basés sur la liste de drapeaux. Lorsqu'un événement se produit le drapeau correspondant est réglé.
  2. si IRS ne peut pas tirer maintenant, il peut être appelé à tout moment plus tard parce que le drapeau est enregistrer.
  3. il y a une liste de toutes les interruptions disponibles cela dépend généralement de la puce. Le plus haut de la liste, plus le prioritaire.

ainsi, des interruptions différentes ne s'interrompent pas, elles seront exécutées selon leur priorité.

0
répondu kelin 2016-02-03 08:42:58