Bootloader für FW-Update

OP #3289735
Lesenswert?

Hallo zusammen,

gleich verneweg, ich arbeite mit einem STM32F207VC und Keil µVision 4.

SO nun zu meinem Problem:
Ich versuche im Startupcode zu verzweigen, das sieht momentan so aus:

; Reset handler
Reset_Handler    PROC
                 EXPORT Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR    R0, =SystemInit
                 BLX    R0
          LDR    R0, =0x2001FFF0
          LDR    R1, =0xDEADBEEF
          CMP    R2,R1
          BEQ    Reboot_Loader
                 LDR    R0, =0x0800C000;
                 BX     R0
                 ENDP

Reboot_Loader    PROC
          EXPORT Reboot_Loader
          LDR    R0, =0x08004004
          LDR    SP, =0x08004000
                 BX     R0
                 ENDP

An der Position 0x0800 C0000 soll mein Hauptprogramm liegen und bei 
0x0800 4000 mein Flashloader zum updaten.

Den Flashloader bekomme ich mit 
__attribute__((section(".ARM.__at_0x08004000"))) void 
fnFlashloader(void); an die entsprechende Stelle bei den ganzen anderen 
Funktionen im Hauptprogramm wird dies allerdings etwas schwieriger.

Kann mir hier jemand weiterhelfen?

Schonmal vielen Dank im voraus.

Stephan
OP #3289993
Lesenswert?

Ich habe es mittlerweile geschafft meinen Code dort abzulegen, wo ich 
ihn haben will.
Hierzu habe ich meinen Flashspeicher in zwei teile zerlegt, den 
Flashloader mit dem obigen Befehl und den Rest mit 
__attribute__((section(".ARM.--autoat_0x0800C000"))).

Den Startup-Code habe ich dann dem ersten Flashbereich zugewiesen.

Allerdings lande ich beim sprung in die main() im HardFault_Handler.

Im Bild ist die Speicherverteilung zu sehen.

mfg Stephan
Angehängte Dateien:
OP #3295704
Lesenswert?

Ich hab es jetzt soweit hinbekommen, dass er mir in die main-Schleife 
springt:

; Reset handler
Reset_Handler    PROC
                 EXPORT Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR    R0, =SystemInit
                 BLX    R0
          LDR    R0, =0x2001FFF0
          LDR    R1, =0xDEADBEEF
           CMP    R2,R1
                 BEQ    Reboot_Loader
                 LDR    R0, =0x0800C001;
                 BX     R0
                 ENDP

Allerdings läuft er mir irgendwann in einen Hard-Fault.
Die verwendete Funktion läuft allerdings im "normalbetrieb", also ohne 
bootloaser einwandfrei.
Gast #3295739
Lesenswert?

Stephan Scherer schrieb:
> LDR    R0, =0x0800C001;
Das Thumb-Bit schlägt zurück. mit "BX main" wäre das nicht passiert. Was 
hast du denn am Anfang des Flashs vor 0x0800C000 ?

Stephan Scherer schrieb:
> LDR    SP, =0x08004000
Du lässt den Stack Pointer in den Flash zeigen? Das klingt ungesund.

Stephan Scherer schrieb:
> Allerdings läuft er mir irgendwann in einen Hard-Fault.
Das ist eine äußerst präzise Fehlerbeschreibung. Assembler-Listing der 
jeweiligen Stelle und Register-Inhalte anschauen.

Stephan Scherer schrieb:
> Die verwendete Funktion läuft allerdings im "normalbetrieb", also ohne
> bootloaser einwandfrei.
Du rufst nach dem Bootloader wieder den Reset_Handler auf? Direkt? Oder 
führst du einen kompletten System-Reset durch (NVIC_Reset oder wie das 
ging)? Wird denn dabei der Stack richtig initialisiert? In 0x08000000 
sollte sich der initiale Stack-Pointer-Wert befinden, der wird beim 
normalen starten automatisch von da geladen.
OP #3295754
Lesenswert?

Hallo Kindergärtner,

Kindergärtner schrieb:
> Das Thumb-Bit schlägt zurück. mit "BX main" wäre das nicht passiert.

Wie meinst du das genau?

Wenn ich BX main mache bekomme ich vom compiler eine Fehlermeldung.

Kindergärtner schrieb:
> Was
> hast du denn am Anfang des Flashs vor 0x0800C000 ?

Im ersten Sektor soll nur der Bootloader selber stehen und in den 
nächsten beiden ab 0x08004000 die Routinen zum Löschen und neu 
beschreiben. Aber soweit bin ich noch nicht :D

Bei dem fehler greift er auf die Adresse 0x600xxxx zu. Das sollte nicht 
möglich sein.

Der plan ist so, dass ich im Normalbetrieb den Magic value (0xDEADBEEF) 
in den Ram schreibe und mit NVIC_SystemReset(); den µC neu starte, den 
Magic Value auslese und dann in die Updateroutine wechsle.
Gast #3295782
Lesenswert?

Stephan Scherer schrieb:
> Wie meinst du das genau?
Wenn das unterste Bit der Sprungziel-Adresse 0 ist, versucht der Core in 
den ARM-Modus zu wechseln, was die Cortex-M nicht können, und daher 
crashen.
> Wenn ich BX main mache bekomme ich vom compiler eine Fehlermeldung.
Eher vom Linker... Da der Linker weiß dass die main im Thumb-Mode 
erstellt wurde setzt er der unterste bit auf 1 s.d. der Core den Sprung 
durchführen kann.

Stephan Scherer schrieb:
> Bei dem fehler greift er auf die Adresse 0x600xxxx zu. Das sollte nicht
> möglich sein.
Wo kommt die Adresse denn her? Musst du ein bisschen debuggen.

Stephan Scherer schrieb:
> Der plan ist so, dass ich im Normalbetrieb den Magic value (0xDEADBEEF)
> in den Ram schreibe
Na hoffentlich wird der nicht mit resettet... Schau mal ob der F2 auch 
Backup-Register hat, die werden wimre nicht gelöscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren