Stellaris Launchpad-Toolchain unter Linux: Unterschied zwischen den Versionen

Aus Hobbyelektronik.org
(Formulierung)
 
(2 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 54: Zeile 54:
 
=Erklärung des Makefiles=
 
=Erklärung des Makefiles=
 
Im folgenden wird genauer auf die einzelnen Teile des Makefiles eingegangen.
 
Im folgenden wird genauer auf die einzelnen Teile des Makefiles eingegangen.
 
  
 
==Verwendete Variablen==
 
==Verwendete Variablen==
Zeile 70: Zeile 69:
  
 
==Texinfo==
 
==Texinfo==
Texinfo beinhaltet das Programm "makeinfo", welches beim Bauvorgang der Newlib benötigt wird.
+
Texinfo beinhaltet das Programm "makeinfo", welches beim Bauen der Newlib benötigt wird.
 
Nur aus diesem Grund wird dieses relativ kleine Software-Paket mit gebaut.
 
Nur aus diesem Grund wird dieses relativ kleine Software-Paket mit gebaut.
  
Zeile 84: Zeile 83:
  
 
==Binutils==
 
==Binutils==
Die Binutils beinhalten eine Vielzahl an Werkzeugen, unter anderem zum übersetzen von Code.
+
Die Binutils beinhalten eine Vielzahl an Werkzeugen, unter anderem zum Übersetzen von Code.
Mehr Informationen dazu gibt es auf der GNU-Website.
+
Mehr Informationen dazu gibt es auf der [http://www.gnu.org/software/binutils/ GNU-Website].
  
 
<pre>
 
<pre>
Zeile 105: Zeile 104:
 
Nun wird der eigentliche Gcc Compiler gebaut.
 
Nun wird der eigentliche Gcc Compiler gebaut.
 
Dieser benötigt zum vollständigen Bauen eine Library mit grundlegenden Funktionen und den entsprechenden Header Dateien.  
 
Dieser benötigt zum vollständigen Bauen eine Library mit grundlegenden Funktionen und den entsprechenden Header Dateien.  
Nachdem die glibc Library zu groß für Mikrocontroller ist, bietet sich Newlib an.
+
Nachdem die glibc-Library zu groß für Mikrocontroller ist, bietet sich z. B. Newlib an.
Zum Bauen der Newlib muss allerdings ein Teil des Gcc bereits vorhanden sein, weshalb der Gcc in zwei Schritten gebaut wird.
+
Zum Bauen der Newlib muss allerdings ein Teil des GCC bereits vorhanden sein, weshalb dieser in zwei Schritten gebaut werden muss.
  
Hier die richtige Reihenfolge:
+
Die richtige Reihenfolge hierfür sit:
 
# GCC-Configure
 
# GCC-Configure
 
# GCC-make all-gcc
 
# GCC-make all-gcc
Zeile 118: Zeile 117:
 
# GCC-make install
 
# GCC-make install
  
Erst nach dem erfolgreichen "make install" vom Gcc ist dieser komplett gebaut.
+
Erst nach dem erfolgreichen letzten Schritt ("make install") ist GCC komplett gebaut.
  
 
Aber nun zu der Erklärung.
 
Aber nun zu der Erklärung.
Zu Beginn wird im Gcc-Verzeichnis ein neuer Ordner angelegt, weil man den Gcc nicht direkt in dem Verzeichnis der Sourcen bauen kann.
+
Zu Beginn wird im GCC-Verzeichnis ein neuer Ordner angelegt, weil man den GCC nicht direkt in dem Verzeichnis der Sourcen bauen kann.
 
Bei der Konfiguration werden eine Vielzahl an Features ausgeschaltet, welche auf dem Mikrocontroller nicht benötigt werden.
 
Bei der Konfiguration werden eine Vielzahl an Features ausgeschaltet, welche auf dem Mikrocontroller nicht benötigt werden.
Wichtig ist das setzen des "--enable-languages" Flag für die gewünschte Sprache.
+
Wichtig ist das Setzen des "--enable-languages" Flags für die gewünschte Sprache - in diesem Fall C.
Dazu kommt natürlich das entsprechende Flag für die Newlib("--with-newlib").  
+
Dazu kommt natürlich das entsprechende Flag für die Newlib ("--with-newlib").  
Um diese zu verwenden, muss der Headerpfad zu der Newlib entsprechend angegeben werden("--with-headers").
+
Um diese zu verwenden, muss zusätzlich der Headerpfad zu der Newlib angegeben werden ("--with-headers").
Zudem ist auch die Angabe des CPU-Typs(cortex-m4) wichtig.
+
Zudem ist auch die Angabe des CPU-Typs (cortex-m4) wichtig.
  
 
<pre>
 
<pre>
Zeile 162: Zeile 161:
  
 
==Newlib==
 
==Newlib==
Vor dem Bauen der Newlib muss die verwendete Version 2.1.0 noch gepatcht werden, weil es sonst zu Komplikationen beim bauen kommt.
+
Vor dem Bauen der Newlib muss die verwendete Version 2.1.0 noch gepatcht werden, weil sonst folgender Fehler auftritt:  
Der Patch ist in das Makefile integriert und wird sofort nach Herunterladen der Sourcen eingespielt.
 
Hier der Patch:
 
 
<pre>
 
<pre>
 +
make[7]: Entering directory '/home/user/stellarislaunchpad/source/newlib-2.1.0/arm-none-eabi/thumb/libgloss/arm/cpu-init'
 +
make[7]: *** No rule to make target '../../../.././libgloss/arm/../config/default.mh', needed by 'Makefile'.  Stop.
 +
</pre>
 +
 +
Der Patch ist in das Makefile integriert und wird sofort nach dem Herunterladen der Sourcen eingespielt:
 +
<source lang="diff">
 
--- libgloss/arm/cpu-init/Makefile.in 2013-10-14 17:15:12.000000000 +0200
 
--- libgloss/arm/cpu-init/Makefile.in 2013-10-14 17:15:12.000000000 +0200
 
+++ libgloss/arm/cpu-init/Makefile.in 2014-10-17 21:38:32.623317260 +0200
 
+++ libgloss/arm/cpu-init/Makefile.in 2014-10-17 21:38:32.623317260 +0200
Zeile 185: Zeile 188:
 
   
 
   
 
  ../config.status: ../configure
 
  ../config.status: ../configure
</pre>
+
</source>
  
Zum Konfigurieren der Newlib gibt es nichts besonders zu erwähnen.  
+
Zum Konfigurieren der Newlib gibt es nichts besonders zu erwähnen. Es wird wie beim GCC natürlich auch unser Target angegeben. Wichtig ist beim Installieren, dass hier nicht unsere "$(MAKE)"-Variable verwendet wird, da es sonst beim Verwenden mehrerer Jobs zu Problemen kommen kann´.
Es wird wie beim Gcc natürlich auch unser Target angegeben.
 
Wichtig ist beim installieren, dass hier nicht unsere "$(MAKE)" Variable verwendet wird.
 
Da es sonst beim Verwenden mehrerer Jobs zu Problemen führen kann.
 
  
 
<pre>
 
<pre>
Zeile 205: Zeile 205:
 
</pre>
 
</pre>
  
==Gcc-final==
+
==GCC-final==
Endlich ist es so weit.
+
Endlich ist es so weit! Wir können unseren Compiler fertig bauen und installieren. Der Compiler befindet sich anschließend unter output/bin/arm-none-eabi-gcc und kann nun verwendet werden.
Wir können unseren Compiler fertig bauen und installieren.
 
Der Compiler befindet sich anschließend unter output/bin/arm-none-eabi-gcc und kann nun verwendet werden.
 
 
<pre>
 
<pre>
 
gcc-final:
 
gcc-final:
Zeile 216: Zeile 214:
  
 
==Lm4flash==
 
==Lm4flash==
Zum Aufspielen der Software auf das Launchpad benötigt man die Lm4flash-tools.
+
Zum Aufspielen der Software auf das Launchpad benötigt man die Lm4flash-tools. Diese brauchen zwingend das Paket libusb und das dazugehörige Developer-Package. Unter Arch und Ubuntu können diese leicht über die Paketmanager installiert werden.
Diese brauchen zwingend das Paket libusb und das dazugehörige Developer Package.
 
Unter Arch und Ubuntu können diese leicht über die Paketmanager installiert werden.
 
 
<pre>
 
<pre>
 
lm4tools:
 
lm4tools:
Zeile 226: Zeile 222:
 
</pre>
 
</pre>
  
Getestet werden kann Lm4flash einfach mit dem flash-blinky Beispiel des Makefiles.
+
Getestet werden kann Lm4flash einfach mit dem flash-blinky Beispiel des Makefiles - dazu wird das blinky-Projekt der Stellarisware crosscompiliert und per lm4flash auf das Launchpad via USB gespielt. Möglicherweise werden zum Übertragen der Daten, wie bereits erwähnt, Rootrechte benötigt.
Dazu wird das blinky-Projekt der Stellarisware crosscompiliert und per lm4flash auf das Launchpad via USB gespielt.
 
Möglicherweise wird zum Übertragen der Daten Rootrechte benötigt.
 
 
<pre>
 
<pre>
 
blinky:
 
blinky:
Zeile 238: Zeile 232:
  
 
==GDB==
 
==GDB==
Zum Debuggen wird nun noch der entsprechende Gdb benötigt.  
+
Zum Debuggen wird nun noch der entsprechende GDB benötigt. Auch dieser kann ohne große Mühe gebaut werden. Hier wird nicht weiter auf den Gdb eingegangen, da es dazu genügend ausführliche Anleitungen im Internet gibt.
Auch dieser kann ohne große Mühe gebaut werden.
 
Hier wird nicht weiter auf den Gdb eingegangen, da es genügend ausführliche Anleitungen im Internet gibt.
 
 
<pre>
 
<pre>
 
gdb:
 
gdb:
Zeile 253: Zeile 245:
  
 
==OpenOCD==
 
==OpenOCD==
Und für alle Freunde von OpenOCD wird der nötige Bauvorgang kurz gezeigt.
+
Und für alle Freunde von OpenOCD kann auch diese Software für die Plattform kompiliert werden. Wichtig dabei ist das "--enable-ti-icdi"-Flag zu setzen:
Wichtig dabei ist das "--enable-ti-icdi" Flag.
 
 
<pre>
 
<pre>
 
openocd:
 
openocd:

Aktuelle Version vom 19. November 2014, 22:51 Uhr

Im folgenden wird beschrieben, wie man sich die Toolchain, Debugger und Flashtools zum Programmieren via USB für das Stellaris Launchpad von Grund auf selber baut. Die Idee dazu kam mir, als ich Probleme mit einem der 32bit Compiler von TI unter einem 64bit Betriebssystem hatten. Außerdem ist es natürlich deutlich "cooler", seine eigenen Compiler zu verwenden! So kann man bei Problemen auch einfach mal im Source Code stöbern.

An dieser Stelle sei gesagt, das dieser Vorgang sehr rechen- und zeitintensiv ist und ihr während des Bauvorgangs deutlich über 10 Tassen Kaffee trinken könnt. Um Missverständnisse auszuräumen sei kurz erwähnt, dass dieses Tutorial für Linuxanwender gedacht ist und eine Portierung auf Windows schwer sein dürfe.

Die komplette Software für die Toolchain kann mittels eines Makefiles (Datei:StellarisToolchainMakefile.h) heruntergeladen und gebaut werden. Am Anfang des Artikels wird die Verwendung dieses Makefiles erklärt. Danach wird auf die einzelnen Komponenten kurz eingegangen.

Warnung: Die hier verwendeten Softwarepakete unterliegen verschiedensten Lizenzen, welche eingehalten müssen werden!

Bauen der Toolchain

Zu Beginn sollte man sich das Makefile herunterladen und in einem beliebigen Ordner speichern:

$ mkdir ~/stellarislaunchpad/
$ wget http://hobbyelektronik.org/w/images/d/d6/StellarisToolchainMakefile.h -O ~/stellarislaunchpad/Makefile

Anschließend folgt das Herunterladen aller Sourcen. Diese haben entpackt eine Größe von ca. 1.4 GiB und liegen in dem Ordner "~/stellarislaunchpad/source". Zur Überprüfung sind hier die heruntergeladen Pakete aufgeführt.

$ make initial -C ~/stellarislaunchpad/
......
$ ls -1 ~/stellarislaunchpad/source/ 
binutils-2.22
gcc-4.9.0
gdb-7.8
lm4tools-master
newlib-2.1.0
openocd-0.8.0
stellarisWare-master
texinfo-5.2

Jetzt kann der eigentliche Bauvorgang gestartet werden. Dieser wird je nach Rechenleistung des Computers mehrere Stunden benötigen. Die Anzahl der Jobs, mit denen gebaut wird, berechnet sich automatisch aus der Anzahl der Prozessoren. Daher das "make" nicht mit mehreren Jobs starten!

$ make all -C ~/stellarislaunchpad/

Das Ergebnis des Bauvorgangs mit Compiler, Gdb, lm4flash, usw. befindet sich in dem Ordner ~/stellarislaunchpad/.

Die wichtigsten Binaries sind:

~/stellarislaunchpad/output/bin/arm-none-eabi-gcc       # c compiler
~/stellarislaunchpad/output/bin/lm4flash                # tool to programm the stellaris launchpad via usb
~/stellarislaunchpad/output/bin/arm-none-eabi-gdb       # gdb
~/stellarislaunchpad/output/arm-none-eabi/sys-include/  # folder with useful header

Nach diesem langwierigem Prozess des Bauens können wir uns endlich der Programmierung des Stellaris Launchpads widmen. Hierfür ist in dem Makefile ein Beispiel vorhanden. Dabei wird das "blinky" Projekt der Stellaris Ware gebaut und auf das Lauchpad gespielt. Dazu muss das Launchpad selbstverständlich am PC via USB eingesteckt sein. Leider ist es mir bis jetzt nicht gelungen, das lm4flash Tool ohne Rootrechte zu starten. Der Systemcall dazu lautet:

$ sudo make example -C ~/stellarislaunchpad/

Ist alles gut gegangen, blinkt das Stellaris Launchpad nun fröhlich in grün vor sich hin. Bei der Stellaris Ware (unter ~/stellarisware/source/stellarisWare-master/) befinden sich noch viele weitere Beispiele, welche zum experimentieren einladen.

Erklärung des Makefiles

Im folgenden wird genauer auf die einzelnen Teile des Makefiles eingegangen.

Verwendete Variablen

Die wichtigsten globalen Variablen des Makefiles werden hier kurz genannt. Nicht aufgeführt sind die Variablen für den Speicherort und Version der einzelnen Pakete.

BASE    = $(shell pwd)                                   # the act. folder
PREFIX  = $(BASE)/output                                 # install folder
SOURCE  = $(BASE)/source/                                # source folder
TARGET  = arm-none-eabi                                  # target name
JOBS    = $(shell cat /proc/cpuinfo | grep MHz | wc -l)  # number of jobs for make
MAKE    = PATH=$(PREFIX)/bin:$${PATH} make -j $(JOBS)    # make variable with modified path and the number of jobs

Texinfo

Texinfo beinhaltet das Programm "makeinfo", welches beim Bauen der Newlib benötigt wird. Nur aus diesem Grund wird dieses relativ kleine Software-Paket mit gebaut.

texinfo:
	cd $(TEXINFO_DIR) && ./configure \
	  --prefix=$(PREFIX)
	$(MAKE) -C $(TEXINFO_DIR) all
	$(MAKE) -C $(TEXINFO_DIR) install


Binutils

Die Binutils beinhalten eine Vielzahl an Werkzeugen, unter anderem zum Übersetzen von Code. Mehr Informationen dazu gibt es auf der GNU-Website.

binutils:
	cd $(BINUTILS_DIR) && ./configure  \
	  --target=$(TARGET) \
	  --prefix=$(PREFIX) \
	  --disable-nls	  \
	  --enable-multilib \
	  --with-gnu-as	  \
	  --with-gnu-ld	  \
	  --disable-libssp   \
	  --disable-werror
	$(MAKE) -C $(BINUTILS_DIR) all
	$(MAKE) -C $(BINUTILS_DIR) install

Gcc-initial

Nun wird der eigentliche Gcc Compiler gebaut. Dieser benötigt zum vollständigen Bauen eine Library mit grundlegenden Funktionen und den entsprechenden Header Dateien. Nachdem die glibc-Library zu groß für Mikrocontroller ist, bietet sich z. B. Newlib an. Zum Bauen der Newlib muss allerdings ein Teil des GCC bereits vorhanden sein, weshalb dieser in zwei Schritten gebaut werden muss.

Die richtige Reihenfolge hierfür sit:

  1. GCC-Configure
  2. GCC-make all-gcc
  3. GCC-make install-gcc
  4. NEWLIB-configure
  5. NEWLIB-make
  6. NEWLIB-make install
  7. GCC-make all
  8. GCC-make install

Erst nach dem erfolgreichen letzten Schritt ("make install") ist GCC komplett gebaut.

Aber nun zu der Erklärung. Zu Beginn wird im GCC-Verzeichnis ein neuer Ordner angelegt, weil man den GCC nicht direkt in dem Verzeichnis der Sourcen bauen kann. Bei der Konfiguration werden eine Vielzahl an Features ausgeschaltet, welche auf dem Mikrocontroller nicht benötigt werden. Wichtig ist das Setzen des "--enable-languages" Flags für die gewünschte Sprache - in diesem Fall C. Dazu kommt natürlich das entsprechende Flag für die Newlib ("--with-newlib"). Um diese zu verwenden, muss zusätzlich der Headerpfad zu der Newlib angegeben werden ("--with-headers"). Zudem ist auch die Angabe des CPU-Typs (cortex-m4) wichtig.

gcc-initial:
	mkdir -p $(GCC_DIR)/build
	cd $(GCC_DIR)/build && PATH=$(PREFIX)/bin:$${PATH} ../configure	\
	  --target=$(TARGET)	    \
	  --prefix=$(PREFIX)	    \
	  --enable-languages=c	    \
	  --disable-bootstrap	    \
	  --disable-libgomp         \
	  --disable-libmudflap	    \
	  --enable-multilib	    \
	  --disable-libphobos	    \
	  --disable-decimal-float   \
	  --disable-libffi	    \
	  --disable-libmudflap	    \
	  --disable-libquadmath	    \
	  --disable-libssp	    \
	  --disable-libstdcxx-pch   \
	  --disable-nls		    \
	  --disable-shared	    \
	  --disable-threads	    \
	  --disable-tls		    \
	  --with-gnu-as		    \
	  --with-gnu-ld		    \
	  --with-cpu=cortex-m4	    \
	  --with-tune=cortex-m4	    \
	  --with-mode=thumb	    \
	  --with-newlib             \
	  --with-headers=$(NEWLIB_DIR)/newlib/libc/include/
	$(MAKE) -C $(GCC_DIR)/build/ all-gcc 
	$(MAKE) -C $(GCC_DIR)/build/ install-gcc

Newlib

Vor dem Bauen der Newlib muss die verwendete Version 2.1.0 noch gepatcht werden, weil sonst folgender Fehler auftritt:

make[7]: Entering directory '/home/user/stellarislaunchpad/source/newlib-2.1.0/arm-none-eabi/thumb/libgloss/arm/cpu-init'
make[7]: *** No rule to make target '../../../.././libgloss/arm/../config/default.mh', needed by 'Makefile'.  Stop.

Der Patch ist in das Makefile integriert und wird sofort nach dem Herunterladen der Sourcen eingespielt:

--- libgloss/arm/cpu-init/Makefile.in	2013-10-14 17:15:12.000000000 +0200
+++ libgloss/arm/cpu-init/Makefile.in	2014-10-17 21:38:32.623317260 +0200
@@ -18,6 +18,7 @@
 tooldir = $(exec_prefix)/$(target_alias)
 
 objtype = @objtype@
+host_makefile_frag = /../../config/default.mh
 
 INSTALL = @INSTALL@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -80,7 +81,7 @@
 install-info:
 clean-info:
 
-Makefile: Makefile.in ../config.status @host_makefile_frag_path@
+Makefile: Makefile.in ../config.status $${host_makefile_frag_path}
 	$$(SHELL) ../config.status --file cpu-init/Makefile
 
 ../config.status: ../configure

Zum Konfigurieren der Newlib gibt es nichts besonders zu erwähnen. Es wird wie beim GCC natürlich auch unser Target angegeben. Wichtig ist beim Installieren, dass hier nicht unsere "$(MAKE)"-Variable verwendet wird, da es sonst beim Verwenden mehrerer Jobs zu Problemen kommen kann´.

newlib:
	cd $(NEWLIB_DIR) && PATH=$${PATH}/:$(PREFIX)/bin/ ./configure \
	  --target=$(TARGET) \
	  --prefix=$(PREFIX) \
	  --enable-multilib \
	  --disable-libssp \
	  --disable-nls
	$(MAKE) -C $(NEWLIB_DIR) all
	# use normal make without jobs because of issues with multiple jobs
	PATH=$(PREFIX)/bin:$${PATH} make -C $(NEWLIB_DIR) install

GCC-final

Endlich ist es so weit! Wir können unseren Compiler fertig bauen und installieren. Der Compiler befindet sich anschließend unter output/bin/arm-none-eabi-gcc und kann nun verwendet werden.

gcc-final:
	$(MAKE) -C $(GCC_DIR)/build/ all
	$(MAKE) -C $(GCC_DIR)/build/ install

Lm4flash

Zum Aufspielen der Software auf das Launchpad benötigt man die Lm4flash-tools. Diese brauchen zwingend das Paket libusb und das dazugehörige Developer-Package. Unter Arch und Ubuntu können diese leicht über die Paketmanager installiert werden.

lm4tools:
	echo "lm4tools needs libusb dev and pkg(try apt-get install libusb-dev)"
	make -C $(LM4TOOLS_DIR)/lm4flash
	cp $(LM4TOOLS_DIR)/lm4flash/lm4flash $(PREFIX)/bin/

Getestet werden kann Lm4flash einfach mit dem flash-blinky Beispiel des Makefiles - dazu wird das blinky-Projekt der Stellarisware crosscompiliert und per lm4flash auf das Launchpad via USB gespielt. Möglicherweise werden zum Übertragen der Daten, wie bereits erwähnt, Rootrechte benötigt.

blinky:
	$(MAKE) -C $(STELLARISWARE_DIR)/boards/ek-lm4f120xl/blinky/

flash-blinky: blinky
	$(PREFIX)/bin/lm4flash $(STELLARISWARE_DIR)/boards/ek-lm4f120xl/blinky/gcc/blinky.bin

GDB

Zum Debuggen wird nun noch der entsprechende GDB benötigt. Auch dieser kann ohne große Mühe gebaut werden. Hier wird nicht weiter auf den Gdb eingegangen, da es dazu genügend ausführliche Anleitungen im Internet gibt.

gdb:
	cd $(GDB_DIR) && ./configure \
	  --target=$(TARGET) \
	  --prefix=$(PREFIX) \
	  --enable-interwork \
	  --enable-multilib
	$(MAKE) -C $(GDB_DIR) all
	$(MAKE) -C $(GDB_DIR) install

OpenOCD

Und für alle Freunde von OpenOCD kann auch diese Software für die Plattform kompiliert werden. Wichtig dabei ist das "--enable-ti-icdi"-Flag zu setzen:

openocd:
	cd $(OPENOCD_DIR) && ./configure \
	  --prefix=$(PREFIX) \
	  --enable-maintainer-mode \
	  --enable-ti-icdi
	$(MAKE) -C $(OPENOCD_DIR) all
	$(MAKE) -C $(OPENOCD_DIR) install