Forum: Mikrocontroller und Digitale Elektronik Hauptprogramm aus Bootloader aufrufen


von Michael S. (kyromaster)


Lesenswert?

Ich möchte einen (etwas komplizierteren) Bootloader programmieren 
(mega32 mit avr-gcc). Die Grundlagen habe ich verstanden, etwas ist mir 
jedoch noch nicht ganz klar.
Ich habe im Sourcecode vom chip45-Bootloader gesehen, dass er sich 
selbst aufruft. Ausserdem ruft er die main()-Methode des Programms als 
Funktionsaufruf auf.
Wie ist das, sind solche calls ein "normaler" Funktionsaufruf, d.h. kann 
ich im Bootloader ein Programm (also seine main()) aufrufen, und nach 
der Rückkehr weiteren Code im Bootloader ausführen, oder wird z.B. durch 
Initialisierungscode (.init-Sektionen im Hauptprogramm) der Stack 
zurückgesetzt, so dass eventuelle lokale Variablen (und Puffer) im 
Bootloader frei werden. Wenn das so wäre müsste man doch alle Puffer 
möglichst global im Bootloader deklarieren, da das Hauptprogramm diesen 
Speicher ja als "frei" ansieht?

gruß

Michael

von Wolfgang Horn (Gast)


Lesenswert?

Hi, Michael,

Du: "... Ausserdem ruft er die main()-Methode des Programms als
Funktionsaufruf auf."

Bitte schau doch mal: Stehen Bootloader und Application in derselben 
Source, lediglich verschiedenen Sections zugewiesen?

Wenn ich das Manual zum AVR-GCC richtig gelesen habe, dann kennt der 
Linker beim Linken des Bootloaders die Adresse von main(), kann sie 
aufrufen und spart sich die erneute Initialisierung.

Geht nicht mit jedem Compiler, aber mit GCC. Der vielleicht größte 
Vorteil: Funktionen im Bootloader können auch von der Application aus 
aufgerufen werden und brauchen nicht doppelt programmiert werden.

Beim nächsten Bootloader-Projekt werde ich das mal probieren.


Ciao
Wolfgang Horn

von Michael S. (kyromaster)


Lesenswert?

Also die bootloader-source die ich meine macht einfach einen Zeiger 
"void *startMain(void) = 0x00" und ruft diesen dann auf. Wenn das 
Hauptprogramm nicht ab 0x00 geladen wird muss man das halt ändern.
Weißt du wie es mit meiner Frage aussieht, also praktisch ob der 
kompilierte Code in seiner init-Section den Stack zurücksetzt oder 
nicht?
Wenn ich mir das genau überlege sollte er das ja eigentlich nicht tun.
Bei mir ist es so dass ich ja in meinem Bootloader eigentlich (ohne 
irgendwelche Hacks) keine Interrupts verwenden kann, d.h. ich habe mir 
gedacht der Bootloader lädt ein kleines Programm von der MMC-Karte, 
dieses benutzt dann die Interrupts und wenn es fertig ist (also seine 
main() ab 0x00) mache ich im Bootloader einfach weiter und lade das 
Hauptprogramm und führe es aus.
Nach Allem was ich bis jetzt gelesen habe sollte das ja möglich sein.

von Peter D. (peda)


Lesenswert?

Michael Stather wrote:

> Ausserdem ruft er die main()-Methode des Programms als
> Funktionsaufruf auf.


Wenn das 2 verschiedene Programme sind, dann krachts aber gewaltig.

Die Ressourcen des Bootloaders werden nicht freigegeben, sondern bleiben 
unnötig blockiert.
Und die Ressourcen der Applikation werden nicht allociert und nicht 
initialisiert.

Sowas ist also total verboten !

Der Bootloader muß immer den Startup-Code der Applikation aufrufen und 
der wird in der Regel den Stack neu aufsetzen, womit automatisch die 
Ressourcen des Bootloaders freigegeben werden.

Da die Applikation auf den Resetvektor 0x0000 gelinkt wird, reicht es 
einfach die Zahl 0x0000 als Funktionspointer zu casten und auszuführen.


Peter

von Michael S. (kyromaster)


Lesenswert?

Ah, also doch *g
Ich habe mich da vielleicht oben etwas dumm ausgedrückt, mit main() 
aufrufen meinte ich auch, einfach die Startadresse (z.B. 0x00) als 
Pointer setzen und dann diesen dereferenzieren, womit ja der 
Startup-Code ausgeführt wird.
Der Bootloader verfügt doch auch über nen Startup-Code, oder nicht? Ich 
habe mich schon gewundert denn der chip45-Bootloader ruft sich selbst 
auf (mit obiger Methode). D.h. es kann hier nicht zum Stack-Overflow 
kommen da der Stack jedes Mal zurückgesetzt wird.

Wenn das so ist, sind dann denn überhaupt Parameterübergaben an das 
Hauptprogramm (vom Bottloader aus möglich), die landen normalerweise ja 
auch auf dem Stack?

von Thorsten (Gast)


Lesenswert?

> Da die Applikation auf den Resetvektor 0x0000 gelinkt wird, reicht es
> einfach die Zahl 0x0000 als Funktionspointer zu casten und auszuführen.

Bzw. _asm("jmp 0").

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.