Forum: Compiler & IDEs avr-gcc: Anwendung bzw. Bootloader gezielt anspringen


von Timmy (Gast)


Lesenswert?

Wie resette ich meine Anwendung am schlauesten, ohne dass der Bootloader 
angesprungen wird? Ich habe das jetzt so probiert (aus der Anwendung 
heraus):

void (*reset)(void) = (void(*)(void))0;

Aufruf:
(*reset)();

Ist das korrekt? Mir bereitet es Kopfzerbrechen, was da mit dem Stack 
passiert. Der Stackpointer wird doch bestimmt nicht zurückgesetzt. Kann 
es sein, dass nach ein paar Resets so alles überläuft?

Dasselbe passiert, nehme ich an, wenn ich analog dazu meinen Bootloader 
direkt anspringe (aus der Anwendung heraus):

void (*start_bootloader)(void) = (void(*)(void))0x3E00;

Aufruf:
(*start_bootloader)();

Was wäre der richtige Weg?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

1
Jumping to non-symbolic addresses like so is not supported:
2
3
          int main (void)
4
          {
5
              /* Call function at word address 0x2 */
6
              return ((int(*)(void)) 0x2)();
7
          }

http://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html#index-g_t_0040code_007bEIND_007d-1677

von Adib (Gast)


Lesenswert?

Hallo Timmy,

Reset am besten per Watchdog reset, also watchdog aktivieren und dann 
warten.

Die Alternative mit dem Jump auf die Addresse muss den Stack setzten und 
alle Register auf default setzen bzw. Module deaktivieren.
Den Watchdog kann man zb nicht wieder ausschalten.

Hth, Adib.

von Timmy (Gast)


Lesenswert?

Über den Watchdog kann ich nicht gehen. Ich habe einen Bootloader, der 
in diesem speziellen Fall nicht aufgerufen werden darf. Im Bootloader 
werden verschiedene Register initialisiert, die ich aber auf anderen 
Werten brauche. Es muss daher direkt die Anwendung neu starten.
Ich habe einen atmega mit 32 KiB Flash, d.h. das oben Genannte sollte 
nicht zutreffen. "jmp 0" sollte dann doch gehen!?

von Karl M. (Gast)


Lesenswert?

Hi, was man i.a. Macht ist
1
cli
2
; and more
3
.set jump_addr = 0x0000 ; bzw, deine Codestartadresse
4
ldi R16,lo8(jump_addr)
5
ldi R17,hi8(jump_addr)
6
push R16
7
push R17
8
ret

von qrtdjvbhjl (Gast)


Lesenswert?

Welcher Prozessor?
Im ATXmega ist ein uebler Bug (zumindest in dem AtXmega64A3U, den ich 
hier vor mir habe), da werden die USB-Register bei einem solchen 
Einspringen (nach Appnote von Atmel) nicht korrekt gesetzt und der 
Bootlader ist dann nicht per USB erreichbar, also nutzlos.

qrtdjvbhjl

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Adib schrieb:
> Die Alternative mit dem Jump auf die Addresse muss den Stack setzten

Nö, muss sie nicht, zumindest dann wenn der Standard Startup-Code 
verwendet wird.  Der setzt nämlich den SP; und zwar auch bei solchen 
Devices, die den SP bereits beim Reset auf Ende RAM initialisieren.

Karl M. schrieb:
> Hi, was man i.a. Macht ist
1
> cli
2
> ; and more
3
> .set jump_addr = 0x0000 ; bzw, deine Codestartadresse
4
> ldi R16,lo8(jump_addr)
5
> ldi R17,hi8(jump_addr)
6
> push R16
7
> push R17
8
> ret

Nichst sehr hilfreich, denn wenn die Adresse nicht mehr 0 ist dann 
crasht dass.  Außerdem hann man jump_addr durekt anspringen.

Und für das alles braucht's auch kein Assembler...

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.