Ich weiß, dass bei Computern der von der main()
Funktion zurückgegebene Wert vom Betriebssystem empfangen wird. Aber was passiert in der main()
Funktion eines Mikrocontrollers?
microcontroller
avr
c
user18118
quelle
quelle
main
mit zwei unterschiedlichen Signaturen unterstützen, die beide zurückgebenint
. Wenn Sie eine freistehende C-Implementierung verwenden, bestimmt diese Implementierung, wie Sie die Startfunktion schreiben sollen. Sie können keinevoid
Rückgabefunktion schreiben, nur weil sie nicht zurückgegeben wird. Das Verhalten von nicht wiederkehr unterscheidet sich von der Funktion Typ , die die Gesamt-Aufrufkonventionen beeinflusst.Antworten:
Auf einem Mikrocontroller
main()
wird nicht erwartet, dass er jemals beendet wird, und das Verhalten ist nicht definiert - es liegt also an dem, der die C-Laufzeit für den Mikrocontroller geschrieben hat. Ich habe Systeme gesehen, die:main()
, damit sie beim Beenden einfach erneut aufgerufen wird.main()
jemals beendet wird.main()
. Dies nennt man "ins Unkraut laufen".Ich habe noch nie einen gesehen, der überhaupt etwas mit dem von zurückgegebenen Wert macht
main()
. Wenn Ihnen dies wirklich wichtig ist, sollten Sie sich den Quellcode für die C-Laufzeitbibliothek Ihres Systems ansehen und möglicherweise ändern.quelle
main()
der einenint
Rückgabewert definiert, wurde offensichtlich nicht für einen Mikrocontroller ohne Betriebssystem entwickelt. Dies ist also ein unspezifiziertes Verhalten und abhängig von Ihrer C-Laufzeit kann alles passieren, wie Dave aufgelistet hat.main()
Rückgabewert zu definieren, geschweige denn , ihn zu definieren. Das liegt beim Implementierer.void main( void )
ist die Implementierung definiertes Verhalten , nicht unspezifiziertes Verhalten .main()
.Ein häufiges Missverständnis / Mythos ist, dass dies
int main
die einzige gültige Form ist, die in der Norm festgelegt ist. Das ist nicht wahr.Der C-Standard spricht von zwei Implementierungen: gehostet und freistehend. "Implementierung" bedeutet in diesem Fall Compiler. Gehostete Compiler kompilieren für ein bestimmtes Betriebssystem und freistehende Compiler kompilieren für eine bestimmte Bare-Metal-Anwendung. Eingebettete Systeme sind fast immer freistehende Systeme - auch im Fall von RTOS.
Für freistehende Implementierungen kann jede Form verwendet
main()
werden. Sie müssen nicht einmal eine Funktion namens main haben. Meistens verwenden sie das Formularvoid main (void)
, da es keinen Sinn macht, etwas zurückzugeben.Was hier zu beachten ist, ist, dass immer der Compiler die Form bestimmt
main()
und niemals der Programmierer.Freistehende Implementierungen , die tun von der Rückgabe etwas
main()
sehr fraglich. Sie wundern sich, ob die Leute, die den Compiler erstellt haben, tatsächlich den Standard gelesen haben ...Details hier .
quelle
Der C-Sprachstandard erlaubt die Implementierung definierter Variationen
void main( void )
und dies ist die übliche Form in eingebetteten Systemen - einfach, weil nicht erwartet wird, dass sie zurückkehren.Wenn Sie sich das Compiler-Setup ansehen, gibt es normalerweise ein Bootstrap-Code-Snippet, das vom Reset-Vektor aufgerufen wird und eine grundlegende Initialisierung (einschließlich z. B. Kopieren von Initialisierungswerten in Variablen) vor dem Aufrufen von main () durchführt.
Dies wird sich (normalerweise) auch in einer Endlosschleife befinden oder möglicherweise einen Reset durchführen, wenn es
main()
zurückkehrtquelle
Es hängt (wie andere Antworten bereits sagten) von Ihrer Toolchain ab, wird aber zum Beispiel in GCC
main
als andere Funktionen kompiliert, so dass sein Rückgabewert entsprechend den Aufrufkonventionen gespeichert wird (auf ARM verwende ich direkt nicht mit GCC, es wird auf R0 gesetzt) kurz vor der Rückkehr).Ich vermute, dass dies bei AVR-GCC ähnlich ist, sodass benutzerdefinierte Skripte diesen Wert nach den Hauptrückgaben verwenden können.
quelle
main
, seinen Rückgabewert erhalten kann. Natürlich wird es in 99,9% Situationen ignoriert, aber answer gibt es Informationen darüber, wer diesen Rückgabewert erhalten kann.