Forum: Compiler & IDEs Sprung nach 0x0000 aus Bootloader heraus


von Matthias (Gast)


Lesenswert?

Hi

ich habe eben einen Bootloader fertiggestellt. Diesmal mit dem AVRGCC
(ASM auf dem AVR ist einfach nicht mein Ding) Hat mit den
Hilfsfunktionen aus boot.h auch einwandfrei geklappt. Jetzt ist da nur
noch ein Problem:

Wie springe ich, wenn der Bootloader seine Aufgabe erledigt hat in die
eben geladene Applikation?

ein
asm volatile("rjmp 0x0000");
wird im List-File zu
19e8:  39 cf         rjmp  .-398      ; 0x185c

Springt also irgendwo mitten in den Bootloader (beginnt ab 0x1800).
Selbiges wenn ich einen Funktionspointer bei 0x0000 erzeuge und diesen
dann aufrufe. (Aus dem rjmp wird natürlich ein rcall, die Adresse
bleibt aber die gleich)

Um die Start-Adresse anzupassen hab ich einfach per
-Wl,--section-start=.text=$(ROM_START) die Adresse der text-section
verschoben.

Controller ist ein Mega8

Matthias

von Schmittchen (Gast)


Lesenswert?

Hattest du nicht letztens selbst den Tipp gegeben, daß nur ein WD-Reset
ein sauberer Reset ist? Also, was spricht dagegen?

von Matthias (Gast)


Lesenswert?

Hi

irgnedwie hatte ich in Erinnerung das man den WD nur Einschalten aber
nicht ausschalten kann. War aber wohl ein anderer Controller. Die
Lösung für obiges Problem würde mich aber trotzdem interessieren.

Matthias

von mmerten (Gast)


Lesenswert?

bei AVRs mit mehr als 8k ist rjmp/rcall natürlich durch jmp/call zu
ersetzen. Ein jmp 0x0000 bringst natürlich nicht, da hier ja alle I/O
Register nicht zurückgesetzt werden. Die beste möglichkeit ist hier der
WDR Reset

von Matthias (Gast)


Lesenswert?

Hi

>bei AVRs mit mehr als 8k ist rjmp/rcall natürlich durch jmp/call zu
>ersetzen.

Was du nicht sagst :-)
Der Mega8 hat aber nicht mehr als 8k. Also ist rjmp völlig richtig.

>Ein jmp 0x0000 bringst natürlich nicht, da hier ja alle I/O
>Register nicht zurückgesetzt werden.

Das laß mal meine Sorge sein.

>Die beste möglichkeit ist hier der WDR Reset

Das würde ich nicht so sehen. Man muß dabei im geladenen Programm
erstmal den WD stoppen wenn man ihn nicht verwendet. Der Bootloader hat
also Rückwirckungen auf das geladene Programm. Was noch dazu kommt ist
das beim Einschalten ja erstmal der Bootloader gestartet wird. Und da
möchte ich (bzw. die Hardware um den Mega8) ungern 16ms zusätzlich
warten müssen wenn der Bootloader nicht gewünscht ist.

Vor dem Herausspringen aus dem Bootloader kann man ja die Register im
IO-Bereich (wenn nötig) auf ihre ursprünglichen Werte zurücksetzen.

BTW:
Es interessiert mich einfach warum der Assembler des AVRGCC aus einem
"rjmp 0x0000" ein rjmp auf eine (für mich) zusammenhanglose Addresse
macht und noch viel mehr wie man das beheben kann.

Matthias

von Joerg Wunsch (Gast)


Lesenswert?

> Es interessiert mich einfach warum der Assembler des AVRGCC aus
> einem "rjmp 0x0000" ein rjmp auf eine (für mich) zusammenhanglose
> Addresse macht und noch viel mehr wie man das beheben kann.

Hängt vielleicht irgendwo mit der Verschiebbarkeit der Segmente
zusammen.

Andere Idee: ein globales Symbol auf Linkerebene als 0 definieren
(geht mit -Wl,--defsym=app_start=0) und dieses Symbol anspringen.

von Matthias (Gast)


Lesenswert?

Hi

das hat geholfen.
Im Listfile stimmt der Sprung. Auf der Hardware werd ichs morgen mal
testen. Danke.


Matthias

von Eugen Dischke (Gast)


Lesenswert?

ist es nicht möglich das beispiel von bootloader app note zu übernehmen
?
also

void (*appptr)( void ) = 0x0000;

und dann halt mit

appptr();

anspringen
 kannst du mal dein sourcecode posten, mich würde das als beispiel
interessieren, hab in lezter zeit versucht selber einen BL zu schreiben
( auch für mega 8), was mir aber net so gut gelungen ist. nicht zulezt
wegen des net so gut kommentierten AVRProg Protokolls. die mega 8 ID
musste ich erst durch probieren rausfinden, hast du vieleicht bessere
quellen oder hast du ein anderes programm für diesen zweck in gebrauch
?
MfG
eugen d

von Peter D. (peda)


Lesenswert?

Mit dem Watchdog kanns doch nicht gehen !

Das Watchdog-Reset geht ja auch wieder zum Bootloader zurück.

Solange die Bootloader-Fuse gesetzt ist, muß man nach 0x0000 springen,
anders kommt man da nicht hin.

Im Bootloader kann man auch die Fuses nicht umsetzen.

Es reicht aber in jedem Fall ein RJMP aus, da man ja übers obere Ende
springen kann (wrap around).


Peter

von Matthias (Gast)


Lesenswert?

Hi

Die von dir vorgeschlagene Methode hatte ich ja auch schon probiert.
Das was du da beschreibst ist ein Funktionspointer. Auch bei diesem
ersetzt der Linker 0x0000 durch die Adresse von main.

Im Moment nutze ich ein selbst geschriebenes VB Programm welches ein
eigenes, sehr einfaches, ASCII basiertes Protokoll fährt. Da es für
mich funktioniert habe ich auch nicht vor das zu ändern. Das Ganze soll
ja in 512 Byte passen.

Wenn du willst kann ich dir den Sourcecode mal zukommen lassen. Ist
aber wirklich nichts besonderes.

Matthias

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.