ARM GCC: Unterschied zwischen den Versionen
(→GCC Binärdistributionen: veraltete Links entfernt) |
|||
Zeile 4: | Zeile 4: | ||
* [https://launchpad.net/gcc-arm-embedded GCC-ARM-Embedded] für Cortex-R4/R5/M0/M3/M4(F)/M0+. Windows, Linux, Mac, bereitgestellt von ARM selbst, vollständiger Support für FPU's, C++11, kein Code-Size-Limit | * [https://launchpad.net/gcc-arm-embedded GCC-ARM-Embedded] für Cortex-R4/R5/M0/M3/M4(F)/M0+. Windows, Linux, Mac, bereitgestellt von ARM selbst, vollständiger Support für FPU's, C++11, kein Code-Size-Limit | ||
* [http://sourceforge.net/projects/devkitpro/ devkitPro] | * [http://sourceforge.net/projects/devkitpro/ devkitPro] | ||
* [http://www.lpcware.com/lpcxpresso/home LPCXpresso] (vormals CodeRed IDE) ist eine IDE von NXP für die LPC-Mikrocontroller die den GCC enthält | * [http://www.lpcware.com/lpcxpresso/home LPCXpresso] (vormals CodeRed IDE) ist eine IDE von NXP für die LPC-Mikrocontroller die den GCC enthält | ||
* [http://www.yagarto.de/ Yagarto] (Windows, mit Eclipse-Integration) - veraltet | |||
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/#winarm WinARM] - veraltet | * [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/#winarm WinARM] - veraltet | ||
* GNUARM - veraltet | * GNUARM - veraltet |
Version vom 19. Februar 2014, 13:00 Uhr
Der GCC kann auch für ARM konfiguriert werden. Es gibt diverse fertige Binärdistributionen die für verschiedene Controller mit ARM-Kern verwendet werden können.
GCC Binärdistributionen
- Mentor Graphics Sourcery Tools (vormals CodeSourcery CodeBench Lite) Windows, Linux
- GCC-ARM-Embedded für Cortex-R4/R5/M0/M3/M4(F)/M0+. Windows, Linux, Mac, bereitgestellt von ARM selbst, vollständiger Support für FPU's, C++11, kein Code-Size-Limit
- devkitPro
- LPCXpresso (vormals CodeRed IDE) ist eine IDE von NXP für die LPC-Mikrocontroller die den GCC enthält
- Yagarto (Windows, mit Eclipse-Integration) - veraltet
- WinARM - veraltet
- GNUARM - veraltet
Bei der Auswahl der Toolchain sollte beachtet werden, dass es größere Unterschiede bei den bereitgestellten C-Bibliotheken gibt. Die Sourcery Codebench Lite-Edition stellt z.B. keine Bibliotheken mit FPU-Unterstützung bereit, so dass trotz vorhandener FPU beim Cortex-M4 nur suboptimaler Code erzegt werden kann. Siehe [1] für ein kleines Beispiel und eine Erklärung.
Die im Netz häufig anzutreffende summon-arm Toolchain hat einen der seltenen Compiler-Bugs [2] und sollte daher nicht verwendet werden, wenn man floatingpoint-Typen einsetzen möchte. Egal ob mit oder ohne FPU.
Beim Einsatz des gcc in Verbindung mit in C geschriebenem startup-Code bei den Optimierungslevels "-O2" und "-O3" muss zusätzlich "-fno-gcse" gesetzt werden, da ansonsten die von der CPU benötigte NVIC-Tabelle(n) und zugehörige Funktionen u.U. nicht so aussehen wie sie sollten.
Siehe auch ARM-GCC development resources im Forum.
Nutzung mit eigener Umgebung/Kommandozeile
Hier einige Hinweise wie man den GCC direkt verwenden kann (zB. mit selbstgebautem makefile), falls man das nicht von einer Entwicklungsumgebung machen lässt.
Compiler & Linker Flags
Für Eilige, zum Copy&Pasten. Detailinformationen gibt es in der GCC Dokumentation, auch speziell für ARM.
- Mit Optimierungen:
Tool/Sprache | Cortex-M3 | Cortex-M4F |
---|---|---|
C-Compiler (gcc) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -Os -flto |
C++ Compiler (g++) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto -fno-rtti -fno-exceptions | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -Os -flto -fno-rtti -fno-exceptions |
Assembler (as) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb |
Linken von C Code (mit gcc-Befehl) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto -Wl,--gc-sections -static | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -Os -flto -Wl,--gc-sections -static |
Linken von C++ (und C) Code (mit g++-Befehl) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto -fno-rtti -fno-exceptions -Wl,--gc-sections -static | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -Os -flto -fno-rtti -fno-exceptions -Wl,--gc-sections -static |
- Ohne Optimierungen, mit Debug-Informationen:
Tool/Sprache | Cortex-M3 | Cortex-M4F |
---|---|---|
C-Compiler (gcc) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -g | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -g |
C++ Compiler (g++) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -g -fno-rtti -fno-exceptions | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -g -fno-rtti -fno-exceptions |
Assembler (as) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb |
Linken von C Code (mit gcc-Befehl) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -g -Wl,--gc-sections -static | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -g -Wl,--gc-sections -static |
Linken von C++ (und C) Code (mit g++-Befehl) | -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -g -fno-rtti -fno-exceptions -Wl,--gc-sections -static | -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -g -fno-rtti -fno-exceptions -Wl,--gc-sections -static |
- Siehe auch das Readme vom GCC-ARM-Embedded
- Um das -flto -Flag verwenden zu können, muss der GCC LTO unterstützen. Beim GCC-ARM-Embedded ist dies ab Version 4.7-2013-q2-update der Fall.
- Die LTO erkennt die ISR's und den Interrupt Vector möglicherweise als "unbenutzt" und optimiert sie daher weg. Dies kann durch Markierung der Funktionen & Variablen mit "__attribute__ ((used))" verhindert werden.
- Alle Compileroptionen müssen auch beim Linken mit angegeben werden (ist in obiger Tabelle berücksichtigt), da auch dann u.U. Code generiert werden kann.
Startupcode & Linkerscript
- Damit der compilierte Code an den richtigen Stellen im Controller landet (d.h. dem Flash) muss man dem Linker ein Linkerscript mitgeben. Dies geht per "-T pfad_zum_linkerscript.ld" an den Linker-Befehl. Das Script ist praktisch Controller-spezifisch, es gibt Beispiel-Scripte der Controller-Hersteller.
- Damit beim Starten die richtigen Initialisierungen vorgenommen werden (wie globale Variablen und bei C++ Konstruktoren globaler Objekt-Instanzen) muss als erstes ein Startupcode laufen, der dann die main()-Funktion aufruft. Der Startupcode ist meistens in Assembler geschrieben, C/C++-Code ist aber auch möglich. Assemblercode kann per arm-none-eabi-as (Flags s.o.) assemblisiert werden, die resultierende .o -Datei normal mitgelinkt. Auch für den Startupcode gibt es Beispiele der Controller-Hersteller.
Zusammen bieten die beiden Dateien der Anwendung ein Standard-C-Interface, d.h. man kann wie gewohnt globale Variablen verwenden und seinen Code in die main()-Funktion schreiben.
FPU der Cortex-M4F nutzen
Um die FPU zu nutzen, muss dem Compiler per Flag dazu gebracht werden, FPU-Instruktionen zu generieren.
Außerdem muss vor Benutzung der FPU-Befehle die FPU aktiviert werden, dies geschieht typischerweise im Startupcode, bevor die main() -Funktion aufgerufen wird. Hier die entsprechenden Befehle, falls sie im verwendeten Startupcode nicht onehin schon enthalten sind:
/*FPU settings*/ ldr r0, =0xE000ED88 /* Enable CP10,CP11 */ ldr r1,[r0] orr r1,r1,#(0xF << 20) str r1,[r0]
In C/C++ unter Verwendung der CMSIS geht es so:
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
Weiterhin sollte die GCC-Distribution auch Laufzeitbibliotheken mit FPU-Unterstützung mitbringen (CodeBench lite und Yagarto werden ohne ausgeleifert, GCC-ARM-Embedded mit).
Am Beispiel der STM32F4 mehr dazu in diesem Thread: Floating Pointing Unit STM32F4
Disassemblieren mit GCC
arm-none-eabi-objdump -d -t -C pfad_zum_binary.elf
Konvertieren zwischen Binary-Formaten beim GCC
arm-none-eabi-objcopy -O ausgabeformat eingabe_binary.elf ausgabe_binary
Nützlich als Ausgabeformat sind z.B. "ihex" oder "binary".
Code-Größe optimieren
Obige Flags (insbesondere -flto -Os -ffunction-sections -fdata-sections -Wl,--gc-sections ) verwenden. Hier finden sich noch ein par Tips, für den 1. kann aber mittlerweile der GCC-ARM-Embedded direkt verwendet werden, da er jetzt LTO unterstützt (s.o.).