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.


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.


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.


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.