Hi!
Ich hab das (allerdings beim STM32F4) so gemacht:
- Die Anwendung liegt bei 0x08000000, der Bootloader bei 0x08020000, so
kann man mit normalem Programmierer immer auch die Anwendung
überschreiben, ohne den Bootloader mit zu überschreiben; den Bootloader
programmiere ich an diese Adresse mit dem ST-Link Utility
- Wichtig hier ist, sich die Sektoraufteilung des Flash anzusehen, am
einfachsten beim Beschreiben ist es, ganze Sektoren zu löschen. Daher am
besten den Bootloader bei einem neuen Sektor starten lassen!
- Das Bootloader-Programm braucht einige Besonderheiten: Im Linker-File
muss der ROM Origin auf 0x08020000 gesetzt werden. Zudem muss die
Vektor-Tabelle ein Offset von 0x20000 bekommen (verwendet in der
system_stm32fxxx.c Datei):
1 | #define VECT_TAB_OFFSET 0x00000
|
- In der eigentlichen Anwendung gibt es einen Aufruf, welcher den Proz.
zurücksetzt und dann in den Bootloader springt, etwa so:
1 | uint8_t bootloader_init(void) {
|
2 |
|
3 | //magic RAM constant
|
4 | *((uint32_t *)0x2000FFF0) = 0xDEADBEEF;
|
5 | NVIC_SystemReset();
|
6 |
|
7 | return 1;
|
8 |
|
9 | }
|
- Vor Aufruf des Reset-Vektors wird eine Speicheradresse 0x2000FFF0 mit
einem besonderen Wert (magic constant) beschrieben.
- Im Startskript der Anwendung ist dann die eigentliche Verzweigung in
den Bootloader:
1 | Reset_Handler:
|
2 | //check for magic constant in RAM for bootloader operation
|
3 | ldr r0, =0x2000FFF0
|
4 | ldr r1, =0xDEADBEEF
|
5 | ldr r2, [r0, #0]
|
6 | str r0, [r0, #0] //invalidate constant to prevent jumping twice
|
7 | cmp r2, r1
|
8 | beq BootLoader
|
9 | //...
|
10 | //normal start script follows here
|
11 | //...
|
12 | BootLoader:
|
13 | ldr r0, =0x08020000
|
14 | ldr sp, [r0, #0]
|
15 | ldr r0, [r0, #4]
|
16 | bx r0
|
Empfehlenswert für das Beschreiben des Flash ist auch das Flash-Beispiel
aus der STM32 Standard Peripheral Lib.
Viel Erfolg!