STM32F2 - Neue Firmware starten

Gast #2774721
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 };
#2774806
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
...
Gast #2774833
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 ?
#2774899
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
Gast #2775719
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);

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.