Que se passe-t-il lorsque j'appelle exit () de mon programme?

17

Dans l'un setupou l'autre loop, si je devais ajouter un exit(0)appel, où le contrôle serait-il passé? Quel serait le prochain état du microcontrôleur? Cela arrêterait-il l'exécution et mettrait-il hors tension?

J'utilise un Arduino Uno de révision 2.

asheeshr
la source
Je pense que ça s'arrête. Cela n'arrêterait pas l'horloge ni ne mettrait hors tension.
TheDoctor
Le reste de la mémoire doit être rempli d' NOPinstructions d'assemblage, qui s'arrêtent juste pendant quelques cycles d'horloge
TheDoctor

Réponses:

12

Ma première supposition est fausse. J'aurais pensé qu'il reviendrait simplement de la boucle et que la bibliothèque principale appellerait simplement loop () à nouveau. Cependant, je vois que le code suivant a été créé. Remarquant que __stop_program est une boucle difficile ...

Un extrait de la liste de Blink.ino, avec la sortie (0) ajoutée:

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
  exit(0);
}

Le démontage de ce qui précède:

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 100:   80 91 00 01     lds r24, 0x0100
 104:   61 e0           ldi r22, 0x01   ; 1
 106:   0e 94 ca 01     call    0x394   ; 0x394 <digitalWrite>
  delay(1000);               // wait for a second
 10a:   68 ee           ldi r22, 0xE8   ; 232
 10c:   73 e0           ldi r23, 0x03   ; 3
 10e:   80 e0           ldi r24, 0x00   ; 0
 110:   90 e0           ldi r25, 0x00   ; 0
 112:   0e 94 f7 00     call    0x1ee   ; 0x1ee <delay>
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 116:   80 91 00 01     lds r24, 0x0100
 11a:   60 e0           ldi r22, 0x00   ; 0
 11c:   0e 94 ca 01     call    0x394   ; 0x394 <digitalWrite>
  delay(1000);               // wait for a second
 120:   68 ee           ldi r22, 0xE8   ; 232
 122:   73 e0           ldi r23, 0x03   ; 3
 124:   80 e0           ldi r24, 0x00   ; 0
 126:   90 e0           ldi r25, 0x00   ; 0
 128:   0e 94 f7 00     call    0x1ee   ; 0x1ee <delay>
  exit(0);
 12c:   80 e0           ldi r24, 0x00   ; 0
 12e:   90 e0           ldi r25, 0x00   ; 0
 130:   0e 94 1e 02     call    0x43c   ; 0x43c <_exit>

...

0000043c <_exit>:
 43c:   f8 94           cli

0000043e <__stop_program>:
 43e:   ff cf           rjmp    .-2         ; 0x43e <__stop_program>

Notez que si _exit n'avait pas appelé cli, les interruptions pourraient faire des choses. Mais ce n'est pas le cas.

mpflaga
la source
avr-objdump -S {compiled *.elf file}produit un fichier qui inclut le code C qui mène à chaque section du code assembleur. C'est beaucoup plus facile à suivre.
Connor Wolf
aaaet je viens de l'essayer, et il n'émet pas correctement le code C en ligne pour la fonction de boucle. Que se passe-t-il?
Connor Wolf
Whoa, extrêmement étrange. J'ai compilé le projet avec Stino au lieu de l'éditeur Arduino, décompilé le à *.elfpartir de cela, puis j'obtiens les symboles de débogage appropriés. Je pense que le Arduino éditeur de texte / bouton macro (je refuse de l' appeler un IDE car ce n'est pas) chose dépouillant les informations de débogage à partir de tout le fichier principal de C ++ compilé, pour une raison bizarre et stupide.
Connor Wolf
Il y a une explication, et c'est à voir avec la façon dont l'IDE copie vos fichiers dans un emplacement temporaire. Vous pouvez « solution » qui en disant objdump-où AVR la source est: avr-objdump -S -I/path/to/the/sketch/folder xxx.elf . Il s'agit du chemin du dossier d' esquisse , pas du fichier .ino lui-même. Ensuite, vous devriez obtenir la source C dans le vidage.
Nick Gammon
11

Eh bien, je viens de le tester avec mon Arduino Uno et il a complètement arrêté le code et laissé toutes les sorties telles qu'elles étaient lorsque le code a cessé de fonctionner (il a donc laissé une LED que j'avais allumée). Il ne semble pas y avoir de nettoyage d'E / S lorsque vous appelez exit. C'est ce que j'attendais car l'IDE Arduino fournit les fonctions de configuration et de boucle, si vous programmez l'ATMEGA * 28 avec n'importe quel autre IDE AVR, vous commencez avec la fonction principale comme tous les programmes C / C ++. Les fonctions de configuration et de boucle ne sont pas standard sur les AVR MCU.

Remarque: La pression du bouton de réinitialisation redémarre le code, si vous vous posiez la question.

Jesse Laning
la source
Bon à savoir. Je cherchais quelque chose de plus détaillé et de niveau inférieur . En appelant exit(0)les instructions démontées sont (IIRC) __stop_program, cliet un verrou tournant. Je voulais vérifier si cela est correct avec une explication de la façon dont le contrôle est passé, c.-à-d. Appel pile pop?, Appel ISR?
asheeshr
Ah, eh bien, je n'ai pas examiné l'arduino à un niveau aussi bas, pour cette information, vous voudrez peut-être consulter le site Web atmel.
Jesse Laning