Forum: Mikrocontroller und Digitale Elektronik STM32F2 - Neue Firmware starten


von Leon (Gast)


Lesenswert?

Hallo, ich nutze den STM32F207 und habe folgendes Problem.
Meine derzeitige Firmware liegt im Adressbereich 0x08000000 - 
0x08010000.
Die neue Firmware (binäre Daten) erhalte ich über die UART. Diese 
Firmware soll im Adressbereich 0x08020000 - 0x08030000 liegen. Nun soll 
die neue Firmware in den Adressbereich der aktuellen Firmware 
(Adressbereich 0x08000000 - 0x08010000) kopiert und im Anschluss 
ausgeführt werden. Wie könnte man sowas mit dem STM32 realisieren ? Was 
müsste eventuell im Linker Skript verändert werden ?

Linker Skript:
1
/*###ICF### Section handled by ICF editor, don't touch! ****/
2
/*-Editor annotation file-*/
3
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
4
/*-Specials-*/
5
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
6
/*-Memory Regions-*/
7
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
8
define symbol __ICFEDIT_region_ROM_end__   = 0x08010000;
9
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
10
define symbol __ICFEDIT_region_RAM_end__   = 0x20020000;
11
/*-Sizes-*/
12
define symbol __ICFEDIT_size_cstack__ = 0x400;
13
define symbol __ICFEDIT_size_heap__   = 0x200;
14
/**** End of ICF editor section. ###ICF###*/
15
16
17
define memory mem with size = 4G;
18
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
19
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
20
21
22
define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
23
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };
24
25
initialize by copy { readwrite };
26
do not initialize  { section .noinit };
27
28
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
29
30
place in ROM_region   { readonly };
31
place in RAM_region   { readwrite,
32
                        block CSTACK, block HEAP };

von Phantomix X. (phantomix)


Lesenswert?

Du brauchst noch ein drittes Stück Software, meistens "Bootloader" 
genannt, in deinem Fall reicht nach dem Empfang Code für eine CRC und 
das Umkopieren aus.

Wenn 0...FFFF deine ganze Applikation ist und komplett durch 
20000...2FFFF ersetzt werden soll, könntest du mal schauen, ob du den 
Code fürs Umkopieren im RAM ausführen kannst. -> ST Application Notes, 
Reference Manual
1
/* Specify the memory areas */
2
MEMORY
3
{
4
  FLASH (rwx)     : ORIGIN = 0x08000000, LENGTH = 64K
5
  UPDATE (rw)     : ORIGIN = 0x80020000, LENGTH = 64K
6
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 112K
7
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
8
}
9
10
...

von Leon (Gast)


Lesenswert?

Vielen Dank für deine Idee. Das mit dem dritten Stück Software könnte 
man vielleicht auch so machen.

Die aktuelle laufende Applikation liegt zwischen dem Bereich 0x08000000 
- 0x0800FFFF. In diesem Bereich könnte ich ebenfalls eine Update Routine 
implementieren die zum Beispiel im Bereich 0x08001000 - 0x08002FFF.
Die neue Firmware liegt dann im Bereich 0x08020000 - 0x0802FFFF. Auch 
hier ist ebenfalls die gleiche Update Routine vorhanden nur im Bereich 
0x08021000 - 0x08022FFF. Nachdem nun alle Daten im Flashbereich 
0x08020000 - 0x0802FFFF abgelegt wurden, kann dann mittels 
Funktionspointer auf 0x08021000 die Update Routine zugegriffen und 
zugleich ausgeführt werden. In dieser Routine soll dann der Flashbereich 
0x08020000 - 0x0802FFFF in den Bereich 0x08000000 - 0x0801FFFF kopiert 
werden und im Anschluss soll noch ein Reset ausgelöst werden.

Wie man sowas mit einem STM32 realisiert weiss ich nicht. Was müsste im 
Startup-File im Linkerskript-File angepasst werden ?

von Phantomix X. (phantomix)


Lesenswert?

2 Probleme seh ich dabei:

- Wenn du den Updatemechanismus im Applikationsbereich ausführst, wird 
das ganze Krachen gehen, da der Updatemechanismus sich während des 
Kopierens erstmal selbst löscht

- Wenn du den Updatemechanismus "von woanders" ausführst - sei es im 
Flash oder im RAM - darf er intern keine festen Sprungadressen 
verwenden, das Fachwort dazu heisst "relocatable code"
-> http://en.wikipedia.org/wiki/Position-independent_code
-> http://www.ganssle.com/articles/arelocat.htm

von Leon (Gast)


Lesenswert?

Hallo Phantomix Ximotnahp,

die FlashUpdate Funktion befindet sich in der aktuell laufenden Firmware 
0x08001000 - 0x08002FFF und auch in der neuen Firmware 0x08021000 - 
0x08022FFF.

Auf einen Infineon Mikrocontroller habe ich dies bereits erfolgreich 
implementiert.
1
void (*FlashUpdate)(ulong,uword);
2
3
FlashUpdate = (void (*)(ulong,uword))((ulong)(FLASHADRESSE));
4
FlashUpdate(FLASHADRESSE,AnzahlSektoren);

von Leon (Gast)


Lesenswert?

Als Entwicklungsumgebung setze ich IAR Embedded Workbench ein.

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.