Moin, ich habe einen STM32F103 mit Bootloader und Firmware. Bootloader startet normal bei 0x8000000. Firmware bei 0x8010000. Problem ist, dass ich an der Firmware aktuell keine Veränderungen machen kann. Firmware wurde extern mit Keil erzeugt. Wenn ich mit meinem GCC einen Bootloader und eine Firmware erzeuge, so ist der Sprung vom Bootloader in die Firmware kein Thema. Sobald ich aber an 0x8010000 die eigentliche Firmware habe, friert mir die Geschichte komplett ein. Nun kann ich im Hex-Viewer sehen, dass der SP im Flash auf 0x20000400 bei mir liegt. In der eigentlichen Firmware allerdings auf 0x20005CE8. Liegt hier schon der Hund begraben? Wo müsste ich ansetzen, dass mein Bootloader mit der anderen Firmware zusammen arbeitet?
Nico W. schrieb: > Problem ist, dass ich an der Firmware aktuell keine Veränderungen machen > kann. Firmware wurde extern mit Keil erzeugt. Ja, das ist Dein Problem. > Nun kann ich im Hex-Viewer sehen, dass der SP im Flash auf 0x20000400 > bei mir liegt. In der eigentlichen Firmware allerdings auf 0x20005CE8. > > Liegt hier schon der Hund begraben? Wo müsste ich ansetzen, dass mein > Bootloader mit der anderen Firmware zusammen arbeitet? Nein, den Stack teilen sich Bootlaoder und Firmware ja nicht. Das ist somit auch der einzige Eintrag in der Vector-Table, der keine Probleme macht. Als Du die Firmware mit der Start-Adresse 0x8000000 gelinkt hast, bezogen sich z.B. auch alle Einträge in der Vector-Table auf diese Start-Adresse. Jeder Interrupt schlägt also fehl, weil jeder Eintrag um 0x10000 korregiert werden müsste. Jeder absolute Sprung in der Firmware führt jetzt an eine um 0x10000 zu korrigierende Adresse. Die einzige Möglichkeit, die ich sehe, ist die Firmware ab 0x8000000 stehen zu lassen und den Bootloader dort drüber zu plazieren Dann könntest Du den Reset_Handler()-Eintrag in der Vector-Table der Firmware auf den Start des Bootloaders setzen und dann vom Bootloader aus den Reset_Handler() der Firmware aufrufen (den Wert musst Du dann fest in den Bootloader backen). HTH Torsten
:
Bearbeitet durch User
Danke für deine Antwort. Vielleicht kam das im ersten Post nicht genau rüber. Die Firmware liegt generell bei 0x8010000. Das ist keine Idee von mir. Davor liegt ein Bootloader. Den möchte ich mit meinem Bootloader überschreiben. Sobald ich diesen Bootloader aber überschreibe, läuft die normale Firmware nicht mehr an und hängt sich auf.
Nico W. schrieb: > Sobald ich diesen Bootloader aber überschreibe, läuft die normale > Firmware nicht mehr an und hängt sich auf. Das klingt so, als würde Dein Bootloader die Applikation nicht richtig starten. Ich würde da mal im Assembler durch debuggen und mir die Register angucken. Hast Du im Bootloader alle Interrupts disabled, bevor Du die Firmware startest? In meinen Bootloadern gehe ich dazu immer noch mal eine Extra-Runde durch Reset. Dazu schreibe ich ein sehr spezielles Muster irgendwo ins RAM und wenn das direkt nach dem Reset dort steht, startet der Startup-Code die Firmware. Damit kann man dann sicher stellen, dass die HW wirklich ausreichend zurück gesetzt ist.
Was heißt "einfrieren"? Endlosschleife, Hardfault? Neben den Interrupts ist auch die Clock-Init eine gefährliche Sache. Wenn der Bootloader etwa die PLL schon entsprechend konfiguriert kann es durchaus sein, dass in der eigentlichen Applikation ewig auf irgendwelche Bits gewartet wird weil man vergeblich versucht die PLL erneut zu setzen.
Torsten R. schrieb: > In meinen Bootloadern gehe ich dazu immer noch mal eine Extra-Runde > durch Reset. Dazu schreibe ich ein sehr spezielles Muster irgendwo ins > RAM und wenn das direkt nach dem Reset dort steht, startet der > Startup-Code die Firmware. Damit kann man dann sicher stellen, dass die > HW wirklich ausreichend zurück gesetzt ist. Das scheint keine schlechte Idee zu sein. Bin dank deinem Post mal allgemein auf die Idee gekommen, den Bootloader auf möglichst wenig zu reduzieren. Hab jetzt eigentlich keine Initialisierung von nix mehr drinne. Steht noch immer. Ich geh mal weiter in die Tiefen...
Vincent H. schrieb: > Was heißt "einfrieren"? Endlosschleife, Hardfault? Muss meinen Debugger noch zum laufen bekommen. Werde das aber noch genauer betrachten. Melde mich aber dazu nochmal.
Bin einen kleinen Schritt weiter. Es sieht zumindest so aus, dass mein Bootloader und der ursprüngliche Bootloader im Prinzip das gleiche machen. Alle Register sind am Ende zumindest identisch. Ich bin jetzt mal ein wenig durch den ursprünglichen Bootloader gesteppt. Bei einem bestimmten Punkt lege ich den STM dermaßen lahm, dass mein ST-Link keine Verbindung mehr bekommt. Dann hilft nur noch Strom komplett vom STM ziehen und ein Neustart. (Ich habe hier einen originalen ST-Link/V2 Isol). Hier der Bereich der abschmiert.
1 | 08001b3a: ldr r0, [pc, #504] ; (0x8001d34) |
2 | 08001b3c: ldr r0, [r0, #24] |
3 | 08001b3e: orr.w r0, r0, #1 |
4 | 08001b42: ldr r1, [pc, #496] ; (0x8001d34) |
5 | 08001b44: str r0, [r1, #24] |
6 | 08001b46: ldr r0, [pc, #496] ; (0x8001d38) |
7 | 08001b48: ldr r0, [r0, #4] |
8 | 08001b4a: orr.w r0, r0, #67108864 ; 0x4000000 |
9 | 08001b4e: ldr r1, [pc, #488] ; (0x8001d38) |
10 | 08001b50: str r0, [r1, #4] ; <--- break point |
11 | 08001b52: ldr r0, [pc, #480] |
Bei Break point sehen die Register wie folgt aus:
1 | r0 0x4000000 (Hex) |
2 | r1 0x40010000 (Hex) |
3 | sp 0x20000f68 |
4 | lr 0x8001b3b (Hex) |
5 | pc 0x8001b50 |
6 | xPSR 0xa1000000 (Hex) |
7 | msp 0x20000f68 |
8 | psp 0x3129b1a0 |
Wenn ich nach dem Break Point einen single Step mache, dann hängt sich alles auf. Bei einem Continue läuft die ganze Geschichte durch zur Firmware.
Kleine Korrektur. - Breakpoint bei 0x8001b4e - Single Step nach 0x8001b50 - Continue - Alles klappt - Breakpoint bei 0x8001b50 - Continue - Absturz
Torsten R. schrieb: > Hast Du im Bootloader alle Interrupts disabled, bevor Du die Firmware > startest? > > In meinen Bootloadern gehe ich dazu immer noch mal eine Extra-Runde > durch Reset. Dazu schreibe ich ein sehr spezielles Muster irgendwo ins > RAM und wenn das direkt nach dem Reset dort steht, startet der > Startup-Code die Firmware. Damit kann man dann sicher stellen, dass die > HW wirklich ausreichend zurück gesetzt ist. Da war bei mir anscheinend noch der Systick an. Asche über mein Haupt. Den zweiten Tipp habe ich jetzt aber auch genutzt. Ich nutze dazu jetzt das BKP-Register. Magic-Code ins BKP und dann einmal nen NVIC_SystemReset. In der nächsten Runde wird dann die komplette Initialisierung ausgelassen und direkt gesprungen.
Ja, macht Der Bootloader auch. Ich hab jetzt zusätzlich noch das CONTROL und BASEPRI auf Null gesetzt. Hatte damit auch einmal Probleme.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.