Forum: Mikrocontroller und Digitale Elektronik STM32F4 mit Code::Blocks


von André W. (andre-w)



Lesenswert?

Für all diejenigen, denen die ganzen eclipse-basierten IDE-Lösungen für 
den Cortex-Mx und dem GCC nicht wirklich zusagen möchte ich hier eine 
Alternative vorstellen (in diesem Fall speziell für das 
STM32F4-Discovery-Board unter Windows - sollte aber auch ohne größere 
Probleme auch unter Linux und für andere Cortex-M Prozessoren zum laufen 
gebracht werden können):

Dazu braucht ihr:
1) Code::Blocks:
Ich verwende eine relativ aktuelle Version aus dem *SVN (#8086)* - mit 
der derzeit letzten Stable-Version wird es nicht funktionieren, da dort 
u.a. einige Funktionen im Debugger noch nicht zur Verfügung stehen.
Hier ein Link zur Detaillierten beschreibung der "Nightly-Builds": 
http://forums.codeblocks.org/index.php/topic,16560.0.html

Kurz zusammengefasst:
einfach den Inhalt dieser 3 Archive z.B. in C:\Programme\CodeBlocks\ 
entpacken:
http://prdownload.berlios.de/codeblocks/wxmsw28u_gcc_cb_wx2812_gcc452-TDM.7z
http://prdownload.berlios.de/codeblocks/mingwm10_gcc452-TDM.7z
http://prdownload.berlios.de/codeblocks/CB_20120707_rev8086_win32.7z
CodeBlocks kann danach einfach über eine Verknüpfung zur CodeBlocks.exe 
gestartet werden.

2) GNU Tools for ARM Embedded Processors:
Ich verwende die aktuellste Version (*4.6-2012-q2-update*) - die älteren 
Versionen haben noch einen Bug im GDB, der mit den absoluten Dateipfaden 
im Windows-Stil Probleme hat (der ":" bei C:\ wird falsch 
interpretiert), wodurch das Debugging mit CodeBlocks nicht funktioniert, 
also auf jedenfall die aktuellste Version des Compilers verwenden!
Direkter Download-Link - einfach installieren:
https://launchpad.net/gcc-arm-embedded/4.6/4.6-2012-q2-update/+download/gcc-arm-none-eabi-4_6-2012q2-20120614.exe

3) GDB-Server aus dem Atollic-Truestudio:
Nach der installation der kostenlosen Version liegt der GDB-Server in:
C:\Program Files\Atollic\ST-LINK_gdbserver\
Dieser ganze Ordner kann bei bedarf einfach kopiert werden und Atollic 
wieder deinstalliert werden.
Zur Verwendung muss nur die .bat-Datei ausgeführt werden, bevor der 
Debugger in CodeBlocks gestartet wird
Sollte der GDB-Server nicht richtig starten (als letzte Zeile der 
Ausgabe sollte stehen: "Waiting for client connect on port 61234") muss 
der ST-Link_V2_USBdriver.exe, der im gleichen Server wie der GDB-Server 
liegt, noch installiert werden.

4) Einstellungen in CodeBlocks:
Hauptsächlich muss nur der Pfad zum Compiler und Debugger eingestellt 
werden, der Rest wird durch das Projekt-File erledigt.
Dazu unter Settings->Compiler bzw. Settings->Debugger die Einstellungen 
entsprechend den angehängten Bildern vornehmen.
Am besten mit den Debugger-Einstellungen beginnen, da man sonst in den 
Compiler Einstellungen nicht gleich den richtigen Debugger auswählen 
kann.
Der executable-Path beim Debugger muss auf den arm-none-eabi-gdb.exe 
gesetzt werden (wird im Bild nicht ganz deutlich)
Die "Number of processes for parallel builds" sollte auf die Anzahl der 
CPU-Cores+1 gesetzt werden - also bei einem Dual-Core auf 3 - den Wert 
auf 1 zu lassen schadet bei der größe der meisten Projekte aber auch 
nicht..

5) Das Beispielprojekt aus dem Anhang:
Einfach irgendwo hin entpacken *(der Pfad darf KEINE Leerzeichen 
enthalten!)* - das Projekt aber noch nicht öffnen!

6) STM32F4 DSP StdPeriphLib V1.0.1:
http://www.st.com/internet/com/SOFTWARE_RESOURCES/SW_COMPONENT/FIRMWARE/stm32f4_dsp_stdperiph_lib.zip
Direkt in das Beispiel-Projektverzeichnis Entpacken.
Nach dem Entpacken sollte die Verzeichnisstrucktur so aussehen: 
STM32F4-Test\STM32F4xx_DSP_StdPeriph_Lib_V1.0.1\...

7) Projekt über das *.cbp-File aus CodeBlocks heraus öffnen

8) Unter Project->Build Options und Project->Properties können die 
genauen Einstellungen zum compilieren festgelegt werden. In den 
Properties->Build Targets kann dann auch eingestellt werden, welche 
Dateien aus der StdPeriphLib mit compiliert werden - im 
Beispiel-Projekt, das einfach die 4 LEDs des Discovery-Board 
nacheinander einschaltet werden nur die 'rcc' und 'gpio' benötigt - mehr 
ist derzeit deshalb auch nicht aktiviert..

9) Wenn die Debug-Konfiguration compiliert wurde und der GDB-Server von 
Atollic gestartet ist kann das Programm einfach in den Flash geschrieben 
werden, indem man Debug->Start/Continue anwählt (oder F8 drückt)
Wenn in den Debugger-Optionen, wie im Angehängten Bild zu sehen, die 
Option "Do NOT run the Debugee" aktiv ist wird nach dem Flashen der 
Prozessor angehalten - das Programm läuft erts bei einem zweiten Klick 
auf Debug/Continue los!

10) Wird die Release-Configuration compiliert befindet sich nach dem 
Compilieren in  bin/Release/ ein *.bin-File, das mit dem ST-Link utility 
in den Prozessor geflasht werden kann.

Wenn alle Schritte so befolgt werden sollte man direkt zu einer 
funktionsfähigen Firmware kommen.

Das Beispielprojekt ist mit Sicherheit nicht perfekt, aber ein guter 
Ansatz für erste Versuche mit CodeBlocks.
Woran ich zum Beispiel bis jetzt gescheitert bin ist, die Firmware beim 
Debuggen im Ram des Prozessors laufen zu lassen, um nicht bei jedem 
Versuch den Flash beschreiben zu müssen.
Vorschläge zur Verbesserung der Projekt-Einstellungen - vor allem der 
Compiler-Parameter - werden gerne entgegen genommen ;)
Vielleicht hat auch jemand noch einen Tipp, wie man einfacher an den 
GDB-Server von Atollic kommen kann, ohne dass man die ganze Software 
vorher installieren muss.

von erhardd (Gast)


Lesenswert?

...sehr gute Arbeit!
Ich fürchte nur, wer den Eclipse-Moloch schon am Laufen hat, wird vor 
einer neuen IDE zurückschrecken.

Wenn ich mich recht erinnere, ist CODE::BLOCKS bei weitem nicht so 
umfangreich!
Ich habe CB schon lange laufen, allerdings nur als Hilfseditor für z.B. 
RIDE, der von Haus aus keine .h - files anzeigt(ist aber kein Nachteil, 
den so ist es übersichtlicher, wenn die Programme grösser sind);
Das stm32_st-link-utility kann als .zip von ST heruntergeladen werden...

Wie stellst Du beim Projekt erstellen das Device ein? (Und das passende 
Linker-file?);
Du merkst sicherlich, ich habs selbst nochnicht ausprobiert...

von André W. (andre-w)


Lesenswert?

Das Device wird in den Build Options unter "Compiler Settings" und 
"Linker Settings" eingestellt, direkt über die Parameter, mit denen der 
Compiler gestartet wird. Also z.B. -mcpu=cortex-m4.
Das Linker-File ebenso über den entsprechenden Parameter. z.B. 
-T"${PROJECT_DIR}stm32_flash.ld"
Dabei muss man aber aufpassen, das in der Auswahl auf der linken Seite 
das ganze Projekt ausgewählt hat und nicht das Debug bzw. Release 
Target.

Man könnte das ganze aber auch noch etwas übersichtlicher gestalten, in 
dem man sich im Tab Custom-Variables eigene Variablen anlegt, die dann 
an den entsprechenden Stellen eingesetzt werden. (so hätte man eine 
Zentrale Anlaufstelle für die meisten Compiler-Optionen..)

von erhardd (Gast)


Lesenswert?

...die Idee ist gut!
Ich probiers aus, wenn ich die Zeit finde.
(Ätze grad ein neues Aufsteckboard WLAN/LAN für STM32F417)
Danke...

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich habe den Thread mal reingenommen in den Artikel STM32 unter 
"Programmierung".

von EMIDE (Gast)


Lesenswert?

http://www.emide.org/

* für ARM
* basiert auf Code::Blocks
* Plugin für J-Link gdbserver

von Alex E. (tecnologic) Benutzerseite


Lesenswert?

Moin,

Hab die emIDE gerade mal ausprobiert.
Wenn ich ein neues Projekt erstellen will zeigt er mir keinen Wizard an 
ich komme da also nicht weiter. Viel weiter habe ich dann garnicht 
getestet, weil mein Eclipse läuft. Aber interessant finde ichs schon.

Wie ist das mit Cpp bei Code::Blocks?

MfG

Tec

von André W. (andre-w)


Lesenswert?

Markus Müller schrieb:
> Ich habe den Thread mal reingenommen in den Artikel STM32 unter
> "Programmierung".

Danke, wollte ich bei Gelegenheit auch machen..


EMMIDE schrieb:
> http://www.emide.org/
>
> * für ARM
> * basiert auf Code::Blocks
> * Plugin für J-Link gdbserver

Ich habe mir das ganze gerade einmal kurz angeschaut, leider wäre das 
für mich keine Alternative, da offensichtlich wirklich nur der J-Link 
unterstützt wird und keine anderen Debugger, wie z.B. der ST-Link auf 
den Discovery-Boards. Somit ist wieder an spezielle Hardware gebunden.
Soweit ich das erkennen kann fehlt jetzt sogar die Möglichkeit einen 
beliebigen GDB-Server zu verwenden.
(Ich gehe einmal davon aus, dass Du der Verantwortliche von emIDE bist, 
da es ja anscheinend noch nicht so weit verbreitet ist..)
Mir ist aufgefallen, dass es keinen Quellcode mit den Änderungen zum 
ursprünglichen CodeBlocks Source-Code gibt. Ich bin zwar nicht wirklich 
Experte auf dem Gebiet, aber soweit mir bekannt ist lässt sich das so 
mit der GPL nicht vereinbaren..
Vor allem, da in emIDE einige interessante Bugfixes existieren, die bei 
CodeBlocks noch nicht verfügbar sind:

> "Double execution of forst additional GDB command, handle lines starting with # 
in additional GDB commands as comment"
Ich hatte schon einmal vermutet, dass CodeBlocks den "load"-Command, der 
in meinem Beispiel-Projekt als erster Command im GDB ausgeführt wird, 
zwei mal an den GDB sendet..

> "Added 'Reset target' to the debugger."
Den 'Reset Target'-Button gibt es in CodeBlocks nicht - ist allerdings 
auch kein großes Problem, da man ein "monitor reset" über das 
Debugger-Window auch direkt an den GDB absetzen kann. Es würde aber 
etwas Zeit sparen, wenn man nur einen Button anklicken müsste.

Was emIDE aber auch noch fehlt, ist eine Trennung zwischen Debugger 
starten und Programmspeicher beschreiben - ich habe zumindest öfter den 
Fall, dass ich zwar noch einmal Debuggen will, sich aber an dem 
Programmcode nichts geändert hat. Somit wäre ein neues beschreiben des 
Flash zum einen unnötige Zeit und zum anderen werden Write-Cycles des 
Flash verschwendet.

------------------------------------------------------------
Noch ein paar Tips zum Beispiel Projekt aus dem ersten Post:
Man könnte unter "Project->Properties->Debugger->Debug->Additional GDB 
Commands" den "load"-Befehl einfach herausnehmen, dann wird der Flash 
beim starten des Debuggers nicht neu beschrieben.
Das Flashen könnte dann bei aktivem Debugger durch einen manuell 
abgesetzten Load-Command gestartet werden.
Oder man legt sich alternativ unter "Build Targets" weitere Targets an - 
wie z.B. "Debug" und "Flash+Debug", die dann entsprechend den load 
ausführen oder nicht.
Auch interessant wäre hier ein Target "Debug in RAM", bei dem der 
komplette Code in den Ram geladen wird. Allerdings habe ich mich damit 
noch nicht genug beschäftigt und mir fehlen hier noch ein paar Infos, 
was man dazu noch alles braucht.
Vermutlich müsste dazu das Linker-File geändert werden und in den Flash 
an den Reset- und Interrupt-Vektoren ein Sprung zu den entsprechenden 
Stellen im RAM gesetzt werden.
Wenn jemand Infos dazu hat - gerne her damit ;)

Tec Nologic schrieb:
> Moin,
>
> Hab die emIDE gerade mal ausprobiert.
> Wenn ich ein neues Projekt erstellen will zeigt er mir keinen Wizard an
> ich komme da also nicht weiter. Viel weiter habe ich dann garnicht
> getestet, weil mein Eclipse läuft. Aber interessant finde ichs schon.
>
> Wie ist das mit Cpp bei Code::Blocks?
>
> MfG
>
> Tec

Das mit dem Wizard ist mir auch direkt nach dem Starten aufgefallen. Ein 
neues Projekt anzulegen scheint unmöglich zu sein.
Cpp ist bei CodeBlocks kein Problem.

von EMIDE (Gast)


Lesenswert?

Hallo!

Ich bin nicht der Entwickler der IDE. :-)

Bin nur durch Zufall drüber gestolpert:
http://www.segger.com/jlink-ide-integration.html

Da ich beruflich mit IAR und dem J-Link arbeite, bin ich ein großer Fan 
von diesem Duo. Die Qualität der Software rund um den J-Link finde ich 
prima hinsichtlich Stabilität.

Daher würde ich den gerne auch privat einsetzen (J-Link EDU für ca. 
50EUR).
Nur leider ist mir die EWB von IAR zu teuer, um sie privat kaufen. Die 
Kickstart-Version reicht leider nicht mehr aus.

Daher suche ich jetzt nach einer freien Alternative, die den J-Link 
benutzen kann. Generell bin ich auch nicht so der Eclipse-Fan.
Da kam emIDE gerade gelegen.

Leider habe ich auch noch nicht herausgefunden, wie man ein Projekt 
anlegt.

von André W. (andre-w)


Lesenswert?

Dann probiere doch erst einaml CodeBlocks ohne die Modifikationen von 
emIDE - da es ja soweit ich gesehen habe einen GDB-Server für den J-Link 
gibt sollte es kein großartiges Problem sein das Beispiel-Projekt auf 
den J-Link GDB-Server einzustellen.
Im Prinzip müsste man nur unter Project/Debugger den Port anpassen und 
ggf. noch bei den additional commands kleine Anpassungen machen - der 
Rest sollte gleich bleiben können. Und man müsste halt im gegensatz zu 
emIDE den GDB-Server von Hand starten..
Für andere Prozessoren braucht man ggf. noch entsprechende Linker und 
Starter-Files - die sollten sich aber auch finden lassen.

Ich bin gerade dabei mir ein neues Projekt Template zu bauen, mit den 
Erkenntnissen der letzten Tage.. mal sehen was dabei raus kommt.

von André W. (andre-w)


Angehängte Dateien:

Lesenswert?

Im Anhang gibt es jetzt das Ergebnis des neuen Templates! (Anweisungen 
zur Verwendung in der README.txt)

jetzt sind unter Custom Variables die wichtigsten Einstellungen für den 
Prozessor zusammengefasst und es gibt 3 Targts:
Flash+Debug:
Dieses Target startet den Debugger und beschreibt sofort den Flash mit 
dem aktuell compilierten File.

Debug:
Wenn man den Debugger mit diesem Target startet wird nur der GDB 
gestartet - der Flash aber nicht beschrieben.

Release:
erzeugt ein ${PROJECT_NAME}.bin-File, dass mit dem ST-Link Utility auf 
den Prozessor geladen werden kann.

von EMIDE (Gast)


Lesenswert?

Hi!

Ich habe das mit CB und einem J-Link EDU jetzt soweit laufen.

Kannst Du mir erklären, was das Ändern des Linker-Skripts bewirkt?
Stichwort: " _exit = .;"

Ich kann meinen Startup-Code nämlich ohne Probleme debuggen.
Allerdings lande ich immer im Hard Fault Handler sobald ich auf "BL 
__libc_init_array" komme.

Ich muss dazu sagen, dass ich einen STM32L152VB benutze. Ich hatte mir 
ein Projekt von Atollic Truestudio Lite generieren lassen und das 
Linker-Skript benutzt.

von EMIDE (Gast)


Lesenswert?

Ok. Das Problem mit __libc_init_array() hat sich erledigt.
Es ist bei Dir ja auch aus kommentiert.

Da kein C++ mit statischen Konstruktoren vorhanden ist, wird das wohl 
nicht benötigt. Siehe dazu Punkt 22:
http://eetimes.com/design/embedded/4026075/Building-Bare-Metal-ARM-Systems-with-GNU-Part-2

Könntest Du das mit dem Linker-Skript trotzdem noch erläutern? Danke!

von Tobi (Gast)


Lesenswert?

erhardd schrieb:
> ...die Idee ist gut!
> Ich probiers aus, wenn ich die Zeit finde.
> (Ätze grad ein neues Aufsteckboard WLAN/LAN für STM32F417)
> Danke...

Was für ein WLAN-Modul verwendest du denn?

von erhardd (Gast)


Lesenswert?

Beitrag "stm32f4 Bord im LAN"
@Tobi (Gast)
...dieses wird nur mit einem DP83848 PHY gekoppelt...

von André W. (andre-w)


Lesenswert?

EMIDE schrieb:
> Hi!
>
> Ich habe das mit CB und einem J-Link EDU jetzt soweit laufen.
>
> Kannst Du mir erklären, was das Ändern des Linker-Skripts bewirkt?
> Stichwort: " _exit = .;"
>
> Ich kann meinen Startup-Code nämlich ohne Probleme debuggen.
> Allerdings lande ich immer im Hard Fault Handler sobald ich auf "BL
> __libc_init_array" komme.
>
> Ich muss dazu sagen, dass ich einen STM32L152VB benutze. Ich hatte mir
> ein Projekt von Atollic Truestudio Lite generieren lassen und das
> Linker-Skript benutzt.

Hi,

mit dem Linker-Script bin ich auch noch nicht so richtig Fit - aber hier 
mal ein Versuch zur Erklärung (ohne Garantie auf Richtigkeit!):

wenn der Eintrag im Linkserscript fehlt bekomme ich beim linken folgende 
Fehlermeldung:
1
arm-none-eabi-g++.exe
2
    -o bin\Debug\TRIP_STM32_Graph.elf
3
    obj\Debug\STM32F4xx_DSP_StdPeriph_Lib_V1.0.1\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c.o
4
    obj\Debug\STM32F4xx_DSP_StdPeriph_Lib_V1.0.1\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c.o
5
    obj\Debug\STM32F4xx_DSP_StdPeriph_Lib_V1.0.1\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c.o
6
    obj\Debug\TRIP_STM32_Graph\main.c.o
7
    obj\Debug\STM32F4xx_DSP_StdPeriph_Lib_V1.0.1\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\TrueSTUDIO\startup_stm32f4xx.s.o
8
    -mthumb
9
    -Wall
10
    -mlittle-endian
11
    -T"C:\Software\TRIP_STM32_Graph\..\STM32F4xx_DSP_StdPeriph_Lib_V1.0.1\Project\STM32F4xx_StdPeriph_Templates\TrueSTUDIO\STM324xG_EVAL\stm32_flash.ld"
12
    -mcpu=cortex-m4
13
    -mfloat-abi=hard
14
    -mfpu=fpv4-sp-d16
15
    -g
16
17
c:/program files (x86)/gnu tools arm embedded/4.6 2012q2/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-exit.o): In function `exit':
18
exit.c:(.text.exit+0x16): undefined reference to `_exit'

Was vermutlich daran liegt, dass der Linker nicht weis an welche Stelle 
er diese Section schreiben soll.
Die Zeile im Linker-Script teilt ihm das dann mit, das die Funktion an 
das Ende des Flash kommt. (Die Problemlösung hatte ich durch googlen 
gefunden - aber den Link nicht mehr parat..)

Wozu er überhaupt die exit funktion mit linken will ist mir allerdings 
ein Rätsel, da auf einem µC die Main in eine Endlos-Schleife läuft und 
nie ein Exit benötigt wird.

Vermutlich wurde deswegen die Exit-Funktion in der Atollic-Toolchain 
(von der ja eigentlich das Linkerscript stammt) weg optimiert und auch 
kein Eintrag im Linkerscript dazu erstellt,
während sie in den GNU Tools for ARM Embedded Processors noch mit 
vorhanden ist..

Gruß,
André

von EMIDE (Gast)


Lesenswert?

@andre-w

Strange. Ich habe das Linker-Skript so gelassen, wie es dem Atollic 
herauskommt. Bei mir läuft der Compiler durch.

Wie genau läuft das hier jetzt eigentlich mit der libc?
Ich möchte natürlich auch ein paar Ausgaben mit printf() erzeugen.

Beim Atollic kann man dazu ja die Funktion _write() schreiben, die dann 
angeblich vom eingebauten printf() benutzt werden kann.

Zum Beispiel so:
1
int _write(int file, char *ptr, int len)
2
{
3
  /* Implement your write code here, this is used by puts and printf for example */
4
  int i=0;
5
  for(i=0 ; i<len ; i++)
6
    ITM_SendChar((*ptr++));
7
  return len;
8
}

Gibt es so einen Mechanismus auch bei den ARM GNU Tools?
Wenn ich stdio.h einbinde und printf() aufrufe, dann gibt es sofort 
einen Hard Fault.

von EMIDE (Gast)


Lesenswert?

Also irgendetwas scheint da noch faul zu sein.
Die Kombination aus Startup-Code und Linker-Skript scheint nicht so ganz 
zu passen. Zumindestens nicht, wenn man die libc (newlibc) der GNU ARM 
Toolchain benutzen möchte, die ja dabei ist.

Muss die libc nicht erst im Startup-Code initialisiert werden? Einsprung 
_start zum Beispiel?
In der README.TXT der Toolchain steht sowas zumindestens im 
Startup-Code.
Wenn ich das aber einbaue, dann lande ich wieder im Hard Fault Handler.

Ist die Atollic Toolchain denn SO anders? Die benutzen doch auch die 
newlibc.

von EMIDE (Gast)


Lesenswert?

Skript passend zum STM32L152VB:
1
/* Entry Point */
2
ENTRY(Reset_Handler)
3
4
/* Highest address of the user mode stack */
5
_estack = 0x20004000;    /* end of 16K RAM */
6
7
/* Generate a link error if heap and stack don't fit into RAM */
8
_Min_Heap_Size = 0;      /* required amount of heap  */
9
_Min_Stack_Size = 0x80; /* required amount of stack */
10
11
/* Specify the memory areas */
12
MEMORY
13
{
14
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 128K
15
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 16K
16
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
17
}
18
19
/* Define output sections */
20
SECTIONS
21
{
22
  /* The startup code goes first into FLASH */
23
  .isr_vector :
24
  {
25
    . = ALIGN(4);
26
    KEEP(*(.isr_vector)) /* Startup code */
27
    . = ALIGN(4);
28
  } >FLASH
29
30
  /* The program code and other data goes into FLASH */
31
  .text :
32
  {
33
    . = ALIGN(4);
34
    *(.text)           /* .text sections (code) */
35
    *(.text*)          /* .text* sections (code) */
36
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
37
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
38
    *(.glue_7)         /* glue arm to thumb code */
39
    *(.glue_7t)        /* glue thumb to arm code */
40
    *(.eh_frame)
41
42
    KEEP (*(.init))
43
    KEEP (*(.fini))
44
45
    . = ALIGN(4);
46
    _etext = .;        /* define a global symbols at end of code */
47
  } >FLASH
48
49
50
   .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
51
    .ARM : {
52
    __exidx_start = .;
53
      *(.ARM.exidx*)
54
      __exidx_end = .;
55
    } >FLASH
56
57
  .preinit_array     :
58
  {
59
    PROVIDE_HIDDEN (__preinit_array_start = .);
60
    KEEP (*(.preinit_array*))
61
    PROVIDE_HIDDEN (__preinit_array_end = .);
62
  } >FLASH
63
  .init_array :
64
  {
65
    PROVIDE_HIDDEN (__init_array_start = .);
66
    KEEP (*(SORT(.init_array.*)))
67
    KEEP (*(.init_array*))
68
    PROVIDE_HIDDEN (__init_array_end = .);
69
  } >FLASH
70
  .fini_array :
71
  {
72
    PROVIDE_HIDDEN (__fini_array_start = .);
73
    KEEP (*(SORT(.fini_array.*)))
74
    KEEP (*(.fini_array*))
75
    PROVIDE_HIDDEN (__fini_array_end = .);
76
  } >FLASH
77
78
  /* used by the startup to initialize data */
79
  _sidata = LOADADDR(.data);
80
81
  /* Initialized data sections goes into RAM, load LMA copy after code */
82
  .data :
83
  {
84
    . = ALIGN(4);
85
    _sdata = .;        /* create a global symbol at data start */
86
    *(.data)           /* .data sections */
87
    *(.data*)          /* .data* sections */
88
89
    . = ALIGN(4);
90
    _edata = .;        /* define a global symbol at data end */
91
  } >RAM AT> FLASH
92
93
  /* Uninitialized data section */
94
  . = ALIGN(4);
95
  .bss :
96
  {
97
    /* This is used by the startup in order to initialize the .bss secion */
98
    _sbss = .;         /* define a global symbol at bss start */
99
    __bss_start__ = _sbss;
100
    *(.bss)
101
    *(.bss*)
102
    *(COMMON)
103
104
    . = ALIGN(4);
105
    _ebss = .;         /* define a global symbol at bss end */
106
    __bss_end__ = _ebss;
107
  } >RAM
108
109
  /* User_heap_stack section, used to check that there is enough RAM left */
110
  ._user_heap_stack :
111
  {
112
    . = ALIGN(4);
113
    PROVIDE ( end = . );
114
    PROVIDE ( _end = . );
115
    . = . + _Min_Heap_Size;
116
    . = . + _Min_Stack_Size;
117
    . = ALIGN(4);
118
  } >RAM
119
120
  /* MEMORY_bank1 section, code must be located here explicitly            */
121
  /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
122
  .memory_b1_text :
123
  {
124
    *(.mb1text)        /* .mb1text sections (code) */
125
    *(.mb1text*)       /* .mb1text* sections (code)  */
126
    *(.mb1rodata)      /* read-only data (constants) */
127
    *(.mb1rodata*)
128
  } >MEMORY_B1
129
130
  /* Remove information from the standard libraries */
131
  /DISCARD/ :
132
  {
133
    libc.a ( * )
134
    libm.a ( * )
135
    libgcc.a ( * )
136
  }
137
138
  .ARM.attributes 0 : { *(.ARM.attributes) }
139
}

von EMIDE (Gast)


Lesenswert?

Ich denke, dass mein Problem evtl. hier zu suchen ist:
Beitrag "STM32F4 C++ springt bei __libc_init_array in den HardFault"

von EMIDE (Gast)


Lesenswert?

Wieder etwas gelernt.

Die newlibc benutzt verschiedene Implementierungen, die für die 
jeweilige Architektur optimiert sind. Stichwort: multilibs

Welche lib nun ausgewäht wird, kann man so überprüfen:
arm-none-eabi-gcc.exe -print-multi-directory -mcpu=cortex-m3 -mthumb
armv7-m

Hier wird also "armv7-m" ausgespuckt. Dort befindet sich nun auch die 
richtige libc, die nur aus dem Thumb-Befehlssatz besteht. Der Cortex-M3 
unterstützt ja nur diesen.

Man muss also in CB noch unter den Linker Settings folgende Schalter 
einfügen: -mcpu=cortex-m3 -mthumb
Dann benutzt der Linker auch die richtige libc und es gibt keinen Hard 
Fault mehr, weil die CPU in den ARM Modus springen sollte.

von EMIDE (Gast)


Lesenswert?

Gibt es für CB evtl. ein Plugin mit dem eine bessere Disassembly-Ansicht 
bekommt? Das was da aktuell geboten wird, ist ja recht spatanisch.
Derzeit bekommt man nur ein wenig Assembler der aktuellen C-Source Zeile 
angezeigt. Scrollen ist nicht möglich.

von Johann H. (joe-c)


Lesenswert?

Hallo,

ich versuche schon seit einiger Zeit C::B als IDE für den STM32F4 
einzustellen, aber es klappt irgendwie nicht richtig.

Aktuell habe ich eine Portable Variante von CodeBblocks 12.11 und den 
GNU (Link aus dem ersten Beitrag) in Verwendung.
Der oben mitgelieferte Projektodner (STM32F4-Template2.zip) ist eine 
abgewandelte Variante von André W. (Beitrag #2768278)

Bulid/Rebuild laufen in Debug und Release ohne Warnungen und Fehler 
durch. Die *.bin wird auch erstellt und lässt sich mit dem ST-Link 
Untility öffnen.
Das Problem ist allerdings, die Sartadresse ist immer 0x00000000, 
weshalb ich auch folgende Fehlermeldung bekomme:
1
STM32 ST-LINK CLI v1.4.0
2
STM32 ST-LINK Command Line Interface
3
Connected via SWD.
4
Device ID:0x411
5
Device flash Size : 1024 Kbytes
6
Device family :STM32F4xx
7
Flash Programming:
8
File : output\Release\exe\Blinky_STM3240G.bin
9
Address : 0x00000000
10
[0x00000000]:Invalid address!
11
MCU Reset.
12
Application started.

Zusätzlich hab ich die http://www.emide.org/ ausprobiert. Dort hab ich 
ein Testprojekt erstellt und bei postbuild folgende Erweiterung 
eingegeben:
1
arm-none-eabi-objcopy -O binary ${PROJEKT_DIR}output\Release\exe\${PROJECT_NAME}.elf ${PROJEKT_DIR}output\Release\exe\${PROJECT_NAME}.bin
2
arm-none-eabi-size --format=berkeley ${PROJEKT_DIR}output\Release\exe\${PROJECT_NAME}.elf
3
C:\Users\Talentfrei\Desktop\CodeBlocks-12P_big\tool\ST-LINK_gdbserver\ST-LINK_CLI.exe -c SWD -P "${PROJEKT_DIR}output\Release\exe\${PROJECT_NAME}.bin" -Rst -Run

Interessanterweise ist die Wirkung fast dieselbe. Build ohne Fehler und 
Warnungen und am Ende ist eine BIN Datei da. Aber auch hier ist die 
Startadresse wieder 0x00000000.

Ich weiss nicht was ich falsch mache. Hab einen Fehler im Linkerscript 
vermutet und versucht hier eine Lösung zu finden 
http://www.bravegnu.org/gnu-eprog/c-startup.html
wurde aber nicht fündig.

Kann mir jemand sagen, was ich falsch mache und wie es richtig wäre?

MFG

von Johann H. (joe-c)


Angehängte Dateien:

Lesenswert?

...irgendwie sind die Anhänge abhanden gekommen... neuer Versuch.

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.