Was passiert, wenn ich exit () von meinem Programm aus aufrufe?


17

In setupoder loop, wenn ich einen exit(0)Anruf hinzufügen würde, an wen würde die Steuerung übergeben werden? Was wäre der nächste Zustand des Mikrocontrollers? Würde es die Ausführung und Abschaltung stoppen?

Ich benutze eine Revision 2 Arduino Uno.


Ich denke, es hört einfach auf. Es würde weder die Uhr ausschalten noch den Strom abschalten.
TheDoctor

Der Rest des Speichers sollte mit NOPAssembly-Anweisungen gefüllt sein , die nur für ein paar Taktzyklen pausieren
TheDoctor

Antworten:


12

Meine anfängliche Vermutung ist falsch. Ich hätte gedacht, es würde einfach von Schleife zurückkehren und die Kernbibliothek würde einfach wieder loop () aufrufen. Ich sehe jedoch, dass der folgende Code erstellt wurde. Beachten Sie, dass __stop_program eine harte Schleife ist ...

Ein Auszug aus der Auflistung von Blink.ino mit dem Zusatz exit (0):

// 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);
}

Die Demontage der oben genannten:

// 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>

Beachten Sie, dass Interrupts in der Lage wären, Dinge zu tun, wenn _exit nicht cli aufgerufen hätte. Das ist aber nicht der Fall.


avr-objdump -S {compiled *.elf file}Erzeugt eine Datei, die den C-Code enthält, der zu jedem Abschnitt des Assembly-Codes führt. Es ist viel einfacher zu folgen.
Connor Wolf

aaaund ich habe es gerade ausprobiert, und es gibt Inline-C-Code für die Schleifenfunktion nicht korrekt aus. Was zum Teufel?
Connor Wolf

Whoa, sehr seltsam. Ich kompilierte das Projekt mit Stino anstelle des Arduino-Editors, dekompilierte das *.elfdaraus und bekam dann die richtigen Debugging-Symbole. Ich denke, der Arduino-Texteditor / Button-Makro (ich lehne es ab, ihn als IDE zu bezeichnen, da dies nicht der Fall ist) entfernt die Debug-Informationen aus irgendeinem bizarren und dummen Grund nur aus der kompilierten Haupt-C ++ - Datei.
Connor Wolf

Es gibt eine Erklärung, und dies hängt damit zusammen, wie die IDE Ihre Dateien an einen temporären Speicherort kopiert. Sie können „fix“ , dass avr-objdump durch zu sagen , wo die Quelle ist: avr-objdump -S -I/path/to/the/sketch/folder xxx.elf . Dies ist der Pfad des Skizzenordners, nicht die .ino-Datei. Dann sollten Sie die C-Quelle in den Dump bekommen.
Nick Gammon

11

Nun, ich habe es gerade mit meinem Arduino Uno getestet und es hat den Code einfach vollständig gestoppt und alle Ausgaben so belassen, wie sie waren, als der Code aufgehört hat zu laufen (also hat es eine LED belassen, die ich an hatte). Es scheint keine E / A-Bereinigung zu geben, wenn Sie exit aufrufen. Dies war, was ich erwartet hatte, da die Arduino-IDE die Setup- und Loop-Funktionen bietet. Wenn Sie den ATMEGA * 28 mit einer anderen AVR-IDE programmieren, starten Sie mit der Hauptfunktion wie bei allen C / C ++ - Programmen. Die Setup- und Loop-Funktionen sind bei AVR-MCUs nicht Standard.

Hinweis: Durch Drücken der Reset-Taste wird der Code neu gestartet, falls Sie sich fragen.


Gut zu wissen. Ich suchte etwas Detaillierteres und auf einer niedrigeren Ebene. Beim Aufruf exit(0)der zerlegten Anweisungen sind (IIRC) __stop_program, cliund eine spinlock. Ich wollte überprüfen, ob dies korrekt ist, und erläutern, wie die Steuerung übergeben wird, z. B. Aufruf des Aufrufstapels ?, ISR-Aufruf?
Asheeshr

Ah, nun, ich habe Arduino noch nicht auf so niedrigem Niveau untersucht. Zu diesen Informationen möchten Sie vielleicht die Atmel-Website besuchen.
Jesse Laning
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.