STM32 + ARM-GCC: Linker produziert falsche Adressen

OP Persönliche Seite #2674327
Hallo Forum,

ich versuche mit dem ARM-GCC https://launchpad.net/gcc-arm-embedded/ 
unter Windows ein C/C++ Programm für den STM32F4 zu kompilieren. Ich 
habe dazu das Linker-Script und den Startupcode aus dem Beispiel von ST 
übernommen.
Das hat zunächst auch geklappt, dann habe ich eine Winzigkeit im Code 
verändert, und es folgten obskure Probleme, die darauf zurückzuführen 
sind, dass globale Variablen nicht richtig initialisiert wurden. Der 
Grund ist:
Der Linker packt in den Flash den ISR-Vector, den Programmcode, und 
danach drei Arrays preinit_array, init_array, fini_array aus 
Funktionspointern (d.h. einfach Flash-Adressen), die beim Starten / 
Beenden des Programms aufgerufen werden (Kon/de -struktoren von globalen 
Instanzen von C++ Klassen). Danach folgen an einem Stück die 
Initialisierungsdaten für die globalen Variablen.
Der Linker setzt dann, wie im ld-Script angegeben, folgende Labels:
- _sidata, die Anfangsadresse der Initialisierungen im Flash
- _sdata der Anfang der zu initialisierenden Daten im RAM
- _edata das Ende dieser Daten
Der Startupcode macht dann quasi ein
1
memcpy(_sdata, _sidata, _edata-_sdata);
 in Assembler, was alle globalen Variablen initialisiert. Nun scheint 
aber bei mir der Linker das _sidata Label falsch zu setzen, und zwar um 
4 Bytes zu klein, sodass der Startupcode die falschen daten (nämlich das 
fini_array) in den RAM kopiert, sodass alle globalen Variablen falsch 
gesetzt sind... Und ich habe keine Ahnung, woran das liegt!
Der angehängte Code lässt sich mit "ruby build.rb" kompilieren (dazu 
muss man den ruby-Interpreter installiert haben) oder alternativ mit der 
build.bat, müsste mit anpassen der Pfade auch unter Linux gehen. Das 
kompilat ist um "Debug" Verzeichnis auch mitgeliefert, als .elf, .hex 
und .bin sowie die Disassembly. Im letzteren sieht man, dass _sidata auf 
0x080021ac gesetzt wird, während die Daten im Flash tatsächlich erst bei 
0x080021b0 anfangen...

Hat jemand eine Ahnung was ich falsch mache? Vielen Dank im Voraus!
Angehängte Dateien:
Gast #2674338
Hast du schon mal versucht die Sprungmarken manuell zu setzen?


PS: Kann es sein, dass du auf Männer stehst? Kam mir gerade so rüber als 
ich zwischen den Zeilen las.
OP Persönliche Seite #2675315
Habe jetzt nach unendlicher Suche und Fummelei und Starren auf den 
Hexeditor den Fehler doch noch gefunden. Im Linkerscript muss statt
1
  /* used by the startup to initialize data */
2
  _sidata = .;
3

4
  /* Initialized data sections goes into RAM, load LMA copy after code */
5
  .data : 
6
  {
7
    . = ALIGN(4);
8
    _sdata = .;        /* create a global symbol at data start */
9
    *(.data)           /* .data sections */
10
    *(.data*)          /* .data* sections */
11

12
    . = ALIGN(4);
13
    _edata = .;        /* define a global symbol at data end */
14
  } >RAM AT> FLASH
folgendes
1
  /* Initialized data sections goes into RAM, load LMA copy after code */
2
  .data : 
3
  {
4
    . = ALIGN(4);
5
    _sdata = .;        /* create a global symbol at data start */
6
    *(.data)           /* .data sections */
7
    *(.data*)          /* .data* sections */
8

9
    . = ALIGN(4);
10
    _edata = .;        /* define a global symbol at data end */
11
  } >RAM AT> FLASH
12

13
  /* used by the startup to initialize data */
14
  _sidata = LOADADDR(.data);
stehen. Offenbar hat wird .data um ein word nach hinten geschoben, aber 
_sidata zeigt dann auf das word davor. Mit dieser Änderung zeigt _sidata 
immer auf die tatsächliche Adresse von .data . Hoffentlich ...

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.