Forum: Mikrocontroller und Digitale Elektronik STM32 Flash Sektor ändern für Bootloader


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Bert S. (kautschuck)


Angehängte Dateien:

Lesenswert?

Hi,

Ich habe einen Bootloader programmiert und versuche nun in meiner 
Applikation die Flash Adresse für die Vector Table zu ändern. Es handelt 
sich um einen STM32F722RC mit 256kByte Flash, wobei ich die ganze 
Applikation ab Sektor 4 starten möchte, sprich Adresse 0x08010000U.

Sektoren 2 und 3 verwende ich für eine EEPROM Emulation, das 
funktioniert soweit auch gut. Nun habe ich zuerst eine kleine 
Testapplikation geschrieben, diese läuft sauber, wenn ich das Linker 
File und system_stm32f7xx.c so anpasse, dass die Vector Table bei 
0x08010000U startet. Das ganze wurde aber mit der neuesten STM32CubeIDE 
erstellt. Die Test Applikation braucht aber auch nur 6kByte Flash.

Meine alte Applikation braucht 116kByte Flash und wurde noch mit einer 
älteren CubeMX Version gebildet. Wenn ich das ganze auf den uC hochlade, 
dann bricht mir nach dem hochladen der Debugger ab und gibt eine Remote 
Failure Reply E31 aus. Wenn ich das ST_Link Utility verwende, kann ich 
auch alles flashen, jedoch läuft die Applikation nicht.

Noch zu erwähnen ist, dass ich die Applikationen momentan ohne 
Bootloader laufen lasse, also direkt in Atollic gebildet. Muss ich evtl. 
noch weitere settings vornehmen in den Linker-Einstellungen / Debug 
Einstellungen, was mir die neuste STM32CubeIDE automatisch erstellt?

Ich bin leider ratlos.

Edit: Ich habe auch schon das ganze Programm aus kommentiert, so dass 
nur noch die SystemClock init besteht sowie die while() Loop, jedoch 
genau das gleiche Problem. Daher vermute ich Atollic Einstellungen.

: Bearbeitet durch User
von Jim M. (turboj)


Lesenswert?

Bert S. schrieb:
> Meine alte Applikation braucht 116kByte Flash und wurde noch mit einer
> älteren CubeMX Version gebildet.

Wenn die nicht mit der geänderten Adresse neu verlinkt wurde, kannste 
die ganze Aktion vergessen.

von M. H. (bambel2)


Lesenswert?

Jim M. schrieb:
> Wenn die nicht mit der geänderten Adresse neu verlinkt wurde, kannste
> die ganze Aktion vergessen.

Korrekt. Die finale Executable ist nicht Positionsunabhängig. Sprich du 
musst neu Linken mit dem gewünschten Memory Layout im Linkerscript.

Wenn du das bereits korekt machst, kann auch das relocating der 
Vectortabelle noch fehlerhaft sein. Wie springst du in den Code?

Eine der einfachsten Möglichkeiten ist es, die Adresse des Reset 
Handlers aus der Vektortabelle auszulesen und anzuspringen.

Wie sieht die Adresse aus, an die vom Bootloader aus gesprungen wird? 
Ist das LSB der Adresse gesetzt? das wäre noch ein klassicher Fehler. 
Bei Thumb2 Adressen ist das LSB der Adresse immer gesetzt um den 
Befehlssatz zu signalisieren.

von Bert S. (kautschuck)


Lesenswert?

M. H. schrieb:
> Korrekt. Die finale Executable ist nicht Positionsunabhängig. Sprich du
> musst neu Linken mit dem gewünschten Memory Layout im Linkerscript.
>
> Wenn du das bereits korekt machst, kann auch das relocating der
> Vectortabelle noch fehlerhaft sein. Wie springst du in den Code?

Das Linkerscript ist bereits angepasst und die Vector Table ist an den 
korrekten Ort im Flash abgelegt:
1
  /* The startup code goes first into FLASH */
2
  .isr_vector :
3
  {
4
    . = ALIGN(4);
5
    KEEP(*(.isr_vector)) /* Startup code */
6
    . = ALIGN(4);
7
  } >FLASH

Das sollte also passen. Dann habe ich in system_stm32f7xx.c folgenden 
Offset definiert:
1
#define FLASH_BASE 0x00010000U

Das Programm springt dann mit
1
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;

M. H. schrieb:
> Eine der einfachsten Möglichkeiten ist es, die Adresse des Reset
> Handlers aus der Vektortabelle auszulesen und anzuspringen.

Ok, wo muss ich die Reset Handler Adresse setzen?

M. H. schrieb:
> Wie sieht die Adresse aus, an die vom Bootloader aus gesprungen wird?

Momentan verwende ich den Bootloader noch gar nicht, ich nehme die App 
und lasse sie erst einmal an der vorgesehenen Adresse laufen, erst 
später wenn das funktioniert springe ich mit dem Bootloader an diese 
Adresse.

M. H. schrieb:
> Wie sieht die Adresse aus, an die vom Bootloader aus gesprungen wird?
> Ist das LSB der Adresse gesetzt? das wäre noch ein klassicher Fehler.
> Bei Thumb2 Adressen ist das LSB der Adresse immer gesetzt um den
> Befehlssatz zu signalisieren.

Das muss ich mal noch mit dem STLink Utility prüfen.

von M. H. (bambel2)


Lesenswert?

Bert S. schrieb:
> Das Programm springt dann mit
> SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;

Nein. Das biegt nur die Position der Vektortabelle um. Wie du dann ins 
Programm kommst, kann unterschiedlich sein. Entweder du löst einen Reset 
aus (da weiß ich jetzt nicht auswendig, ob da das Umbiegen der Tabelle 
erhalten bleibt), oder du springst über einen Funktionspointer in den 
reset Handler deines Zielcodes.

von M. H. (bambel2)


Lesenswert?

Bert S. schrieb:
> Momentan verwende ich den Bootloader noch gar nicht, ich nehme die App
> und lasse sie erst einmal an der vorgesehenen Adresse laufen, erst
> später wenn das funktioniert springe ich mit dem Bootloader an diese
> Adresse.

Ah. So.... Du hast also eine normale App geschrieben, die du woanders 
hingebogen hast und willst sie jetzt einfach mal debuggen. Das sollte 
theoretsich gehen... Rafft dein Debugger auch, dass er den 
Einstiegspunkt ins Program umbiegen muss? Der Jlink bspw. kann den 
Einstiegspunkt aus dem elf file lesen. Wenn der Debugger den Startpunkt 
nicht richtig erkennt, beginnt dein core trotzdem am Anfang des Flashs 
nach einem Reset.

Bert S. schrieb:
> M. H. schrieb:
>> Eine der einfachsten Möglichkeiten ist es, die Adresse des Reset
>> Handlers aus der Vektortabelle auszulesen und anzuspringen.
>
> Ok, wo muss ich die Reset Handler Adresse setzen?

Das bezog sich auf einen Bootloader, der danach in den Reset des 
Applikation springt.

Der Einstiegspunkt deiner Applikation wird in der Vektortabelle im 
ResetVektor abgelegt. Das ist der erste Eintrag (bzw. der zweite, wenn 
man den Stackpointer an Offset 0 mitzählt).

Sprich: Wenn deine vektortabelle an Adresse 0x00 ist, dann liegt an 
Adresse 0x4 die Adresse des Reset Handlers.
Da steht dann bspw 0x08001001 drin. Hierbei ist, wie gesagt darauf zu 
achten, dass diese Adressen alle das LSB gesetzt haben, das dem Core 
mitteilt, welchen befehlssatz er hinter der Adresse erwarten darf. Der 
Code läge in diesem Fall an Adresse 0x08001000.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.