Forum: Compiler & IDEs GCC als Crosscompiler für ARM auf ARM


von Reinhard M. (reinhard_w)


Lesenswert?

Hallo,


Kurzversion:

Empfiehlt es sich  funktioniert es  hat es schon mal wer gemacht, a) 
auf dem Raspberry die gcc-arm-none-eabi von den Quellen aus zu 
installieren, oder b) den vorhandenen (System-)Compiler (ist ja auch 
ARM) einzusetzen um STM32-Code zu kompilieren?


Langversion:

Ich möchte auf dem Raspberry-2 Programme für STM32 kompilieren. Ich bin 
jedoch (von den tutorials für gcc-arm für Linux oder eigentlich 
mehrheitlich Ubuntu) ein wenig verwirrt, wie die toolchain dafür 
aussehen soll. GNU-Make hab ich natürlich auf Raspbian, sollte keinen 
Unterschied machen, GDB brauche ich nicht, auch keine IDE und kein JTAG.

Soll ich die Quellen z.B. 
gcc-arm-none-eabi-4_9-2015q1-20150306-src.tar.bz2 auf dem raspberry mit 
dessen "system-gcc" (logischer Weise zufällig halt auch arm) quasi als 
Crosscompiler kompilieren/installieren, oder gleich den mit Raspbian 
gelieferten gcc mit den entsprechenden Optionen für den STM32 verwenden 
(dann halt eben mit linkerfile, startupcode, 
Prozessorregisterincludefile usw...)?

Taugt der mit raspbian installierte GCC, um (lediglich mit angepaßten 
Compileroptionen und anderen includes) Code für den STM32 zu 
kompilieren?

Gäbe es Schwierigkeiten mit system-Libraries usw., das Raspberry-System 
und STM32 auseinanderzuhalten? (Vgl.: 
Beitrag "ARM und AVR gcc auf einem Rechner")

Lassen sich die gcc-arm-"eabi"-Quellen unter raspberry kompilieren, ohne 
in Konflikte mit dem System zu kommen? Hat das Vorteile wegen der 
mitgelieferten STM32-Libs oder lassen die sich auch mit dem 
Systemcompiler zu Fuß ganz normal includen und linken, wie man sich das 
sonst auch so erwartet?

Und ... ist der Compiler jetzt nun eigentlich der selbe oder nicht? Muß 
man bei der Versionnummer aufpassen?

Erstes Zielsystem ist ein "Spontankauf", das STM32F0 Value Line 
Discovery, ein Cortex-M0  armv6-m  STM32F030R8T6, nur so zum ersten 
Kennenlernen. Erstes Ziel ist es, den eingebauten UART-Bootloader per 
Raspberry zu verwenden. Als Richtschnur habe ich mir 
http://regalis.com.pl/en/arm-cortex-stm32-gnulinux/ ausgesucht.

von Dr. Sommer (Gast)


Lesenswert?

Reinhard M. schrieb:
> Taugt der mit raspbian installierte GCC, um (lediglich mit angepaßten
> Compileroptionen und anderen includes) Code für den STM32 zu
> kompilieren?
Das geht nicht, der kann nur Linux-Binaries erzeugen (und keine für Bare 
Metal), und kann vermutlich sowieso den Cortex-M nicht.

Reinhard M. schrieb:
> Lassen sich die gcc-arm-"eabi"-Quellen unter raspberry kompilieren, ohne
> in Konflikte mit dem System zu kommen?
Theoretisch ja. Allerdings funktionier das Buildscript vom 
GCC-ARM-Embedded noch nicht einmal unter x86_64, da kannst du dich 
vermutlich auf fröhliche Bug-Suche gefasst machen.

Reinhard M. schrieb:
> Erstes Ziel ist es, den eingebauten UART-Bootloader per
> Raspberry zu verwenden.
Ich würde dringend dazu raten, einen SWD/JTAG-Adapter zu verwenden. Das 
vereinfacht und beschleunigt die Entwicklung und Fehlersuche drastisch. 
Dein Discovery Board hat ja sogar einen ST-Link integriert.

von Jim M. (turboj)


Lesenswert?

Reinhard M. schrieb:
> Erstes Ziel ist es, den eingebauten UART-Bootloader per
> Raspberry zu verwenden.

Einen Raspberry Pi kann man (via GPIO) auch als JTAG Debugger mit 
OpenOCD verwenden. Damit ist die Fehlersuche viel einfacher als über 
UART mit Bootloader.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:
> Allerdings funktionier das Buildscript vom GCC-ARM-Embedded noch nicht
> einmal unter x86_64, da kannst du dich vermutlich auf fröhliche
> Bug-Suche gefasst machen.

Lieber die originalen Quellen von GNU nehmen und dann jeweils mit
configure (--target arm-none-eabi) und make compilieren.

Wichtig ist es, dass man den GCC nie direkt in seinem Verzeichnis
selbst konfigurieren darf.  Es genügt aber, wenn man ein
Unterverzeichnis darin anlegt und dann von da aus ../configure aufruft.

von Schaulus Tiger (Gast)


Lesenswert?

Auf dem Pi2/raspbian müsste man doch die Pakete gcc-arm-none-eabi, 
binutils-... usw. ganz normal über die Paketverwaltung installieren 
können? Das wäre doch mit Abstand das einfachste und sicherste?

von Markus F. (mfro)


Lesenswert?

Dr. Sommer schrieb:
> Reinhard M. schrieb:
>> Taugt der mit raspbian installierte GCC, um (lediglich mit angepaßten
>> Compileroptionen und anderen includes) Code für den STM32 zu
>> kompilieren?
> Das geht nicht, der kann nur Linux-Binaries erzeugen (und keine für Bare
> Metal), und kann vermutlich sowieso den Cortex-M nicht.

Ersteres ist (ziemlich sicher) nicht der Fall während letzteres durchaus 
sein kann (weiß ich nicht).

Dem Compiler ist es völlig wurscht, ob er Code für ein Linux- oder ein 
"Bare Metal" target erzeugt, dafür sind sowieso die binutils zuständig.

Und die wiederum können meiner Ansicht nach neben Code für das 
eigentliche Target immer auch Code für eine beliebige Adresslage und 
ohne Systemcalls  erzeugen.

Also - mit passenden Linker-Scripts und passenden Optionen 
(-ffreestanding -nostdlib) - auch für ein "nackiges" System.

Die System-Libraries kann und darf man natürlich nicht verwenden. Beim 
Rest kommt's auf einen Versuch an, aber ich wüsste nicht, warum das 
nicht gehen sollte.

von Christopher B. (chrimbo) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Wichtig ist es, dass man den GCC nie direkt in seinem Verzeichnis
> selbst konfigurieren darf.  Es genügt aber, wenn man ein
> Unterverzeichnis darin anlegt und dann von da aus ../configure aufruft.

Hallo,
kannst du erklaeren was dafuer der Grund ist? Ich habe das schon oefter 
gelesen, auch auf gcc.gnu.org, aber ausser dass es nicht intensiv 
getestet wird, habe ich keine Erklaerung dafuer gefunden.

MfG
Christopher

von Reinhard M. (reinhard_w)


Lesenswert?

Gut, den (vermutlich selben) Compiler nochmal daneben zu installieren 
scheint die sicherere/üblichere Variante zu sein. Grundsätzlich wird das 
wohl schon möglich sein:

http://www.onandoffables.com/index.php?m=arminarm&p=installation&t=software

Es könnte trotzdem noch abenteuerlich werden, vor allem das Wort 
"probably" macht irgendwie Angst: "If the board has an ARM Cortex-M chip 
(STM32, NXP, Atmel, TI etc.), it'll probably compile. YMMV."

(YMMV hab ich auch noch nicht gekannt: "your mileage may vary"... 
Auweia!)

von Kaj (Gast)


Lesenswert?

Schaulus Tiger schrieb:
> Auf dem Pi2/raspbian müsste man doch die Pakete gcc-arm-none-eabi,
> binutils-... usw. ganz normal über die Paketverwaltung installieren
> können? Das wäre doch mit Abstand das einfachste und sicherste?
Nope. Ich benutze auf dem RPi2 Arch Linux (Kernel 3.18.11-2)) und... was 
soll ich sagen? Da gibt es gcc-arm-none-eabi nicht als paket ueber den 
Paketmanager. Und unter Arch gibt es wirklich so ziemlich alles als 
Paket.
Auf x86 alles kein Problem, aber auf dem RPi alles nicht so einfach.

von Rolf Magnus (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Wichtig ist es, dass man den GCC nie direkt in seinem Verzeichnis
> selbst konfigurieren darf.  Es genügt aber, wenn man ein
> Unterverzeichnis darin anlegt und dann von da aus ../configure aufruft.

Das ist etwas, das man eigentlich sowieso immer machen sollte.

Christopher B. schrieb:
> Hallo,
> kannst du erklaeren was dafuer der Grund ist? Ich habe das schon oefter
> gelesen, auch auf gcc.gnu.org, aber ausser dass es nicht intensiv
> getestet wird, habe ich keine Erklaerung dafuer gefunden.

Der Build legt viele neue Dateien und Verzeichnisse an. Wenn sich da 
irgendwas mit schon vorhandenen Dingen beißt, funktioniert es nicht 
richtig. Deshalb ist es geschickter, einen eigenen Verzeichnisbaum für 
alles, was so vom Build generiert wird, zu haben. Das macht nachher auch 
das Zurückversetzen in den Ursprungszustand leichter. Man muß nur das 
build-Verzeichnis löschen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Markus F. schrieb:
> Dem Compiler ist es völlig wurscht, ob er Code für ein Linux- oder ein
> "Bare Metal" target erzeugt, dafür sind sowieso die binutils zuständig.

Auch der Compiler muss das passende ABI erzeugen können.  Bin mir
gerade nicht sicher, ob das zwischen “bare metal” und RPi wirklich
identisch ist.

Rolf Magnus schrieb:
> Der Build legt viele neue Dateien und Verzeichnisse an. Wenn sich da
> irgendwas mit schon vorhandenen Dingen beißt, funktioniert es nicht
> richtig. Deshalb ist es geschickter, einen eigenen Verzeichnisbaum für
> alles, was so vom Build generiert wird, zu haben.

Dass es geschickter ist, ist keine Frage, aber der GCC ist weit und
breit der einzige, bei dem es ansonsten wirklich schief geht.

von Alexander F. (alexf91)


Lesenswert?

Kaj schrieb:
> Da gibt es gcc-arm-none-eabi nicht als paket ueber den
> Paketmanager. Und unter Arch gibt es wirklich so ziemlich alles als
> Paket.

Kannst du nicht einfach das PKGBUILD Script vom Community Repo nehmen 
und auf dem Raspberry Pi übersetzen?

von Markus F. (mfro)


Lesenswert?

Jörg Wunsch schrieb:
> Auch der Compiler muss das passende ABI erzeugen können.  Bin mir
> gerade nicht sicher, ob das zwischen “bare metal” und RPi wirklich
> identisch ist.

Bei "bare metal" bin ich doch sowieso frei, welches ABI ich verwende, 
dann kann ich doch einfach das nehmen, das der Compiler mir (mehr oder 
weniger zufällig) anbietet?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Markus F. schrieb:
> Bei "bare metal" bin ich doch sowieso frei, welches ABI ich verwende

Im Prinzip ja.  Machst dann halt nur was anderes als der Rest der Welt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Wichtig ist es, dass man den GCC nie direkt in seinem Verzeichnis
> selbst konfigurieren darf.  Es genügt aber, wenn man ein
> Unterverzeichnis darin anlegt und dann von da aus ../configure aufruft.

Wobei auch das nicht "offiziell" unterstützt wird.

von Markus F. (mfro)


Lesenswert?

Johann L. schrieb:
> Wobei auch das nicht "offiziell" unterstützt wird.

Wär' mir neu.

Nach meiner Erinnerung steht's genauso in der Anleitung und funzt auch 
zuverlässig.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Markus F. schrieb:
> Johann L. schrieb:
>> Wobei auch das nicht "offiziell" unterstützt wird.
>
> Wär' mir neu.
>
> Nach meiner Erinnerung steht's genauso in der Anleitung und funzt auch
> zuverlässig.

Lesen gegen Erinnern:  1:0

> First, we highly recommend that GCC be built into a separate
> directory from the sources which does not reside within the
> source tree. This is how we generally build GCC; building where
> srcdir == objdir should still work, but doesn't get extensive
> testing; building where objdir is a subdirectory of
> srcdir is unsupported.

https://gcc.gnu.org/install/configure.html

von user (Gast)


Lesenswert?

also bei debian auf arm ist der gcc-arm-none-eabi dabei

https://packages.debian.org/jessie/gcc-arm-none-eabi

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. schrieb:
> building where objdir is a subdirectory of
> srcdir is unsupported.

Geht aber witzigerweise, im Gegensatz zu objdir == srcdir.

von Rolf Magnus (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Rolf Magnus schrieb:
>> Der Build legt viele neue Dateien und Verzeichnisse an. Wenn sich da
>> irgendwas mit schon vorhandenen Dingen beißt, funktioniert es nicht
>> richtig. Deshalb ist es geschickter, einen eigenen Verzeichnisbaum für
>> alles, was so vom Build generiert wird, zu haben.
>
> Dass es geschickter ist, ist keine Frage, aber der GCC ist weit und
> breit der einzige, bei dem es ansonsten wirklich schief geht.

Ich kenne noch ein anderes, allerdings nicht mehr aktuelles und eher 
obskures, Beispiel.
Bei KDE3 gab es noatun. Das war ein Audio-Player. Bei dem ging es auch 
nur mit builddir!=srcdir. Es gab im Quellverzeichnis ein 
Unterverzeichnis "noatun", das aber eigentlich nicht mehr genutzt wurde. 
Leider waren Verzeichnisse im damals noch verwendeten CVS nicht 
versioniert und konnten damit, wenn sie einmal im Repo waren, nie wieder 
- auch nicht in neuen Revisionen - entfernt werden. Wenn man nun den 
Build im Quellverzeichnis machte, wollte der Compiler ein Executable 
namens noatun anlegen, was aber nicht ging, weil es eben schon ein 
Verzeichnis mit diesem Namen gab.

von Rolf Magnus (Gast)


Lesenswert?

Johann L. schrieb:
> building where objdir is a subdirectory of srcdir is unsupported.

Das ist ja interessant. So mache ich das normalerweise bei allen 
Paketen, die zum bauen ein eigenes Verzeichnis unterstützen. Ich wüßte 
auch nicht, was da schiefgehen sollte, wenn es einigermaßen vernünftig 
implementiert ist.

von Reinhard M. (reinhard_w)


Lesenswert?

So, ich hab mal bequemlichkeitshalber das Packerl von arminarm auf dem 
raspberry installiert.

Erstes naives Kompilieren mit den Optionen von hier gab die Meldung vom 
Linker:

undefined reference to `_exit'

Das erwartet man nicht unbedingt, wenn der Compiler eigentlich wissen 
sollte, daß er bare metal binaries erzeugen soll und er daher nicht nach 
einem Betriebssystem zur Rückkehr suchen sollte. (Das hätte er zumindest 
eventuell wissen "können", weil er ja als crosscompiler 
(vor-)konfiguriert ist.) Das Attribut "noreturn" in main() zu setzen, um 
ihn mit der Nase darauf zu stoßen, daß er keinen exit machen soll, 
brachte nichts.

Dann fand sich der Hinweis, man solle doch --specs=nosys.specs 
hinzufügen.

arm-none-eabi-gcc --specs=nosys.specs main.c -mcpu=cortex-m0 
-mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os 
-fltoarm-none-eabi-gcc: error: nosys.specs: No such file or directory

Aha. Also weiter gesucht, was sich so im lib-tree findet, der nächste 
Vorschlag lautete und fand sich auch im Paket:

arm-none-eabi-gcc --specs=rdimon.specs -lgcc -lc -lm -lrdimon main.c 
-mcpu=cortex-m0 -mfloat-abi=soft -mthumb -ffunction-sections 
-fdata-sections -Os -flto

Ah, kein Fehler, er hat was kompiliert und gelinkt. Aber was zum Teufel 
ist dieses rdimon? Irgendwas zum debuggen, scheint mir. Aber egal.

Weiter gesucht, einen Hinweis auf -nostdlib gefunden und nächster 
Versuch
mit:

arm-none-eabi-gcc -lgcc -lc -lm -nostdlib main.c -mcpu=cortex-m0 
-mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto

Ergebnis ist ein Warning:

cannot find entry symbol _start; defaulting to 00008000

...ich komme der Sache also schon näher, jedenfalls habe ich so etwas 
ähnliches erwartet, ich hab ja noch kein Linkerfile. Interessant, daß er 
die Funktion auf 8000h legt, in die Mitte des Flash, nunja, am Anfang 
ist die Interruptvektortabelle, also vielleicht ist das sogar Absicht.

CMSIS-CORE wäre dann mal als nächstes dran und ein Linker file und ein 
Startupcode, aber alles langsam und Schritt für Schritt.

Wo ist eigentlich diese newlib? Nicht mitinstalliert? Und will ich die 
überhaupt?

Nun, vorläufig habe ich den Eindruck, wenn man sich die toolchain und 
libs im Paket holt, erspart man sich zwar viel, stellt dann aber fest, 
daß man keine Ahnung hat. Aber immer noch besser als eine fertige IDE zu 
verwenden, da hat man genauso wenig Ahnung, aber merkt es nicht mal.

Hm, ich sehe von CMSIS nur was für den STM32-Chip, den die onandoffables 
verkaufen und von newlib auch keine Spur. Das wird man sich extra holen 
müssen. Aber für den ersten Abend soll das mal reichen.

von Rolf Magnus (Gast)


Lesenswert?

Reinhard M. schrieb:
> Wo ist eigentlich diese newlib? Nicht mitinstalliert?

Wenn du sie nicht installiert hast, ist sie nicht installiert.

> Und will ich die überhaupt?

Wenn du irgendeine Standard-C-Funktion nutzen willst, wirst du eine libc 
brauchen. Die newlib ist eine solche. Ohne die wirst du sehr viel zu Fuß 
machen müssen.
Den Link auf die Homepage hättest du übrgens auch selber finden können:
https://sourceware.org/newlib/

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Reinhard M. schrieb:
> undefined reference to `_exit'

Ja, und?  Dann gib ihm doch einfach eins, statt dich an derartigen
Nebensächlichkeiten festzuhalten:
1
void _exit(void) { for (;;) {} }

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Ja, und?  Dann gib ihm doch einfach eins, statt dich an derartigen
> Nebensächlichkeiten festzuhalten:
>
>
1
> void _exit(void) { for (;;) {} }
2
>

Vielleicht noch ein

     __disable_irq();

vor der Endlosschleife?

von Chris W (Gast)


Lesenswert?

Hallo Reinhard,

Du wirst sehr wahrscheinlich die newlib installiert haben. Gib Dir mal 
mit
1
arm-none-eabi-cpp -v
 die Infos vom Präprozessor aus.

Der erste Abschnitt enthält die Buildinfos von dieser Compilerinstanz, 
mit welchen Optionen sie gebaut wurde.

Da findest Du wahrscheinlich
1
--with-newlib
 die eben Deine std-C/C++ lib ist.

Am Ende der Ausgabe findest Du dann noch die Include-Dirs, die immer 
durchsucht werden.

Ein andere für's Linken nützliche Info ist
1
arm-none-eabi-gcc --print-search-dirs
 was Dir erstmal wieder die Buildoptionen und dann die 
Standard-SearchDirs für die Libraries ausgibt.

Zieh Dir bei ST das STM32CubeF0 Packet runter. Das passende findest Du 
auf der Seite von Deinem Discovery Board.

Darin sind die letzten CMSIS-Header enthalten und bei den Beispielen 
unter den "True Studio" Verzeichnissen gibt's die LinkerSkripts und 
Assembler StartCodes.

MfG
   Chris

von Reinhard M. (reinhard_w)


Lesenswert?

Vorweg: Ich möchte Euch nicht langweilen, wenn ich wo nicht mehr selber 
weiterkomme und Eure Hilfe brauche, werde ich schon schreien, derweil 
dokumentiere ich hier eigentlich nur mein Treiben und Staunen. Natürlich 
freue ich mich über Kommentare, Hinweise und Antworten auf die Fragen, 
die sich dabei so ergeben und hoffe, daß andere sie vielleicht 
unterhaltsam oder gar hilfreich finden... Korrekturen zu meinen 
Vermutungen wären allerdings durchaus erwünscht, wenn ich mal wo was 
falsch vermute, damit ich nicht dritte in die Irre führe!


Ja, ich hatte die Homepage von newlib gestern Abend schon noch gefunden, 
war aber zu spät es noch zu berichten. Das ist entfernt so etwas 
ähnliches wie die glibc ohne Betriebssystem-Funktionen. Also nicht 
unbedingt erforderlich. Das meiste wird mangels "Supporting OS 
subroutines" nicht funktionieren bzw. macht "bare metal" eh keinen Sinn. 
Die enthaltenen Divisionsfunktionen sind nur die, die Quotienten und 
Rest gleichzeitig ausrechnen. Bei der arminarm-Installation liegt ein 
libiberty.a herum, das dürfte was ähnliches sein wie newlib.

Apropos newlib. Da finde ich tatsächlich ein newlib.h. Nanu? Ist das 
also doch im Paket dabei gewesen? Aber wenn ich's aufmache, lese ich:

/* dummy file for external tools to use.  Real file is created by
   newlib configuration. */

...irgendwie schon eine ganz spezielle Art von Humor. ;-)

PS: Ein gefülltes newlib.h hab ich auch gefunden, also wer weiß, 
vielleicht ist es ja doch drauf. Ich sollte mal die Verzeichnisstruktur 
genauer untersuchen. Daß da echte Files und Dummyfiles herumliegen, 
erschwert allerdings die Orientierung.

Es gibt aber, so wie ich das bis jetzt verstanden habe, auch noch eine 
"compilerinterne Lib" z.b. für elementare Integermathematik: libgcc. Die 
wäre natürlich schon unbedingt nötig, das schau ich mir gleich an, wo 
das wäre, wenn es denn da ist... Hardwaredivision hat der Cortex-M0 ja 
nicht, insofern könnte das ja doch schon dabei sein (ich hab eine modulo 
Berechnung im Testcode. PS: Jetzt auch eine floating point rechnung, 
kein Warning deswegen. Ich hoffe, er hat es nicht wegoptimiert und zeigt 
nicht nur deswegen keinen Fehler.)

PPS: Ich wollte gerade die Linkeroption zum Erzeugen eines Mapfiles 
nachschlagen, da sehe ich für -nostdlib: "options specifying linkage of 
the system libraries, such as -static-libgcc or -shared-libgcc, are 
ignored."
PPPS: Ah, paßt schon, mit -lgcc wird libgcc dann doch wieder gelinkt. 
Ja, kommt davon, wenn man Compiler- und Linkeroptionen einfach kopiert.

Mir ist aber noch ein wenig unklar, wie der gcc auf 
/lib/gcc/arm-none-eabi/4.8.2/thumb/armv6-m/libgcc.a kommt. Ist das ein 
Automatismus (ABI/GCC-Versionsnummer/Befehlssatz/Architektur/)? Als 
Umgebungsvariable hab ich den Pfad dorthin nicht, von einer Config-Datei 
sehe ich auch nichts.

PPPPS: Ja, der gcc sucht seine libs und wer weiß was sonst noch offenbar 
wirklich nach so einem Konventions-Suchmuster.


BTW: Der native gcc meldet mit dem gleichen Aufruf:

/usr/bin/ld: error: a.out uses VFP register arguments, 
/tmp/cc6KADv3.ltrans0.ltrans.o does not
/usr/bin/ld: failed to merge target specific data of file 
/tmp/cc6KADv3.ltrans0.ltrans.o
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 
00008188
collect2: ld returned 1 exit status

0x8188 statt 0x8000, warum auch immer... Und WTF ist 
"/tmp/cc6KADv3.ltrans0.ltrans.o"? Ein statisches Library-Object kann es 
nicht sein, das wäre nicht in tmp. Also muß er es kompiliert haben. Aber 
was? PS: siehe ganz unten...

Das ist ein wenig das Verwirrende: Einerseits gibt es die diversen 
Compileroptionen für arch=arm, andererseits kann man sie nicht benutzen, 
vermutlich weil besagte libgcc für den Raspberry im falschen Format 
kompiliert wurde (armv7 mit floating point). Auf "multilib" wird der 
raspbian vermutlich nicht konfiguriert worden sein. Ich hab 
grundsätzlich das Problem mit der Übersicht, was konfiguriert wird, was 
als Compileroption, was als Linkeroption definiert wird und was wo liegt 
und wo gesucht wird. Daher wird CMSIS einzubinden sicher auch noch seine 
Fallstricke haben.

__disable_irq() ... das aus CMSIS, core_cmFunc.h?

Ja, ich denk mal, ich werde mich heute Abend mal um CMSIS-core zumindest 
für meinen STM32F030R8T6 kümmern. Zuvor schau ich mir mal das mapfile 
meiner dummy-Kompilate an...

...der nächste kleine Schock, sooo umfangreich hätte ich das Mapfile 
nicht erwartet, nicht ohne Startupcode und Linkerfile. Immerhin enthält 
es erste Hinweise auf das seltsame ltrans-Objekt, wirft dafür aber neue 
Verständnisfragen auf. ...Welches plugin, vom Cortex-M0 etwas?

Hier u.a. das Mapfile per arm-none-eabi-gcc -lgcc -lc -lm -nostdlib 
main.c -mcpu=cortex-m0 -mfloat-abi=soft -mthumb -ffunction-sections 
-fdata-sections -Os -flto -Wall -pedantic -Wl,-MAP

-------------------------------------------------------

Discarded input sections

 .text          0x00000000        0x0 /tmp/cc4jdc6Z.o (symbol from 
plugin)

Memory Configuration

Name             Origin             Length             Attributes
default        0x00000000         0xffffffff

Linker script and memory map

LOAD 
/opt/arminarm/bin/../lib/gcc/arm-none-eabi/4.8.2/thumb/armv6-m/libgcc.a
LOAD 
/opt/arminarm/bin/../lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-ea 
bi/lib/thumb/armv6-m/libc.a
LOAD 
/opt/arminarm/bin/../lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-ea 
bi/lib/thumb/armv6-m/libm.a
LOAD /tmp/cc4jdc6Z.o
LOAD /tmp/ccQfvxXh.ltrans0.ltrans.o
                0x00008000                PROVIDE (__executable_start, 
0x8000)
                0x00008000                . = 0x8000

.interp
 *(.interp)

.note.gnu.build-id
 *(.note.gnu.build-id)

.hash
 *(.hash)

.gnu.hash
 *(.gnu.hash)

.dynsym
 *(.dynsym)

.dynstr
 *(.dynstr)

.gnu.version
 *(.gnu.version)

.gnu.version_d
 *(.gnu.version_d)

.gnu.version_r
 *(.gnu.version_r)

.rel.dyn        0x00008000        0x0
 *(.rel.init)
 *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
 *(.rel.fini)
 *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
 *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*)
 *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
 *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
 *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
 *(.rel.ctors)
 *(.rel.dtors)
 *(.rel.got)
 *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
                0x00008000                PROVIDE (__rel_iplt_start, .)
 *(.rel.iplt)
                0x00008000                PROVIDE (__rel_iplt_end, .)
                0x00008000                PROVIDE (__rela_iplt_start, .)
                0x00008000                PROVIDE (__rela_iplt_end, .)

.rela.dyn       0x00008000        0x0
 *(.rela.init)
 *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
 *(.rela.fini)
 *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
 *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
 *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
 *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
 *(.rela.ctors)
 *(.rela.dtors)
 *(.rela.got)
 *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
                0x00008000                PROVIDE (__rel_iplt_start, .)
                0x00008000                PROVIDE (__rel_iplt_end, .)
                0x00008000                PROVIDE (__rela_iplt_start, .)
 *(.rela.iplt)
                0x00008000                PROVIDE (__rela_iplt_end, .)

.rel.plt
 *(.rel.plt)

.rela.plt
 *(.rela.plt)

.init
 *(SORT(.init))

.plt
 *(.plt)

.iplt
 *(.iplt)

.text           0x00008000        0x0
 *(.text.unlikely .text.*_unlikely .text.unlikely.*)
 *(.text.exit .text.exit.*)
 *(.text.startup .text.startup.*)
 *(.text.hot .text.hot.*)
 *(.text .stub .text.* .gnu.linkonce.t.*)
 .text          0x00008000        0x0 /tmp/ccQfvxXh.ltrans0.ltrans.o
 *(.gnu.warning)
 *(.glue_7t)
 .glue_7t       0x00000000        0x0 linker stubs
 *(.glue_7)
 .glue_7        0x00000000        0x0 linker stubs
 *(.vfp11_veneer)
 .vfp11_veneer  0x00000000        0x0 linker stubs
 *(.v4_bx)
 .v4_bx         0x00000000        0x0 linker stubs

.fini
 *(SORT(.fini))
                0x00008000                PROVIDE (__etext, .)
                0x00008000                PROVIDE (_etext, .)
                0x00008000                PROVIDE (etext, .)

.rodata
 *(.rodata .rodata.* .gnu.linkonce.r.*)

.rodata1
 *(.rodata1)

.ARM.extab
 *(.ARM.extab* .gnu.linkonce.armextab.*)
                0x00008000                PROVIDE (__exidx_start, .)

.ARM.exidx
 *(.ARM.exidx* .gnu.linkonce.armexidx.*)
                0x00008000                PROVIDE (__exidx_end, .)

.eh_frame_hdr
 *(.eh_frame_hdr)

.eh_frame
 *(.eh_frame)

.gcc_except_table
 *(.gcc_except_table .gcc_except_table.*)

.exception_ranges
 *(.exception_ranges .exception_ranges*)
                0x00008000                . = (ALIGN (0x8000) + (. & 
0x7fff))

.eh_frame
 *(.eh_frame)

.gcc_except_table
 *(.gcc_except_table .gcc_except_table.*)

.exception_ranges
 *(.exception_ranges .exception_ranges*)

.tdata
 *(.tdata .tdata.* .gnu.linkonce.td.*)

.tbss
 *(.tbss .tbss.* .gnu.linkonce.tb.*)
 *(.tcommon)

.preinit_array  0x00008000        0x0
                0x00008000                PROVIDE 
(__preinit_array_start, .)
 *(.preinit_array)
                0x00008000                PROVIDE (__preinit_array_end, 
.)

.init_array     0x00008000        0x0
                0x00008000                PROVIDE (__init_array_start, 
.)
 *(SORT(.init_array.*))
 *(.init_array)
                0x00008000                PROVIDE (__init_array_end, .)

.fini_array     0x00008000        0x0
                0x00008000                PROVIDE (__fini_array_start, 
.)
 *(SORT(.fini_array.*))
 *(.fini_array)
                0x00008000                PROVIDE (__fini_array_end, .)

.ctors
 *crtbegin.o(.ctors)
 *crtbegin?.o(.ctors)
 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
 *(SORT(.ctors.*))
 *(.ctors)

.dtors
 *crtbegin.o(.dtors)
 *crtbegin?.o(.dtors)
 *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
 *(SORT(.dtors.*))
 *(.dtors)

.jcr
 *(.jcr)

.data.rel.ro
 *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
 *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*)

.dynamic
 *(.dynamic)

.got
 *(.got.plt)
 *(.igot.plt)
 *(.got)
 *(.igot)

.data           0x00008000        0x0
                0x00008000                __data_start = .
 *(.data .data.* .gnu.linkonce.d.*)
 .data          0x00008000        0x0 /tmp/ccQfvxXh.ltrans0.ltrans.o

.data1
 *(.data1)
                0x00008000                _edata = .
                0x00008000                PROVIDE (edata, .)
                0x00008000                . = .
                0x00008000                __bss_start = .
                0x00008000                _bss_start_ = .

.bss            0x00008000        0x0
 *(.dynbss)
 *(.bss .bss.* .gnu.linkonce.b.*)
 .bss           0x00008000        0x0 /tmp/ccQfvxXh.ltrans0.ltrans.o
 *(COMMON)
                0x00008000                . = ALIGN ((. != 0x0)?0x4:0x1)
                0x00008000                bss_end_ = .
                0x00008000                _bss_end_ = .
                0x00008000                . = ALIGN (0x4)
                0x00008000                . = SEGMENT_START 
("ldata-segment", .)
                0x00008000                . = ALIGN (0x4)
                0x00008000                _end_ = .
                0x00008000                _end = .
                0x00008000                PROVIDE (end, .)

.stab
 *(.stab)

.stabstr
 *(.stabstr)

.stab.excl
 *(.stab.excl)

.stab.exclstr
 *(.stab.exclstr)

.stab.index
 *(.stab.index)

.stab.indexstr
 *(.stab.indexstr)

.comment        0x00000000       0x1a
 *(.comment)
 .comment       0x00000000       0x1a /tmp/ccQfvxXh.ltrans0.ltrans.o
                                 0x1b (size before relaxing)

.debug
 *(.debug)

.line
 *(.line)

.debug_srcinfo
 *(.debug_srcinfo)

.debug_sfnames
 *(.debug_sfnames)

.debug_aranges
 *(.debug_aranges)

.debug_pubnames
 *(.debug_pubnames)

.debug_info
 *(.debug_info .gnu.linkonce.wi.*)

.debug_abbrev
 *(.debug_abbrev)

.debug_line
 *(.debug_line .debug_line.* .debug_line_end)

.debug_frame
 *(.debug_frame)

.debug_str
 *(.debug_str)

.debug_loc
 *(.debug_loc)

.debug_macinfo
 *(.debug_macinfo)

.debug_weaknames
 *(.debug_weaknames)

.debug_funcnames
 *(.debug_funcnames)

.debug_typenames
 *(.debug_typenames)

.debug_varnames
 *(.debug_varnames)

.debug_pubtypes
 *(.debug_pubtypes)

.debug_ranges
 *(.debug_ranges)

.debug_macro
 *(.debug_macro)

.stack          0x00080000        0x0
                0x00080000                _stack = .
 *(.stack)

.ARM.attributes
                0x00000000       0x2f
 *(.ARM.attributes)
 .ARM.attributes
                0x00000000       0x2f /tmp/ccQfvxXh.ltrans0.ltrans.o
 *(.gnu.attributes)

.note.gnu.arm.ident
 *(.note.gnu.arm.ident)

DISCARD
 *(.note.GNU-stack)
 *(.gnu_debuglink)
 *(.gnu.lto_*)
OUTPUT(a.out elf32-littlearm)

von Reinhard M. (reinhard_w)


Lesenswert?

Jetzt gibt es doch ein ernsteres Problem, bzw. einen Rückschlag:

Da ich meine Funktionen im mapfile nicht gesehen habe, dachte ich - wie 
erwähnt - daß sie eventuell wegoptimiert sein könnten.

Im copy&paste compileroptions-string findet sich tatsächlich ein -Os. 
Wenn ich das weglasse oder -O0 schreibe, klappt es offenbar leider nicht 
mehr mit dem Linken der libgcc. Und das finde ich jetzt schon etwas 
seltsam und wäre für Hilfe dankbar. Kann es am noch immer fehlenden 
Linkerfile liegen? Dann würde ich aber eine Fehlermeldung bezüglich 
Überschreitung der Speichergröße erwarten oder daß er etwas nicht 
lokatieren kann oder ähnliches, keine fehlenden Referenzen auf Objekte 
von Libs, die er offenbar geladen hat. Vielleicht erwarten die 
Funktionen in der gcclib.a bestimmte Segmente, was nur mit -Os nicht 
aufgefallen ist, weil diese Funktionen ge-inline-t worden sind?



arm-none-eabi-gcc -lgcc -lc -lm -nostdlib main.c -mcpu=cortex-m0 
-mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -flto -Wall 
-pedantic -Wl,-MAP

: Bearbeitet durch User
von Reinhard M. (reinhard_w)


Angehängte Dateien:

Lesenswert?

Entschuldigung wegen des Textimports. Das mapfile nun als Anhang.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Reinhard M. schrieb:
> undefined reference to `_exit'
>
> Das erwartet man nicht unbedingt, wenn der Compiler eigentlich wissen
> sollte, daß er

Er macht das, was du ihm sagst:

Wenn in der Quelle ein Aufruf zu _exit steht, ezeugt der Compiler einen 
Aufruf zu _exit.

Wenn in einem Modul _exit referenziert wird, dann wird in dem Modul 
_exit referenziert und der Linker wird es auflösen wollen.

Ich glaub kaum, dass man von einem Compiler erwarten kann, dass er sich 
selbst oder die Laufzeitumgebung repariert, wenn der Compiler nicht 
richtig konfiguriert wurde oder die Laufzeitumgebung nicht passt oder 
unvollständig ist.

von Reinhard M. (reinhard_w)


Lesenswert?

Johann L. schrieb:

> Ich glaub kaum, dass man von einem Compiler erwarten kann, dass er sich
> selbst oder die Laufzeitumgebung repariert, wenn der Compiler nicht
> richtig konfiguriert wurde oder die Laufzeitumgebung nicht passt oder
> unvollständig ist.

Es handelt sich um ein fertiges Installationspaket, allerdings für einen 
Cortex-M3, während ich für einen Cortex-M0 zu bauen versuche.

Darüber, ob sich die Unterschiede schon mit compileroptionen (nebst 
linkerfile und startup-code) erschlagen lassen, ob man die internen Libs 
neu compilieren muß, sonstige Libs einfach immer neu kompilieren kann, 
oder der gesamte Compiler samt interner Libs umkonfiguriert werden muß, 
habe ich leider derzeit noch keinen Überblick. Bisher ging ich davon 
aus, daß eine gcc-Installation mit arm-none-eabi beides abdeckt 
(passende Optionen und korrektes linkerfile und startupcode 
vorausgesetzt).

Vielleicht muß man ja - um auf mein aktuelles Problem zurückzukommen - 
auch einfach seine eigene SW mit der selben Optimierungsstufe 
kompilieren, wie die gcclib.a gebaut worden ist oder jedes Mal ein 
Neukompilieren derselben veranlassen. Würde mich allerdings schon sehr 
wundern. Oder es ist jetzt einfach schon die Zeit für ein passendes 
Linkerfile.

von Reinhard M. (reinhard_w)


Lesenswert?

Oh, das ist interessant:

Das Problem habe ich ja offenbar mit gcclib.a bei -O0 mit:

-mcpu=cortex-m0
-mfloat-abi=soft

-mcpu=cortex-m0
-mfloat-abi=hard scheitert selbstverständlich an der fehlenden FPU.

Aber:

-mcpu=cortex-m3
-mfloat-abi=soft

geht auch nicht, jedoch,

-mcpu=cortex-m3
-mfloat-abi=hard

kompiliert, auch mit -O0.

Brauche ich für den Cortex-M0 eine gcclib.a mit -mfloat-abi=soft? 
Multilib?

Hm... multilib... mal schauen, was ich da bei mir hab'...

arm-none-eabi-gcc -print-multi-lib
.;
thumb;@mthumb
thumb/thumb2;@mthumb@march=armv7
thumb/armv6-m;@mthumb@march=armv6-m
thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16;@mthumb@mcpu=cortex-m4@mfloa 
t-abi=hard@mfpu=fpv4-sp-d16

Passen die Compileroptionen -mthumb -march=armv6-m für Cortex-M0? Ich 
wollte gerade nachschauen, ob eine Nicht-Angabe der Option automatisch 
"=soft" bedeutet. Der Hinweis im GCC manual mit "The default depends on 
the specific target configuration." ist jedoch keine große Hilfe.

von Reinhard M. (reinhard_w)


Lesenswert?

Die Sache mit der floating point Arithmetik könnte auch eine falsche 
Fährte sein, da u.a. mit __aeabi_idivmod auch eine Integer-Divison 
betroffen ist. Aber ich bin wenigstens nicht der einzige mit dem 
Problem:

https://www.raspberrypi.org/forums/viewtopic.php?f=72&t=75845

Für heute laß ich es mal gut sein und muß mich mit dem Erkenntnisgewinn 
zufrieden geben:

1.) Ohne -O0 (bzw. mit -Os) kompiliert der GCC sinnlose Rechnungen 
kompromißloser weg, als man glauben möchte, erstaunlicher Weise selbst 
dann, wenn man die Ergebnisse dieser sinnlosen Rechnungen sequentiell in 
eine volatile Variable schreibt.

2.) Grundschulmathematik ist keine so triviale Angelegenheit für 
Compilerbauer ... und deren Kunden, wie man glauben sollte. Für 
ALU-Designer allerdings auch nicht.

von Markus F. (mfro)


Lesenswert?

Reinhard M. schrieb:
> Der Hinweis im GCC manual mit "The default depends on
> the specific target configuration." ist jedoch keine große Hilfe.

gcc -v

Die "Rucksacklibrary" vom gcc heißt übrigens libgcc.a, nicht gcclib...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Reinhard M. schrieb:
> Vielleicht muß man [...] seine eigene SW mit der selben
> Optimierungsstufe kompilieren, wie die gcclib.a gebaut
> worden ist

Nein.

Das ABI ist unabhängig von Optimierungen. Wenn du keine 
Multilibvarianten (libgcc, libc, ...) hast, die zu deinem Silizium 
passen, hann musst du dir diese besorgen oder selbst generieren.

Das Anlegen einer neuen Variante kann einfach sein (wenn z.B. nur neue 
Multilib-Optionen hinzukommen) oder schwieriger (wenn es Änderungem im 
ABI braucht).

Die Funktion __aeabi_idivmod heißt in GCC Naming-Convention 
z.B. __divmodsi4, d.h. bei dieser Anpassung war es nicht damit getan, 
eine neue Multilib-Option einzuführen.

> Es handelt sich um ein fertiges Installationspaket, allerdings für einen
> Cortex-M3, während ich für einen Cortex-M0 zu bauen versuche.

Mit ARM kenn ich mich net aus; aber hier gilt das, was auch überall 
sonst gilt: Wenn Cortex-M3 keine Teilmenge von Cortex-M0 ist, wirst du 
da sehr wahrscheinlich Probleme bekommen.  Wenn der M0 z.B. weniger 
Instruktione kennt als der M3, anderes ABI hat usw. wird M3-Code i.d.R. 
nicht auf einem M0 lauffähig sein.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Wenn der M0 z.B. weniger Instruktione kennt als der M3

Ja, so ist es.  Die Cortexe mit den kleineren Ziffern sind jeweils
eine Untermenge derer mit den größeren Ziffern.

von Reinhard M. (reinhard_w)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich hätte schon gedacht, daß...

> thumb/armv6-m;@mthumb@march=armv6-m

...für den Cortex-M0 passen müßte. Vom thumb-2 Befehlssatz kennt er 
zusätzlich zum thumb Befehlssatz eine Untermenge, aber mit thumb hätte 
er auch durchkommen müssen und ich glaube auch nicht, daß die 
dazugehörige libgcc.a mit floating point Instruktionen kompiliert ist. 
Vielleicht enthält sie diese Funktionen gar nicht, weil das 
Installationspaket  erwartet, daß man ersatzweise eine andere Library 
verlinkt.

Vielleicht sind auch einfach nur die Compiler/Linker Optionen falsch, 
unvollständig oder in einer falschen Reihenfolge.

U.u. könnte es auch am fehlenden Linkerfile liegen, daß das wahre 
Problem also darin besteht, daß der Linker nicht weiß, wohin mit dem 
Zeug.

Immerhin sagt das Mapfile, daß mit...

LOAD 
/opt/arminarm/bin/../lib/gcc/arm-none-eabi/4.8.2/thumb/armv6-m/libgcc.a
LOAD 
/opt/arminarm/bin/../lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-ea 
bi/lib/thumb/armv6-m/libc.a
LOAD 
/opt/arminarm/bin/../lib/gcc/arm-none-eabi/4.8.2/../../../../arm-none-ea 
bi/lib/thumb/armv6-m/libm.a

...schon die richtige (oder besser gesagt: die beabsichtigte) Variante 
geladen wurde.

Ich hab mal geschaut, was in der fraglichen Lib steckt und nach 
__aeabi_f2d gesucht.

Im output von ar -t findet sich extendsfdf2.o und da drinnen steckt laut 
output von nm:

extendsfdf2.o:
00000000 T __aeabi_f2d
         U __clzsi2

...und die Fehlermeldung sagt ja nicht, es wäre eine falsche Funktion, 
die einen nicht unterstützten Befehlssatz enthielte, sondern daß er die 
Funktion einfach nicht findet. Ich vermute "T" heißt "ist hier" und "U" 
heißt "uses". Ah, nein, man nm:

           "T"
           "t" The symbol is in the text (code) section.

           "U" The symbol is undefined.

...soll es mich beunruhigen, daß __clzsi2 undefiniert ist? "count 
leading zeros". Und wozu steht in einer Lib, daß sie eine bestimmte 
Funktion nicht definiert? Kann ja eigentlich nur den Sinn haben, 
darauf zu vertrösten, daß sie in einer anderen Lib steht oder daß sie 
sie aus einer anderen Lib bräuchte.

Danke für das "-v", der ausführliche output vom linker ist im Anhang. 
Auch das bringt neue Details (und neue Fragen):

Die mir relevant bzw. verdächtig erscheinenden Zeilen vom output:

> Using built-in specs.
...hat was mit libs zu tun. "built-in"?

> Configured with: [auszugsweise:]
> --enable-multilib
> --with-newlib
> --with-headers=../newlib-1.20.0/newlib/libc/include

...man frage mich bitte nicht, wie er auf die newlib kommt, da spuckt 
mir vielleicht noch was in die Suppe...

> COLLECT_GCC_OPTIONS=[auszugsweise:]
'-c' '-mcpu=cortex-m0' '-mfloat-abi=soft' '-mthumb' '-nostdlib' 
'-mcpu=cortex-m0' '-mfloat-abi=soft' '-mthumb' '-ffunction-sections' 
'-fdata-sections' '-O0' '-Wpedantic' '-v' '-fltrans-output-list=/tmp

...auch die doppelt auftretenden Optionen erregen meinen Argwohn...

von Reinhard M. (reinhard_w)


Lesenswert?

Noch ein Nachtrag zum Befehlssatz: Der Cortex-M0 kann nicht alle thumb 
Befehle, außerdem fehlt eine Integer-Division, die libgcc hätte also 
tatsächlich was zu tun.

von Markus F. (mfro)


Lesenswert?

Reinhard M. schrieb:
> Und wozu steht in einer Lib, daß sie eine bestimmte
> Funktion nicht definiert? Kann ja eigentlich nur den Sinn haben,
> darauf zu vertrösten, daß sie in einer anderen Lib steht oder daß sie
> sie aus einer anderen Lib bräuchte.

Das "U" heißt, daß in der Funktion dieses Symbol referenziert (benutzt) 
wird - der Linker würd's gern dazulinken, wenn er's denn finden täte.

Wenn's also in der Library nicht ist, muß es halt woanders herkommen.

von Reinhard M. (reinhard_w)


Lesenswert?

Das sehe ich, daß __clzsi2 offenbar fehlt, aber warum fehlt sie? Wo 
sollte sie denn sonst sein? Hängt gcclib von noch grundlegenderen 
Basis-Libs ab?

Das mitgelieferte Beispielprojekt (Cortex-M3) kompiliert. Ich habe es 
zunächst nicht gefunden...

Die exakten Unterschiede im Compileraufruf und evtl. die Pfade muß ich 
mir noch anschauen. Es stört ihn auch die Angabe -mcpu=cortex-m0 nicht, 
auch nicht die floating-point Rechnungen, nur das dazugehörige 
register-include file müßte ich natürlich gegen das vom STM32F030R8 
austauschen, wenn ich das Programm hochladen und laufen lassen wollte.

Jedenfalls... irgendwie...

 .text          0x08006ad8       0x3c 
/opt/arminarm/bin/../lib/gcc/arm-none-eabi/4.8.2/thumb/armv6-m/libgcc.a( 
_clzsi2.o)
                0x08006ad8                __clzsi2

...geht es ja doch.

Er hat anscheinend sogar die richtige Lib ausgewählt und in ihr auch 
sein __clzsi2 gefunden. (Ich hoffe, das ist auch wirklich die 
Software-floating-point library, von -mfloat-abi=soft lese ich nichts - 
ich vermute aber schon, ein HW-Dividierer wird ja wohl keine 
Nullstellenzählfunktion benötigen).


------ für's Protokoll -------

Mein Aufruf (immer noch ohne Linkerfile):

arm-none-eabi-gcc -lgcc -lc -lm -nostdlib main.c -mcpu=cortex-m0 
-mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -O0 -flto 
-Wall -pedantic -Wl,-M -v

Was das makefile vom Beispielprogramm aufruft (da gibt es ein linkerfile 
und es wird getrennt kompiliert und gelinkt):

arm-none-eabi-gcc -c -O0 -g -Wall
-I. -mcpu=cortex-m0 -mthumb -I../../common -I../../board 
-I../../common/CMSIS_v3.6.1/Include
-I../../common/CMSIS_v3.6.1/Device/ST/STM32F10x/Include 
-I../../common/STM32F10x_StdPeriph_Driver_v3.6.1/inc
-I../../common/STM32_USB-FS-Device_Driver_v4.0.0/inc -Iinc -Isrc 
-DUSE_STDPERIPH_DRIVER
-DSTM32F10X_HD src/main.c -o build/src/main.o

arm-none-eabi-gcc -T../../common/stm32_f103_gcc.ld -mcpu=cortex-m0 
-mthumb -nostartfiles -Wl,-M
-o build/leds.elf build/src/main.o 
build/../../common/startup_stm32f10x_hd.o
build/../../common/CMSIS_v3.6.1/Device/ST/STM32F10x/Source/Templates/sys 
tem_stm32f10x.o
build/../../common/STM32F10x_StdPeriph_Driver_v3.6.1/src/misc.o
...und noch ein paar Peripherals...

-------------------------------

...also die toolchain funktioniert grundsätzlich und, wie bereits 
befürchtet, habe ich beim Aufruf irgendetwas falsch gemacht, was genau, 
ist noch herauszufinden, zur Auswahl steht ja genug.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Reinhard M. schrieb:
> arm-none-eabi-gcc -lgcc -lc -lm -nostdlib [...]

Und du wundert dich, wenn bestimmte Symbole nicht aufgelöst werden 
können???

von Reinhard M. (reinhard_w)


Lesenswert?

Aha, mit einem selbst hingeschriebenen _exit() geht es nun auch "mit 
ohne -nostdlib." Ja, wäre von Anfang an die bessere Lösung gewesen, ich 
geb's ja zu. Es schien mir damals eine sinnvolle Option zu sein um zu 
verhindern, daß der gcc die auf dem linux installierte libc verwendet 
und ich hab damals noch nicht gewußt, daß die toolchain die Suche nach 
der libc auf die newlib umbiegt und der crosscompiler ohnehin deutlich 
vom system-compiler getrennt ist.

Vor ein paar Tagen wußte ich nicht mal, daß es die libgcc überhaupt gibt 
und Da ich nur die Abende zwischen Arbeitstagen zur Verfügung habe, geht 
es nur langsam voran.

Morgen kümmere ich mich um die CMSIS für mein Target. Vielen Dank an 
alle!

von Reinhard M. (reinhard_w)


Lesenswert?

Erster Eindruck, gestern: Man sieht den Wald vor lauter Bäumen nicht. Es 
gibt cube, stdperiph und snippets, die nicht aufeinander aufbauen. Und 
das mitgelieferte Beispiel. Startupcodes finden sich zu Hauf, 
Linkerfiles sind etwas seltener.

Bis ich mich etwas orientiert habe, wird es wohl wieder etwas länger 
dauern.

Das Beispiel in der arminarm toolchain verwendet stdperiph mit 
USE_STDPERIPH_DRIVER, also werde ich dieses als erstes mit den files für 
die anderen STM32 - Typen ergänzen. Das beiliegende Makefile ist 
angenehm einfach gehalten. Vom Verzeichnisbaum kann man das nicht sagen 
(und durch mein Dazukopieren wird es natürlich auch nicht besser).

Ich bin momentan etwas skeptisch, ob z.B. ein startup.s aus den Snippets 
mit einem Linkerfile aus stdperiph funktionieren wird, zusammen mit dem 
Beispiel (für einen STM-F10 statt meinem ST-F030), das ein C file als 
startupfile hat.

Ich probiere mal herum, eigentlich nur um herauszufinden, was ich wissen 
muß, um eine eigene übersichtlichere und einfachere Verzeichnisstruktur 
für die eigene Entwicklung aufzubauen...

von Holger H. (sachma)


Lesenswert?

Hallo,
ich verwende seit mehr als 2 Jahren das summon toolchain ( 
https://github.com/esden/summon-arm-toolchain.git )  direkt auf dem PI 
u.a. mit einem "alten" LM4F120 Launchpad
und seit dem PI2 auch das https://launchpad.net/gcc-arm-embedded mit dem 
NUCLEO-F401RE
Ich hab hier auch eine kurze Anleitung verfasst, wie man das Ganze 
compiliert.

http://www.messtechniklabor.de/artikel-h0008-launchpad_tm4c12x_mcu_series_und_raspberry_pi_2_model_b.html

Mit viel "Fantasie" kann man auch den Hauseignenen gcc vom PI verwenden, 
man muss dann newlib und gdb neu übersetzen.
---------------------------------------------------------
#auf dem PI - nicht zum Nachmachen empfohlen:)

sudo ln -s /usr/bin/ar /usr/bin/arm-none-eabi-ar
sudo ln -s /usr/bin/as /usr/bin/arm-none-eabi-as
sudo ln -s /usr/bin/ranlib /usr/bin/arm-none-eabi-ranlib
sudo ln -s /usr/bin/cc /usr/bin/arm-none-eabi-cc
sudo ln -s /usr/bin/gcc /usr/bin/arm-none-eabi-gcc
sudo ln -s /usr/bin/readelf /usr/bin/arm-none-eabi-readelf

build newlib:
#CFLAGS_FOR_BUILD=' -msoft-float -mfloat-abi=softfp ';
./configure --target arm-none-eabi --disable-newlib-supplied-syscalls 
--disable-multilib
#TARGET_CFLAGS=' -msoft-float ' make
TARGET_CFLAGS=' -mfloat-abi=softfp ' make

build gdb:
#warning: Can not parse XML memory map; XML support was disabled at 
compile time
#todo enable xml
./configure --target=arm-none-eabi

#test mit einem LM4F120 Launchpad
https://github.com/scompo/stellaris-launchpad-template-gcc

das http://www.ti.com/tool/sw-ek-lm4f120xl liess sich auf einem ur-Pi(A) 
mit 256MB compilieren...
-------------------------------------------------------

Grüße
Holger

: Bearbeitet durch User
von Holger H. (sachma)


Angehängte Dateien:

Lesenswert?

Hi,
hab nochmal alles zusammengefasst(und mit aktueller Software/02/2015 
getestet), wie man den Raspberry Pi gcc für eine
andere ARM Palttform verwenden kann.
Funktioniert aber trotzdem nicht zu empfehlen...
--> Empfehlung siehe mein Posting zuvor.

Grüße
Holger
-----------------------------

#Stellaris Launchpad EK-LM4F120XL mit Raspberry PI default gcc
#Base: 2015-02-16-raspbian-wheezy.img
sudo apt-get update
sudo apt-get upgrade

#my default
sudo apt-get install -y gcc make bc screen ncurses-dev flex bison 
libgmp3-dev libmpfr-dev \
 libmpc-dev autoconf texinfo python2.7-dev python-yaml libexpat1-dev 
libisl-dev

#gcc arm-none-eabi links
sudo ln -s /usr/bin/ar /usr/bin/arm-none-eabi-ar
sudo ln -s /usr/bin/as /usr/bin/arm-none-eabi-as
sudo ln -s /usr/bin/ranlib /usr/bin/arm-none-eabi-ranlib
sudo ln -s /usr/bin/cc /usr/bin/arm-none-eabi-cc
sudo ln -s /usr/bin/gcc /usr/bin/arm-none-eabi-gcc
sudo ln -s /usr/bin/readelf /usr/bin/arm-none-eabi-readelf
sudo ln -s /usr/bin/ld /usr/bin/arm-none-eabi-ld
sudo ln -s /usr/bin/objcopy /usr/bin/arm-none-eabi-objcopy

#newlib
mkdir ~/stellaris

wget 
http://downloads.sourceforge.net/project/devkitpro/sources/newlib/newlib-2.2.0.tar.gz
tar -xf ./newlib-2.2.0.tar.gz
cd ./newlib-2.2.0

./configure --target arm-none-eabi --disable-newlib-supplied-syscalls 
--disable-multilib
TARGET_CFLAGS=' -mfloat-abi=softfp ' make

cd ~/stellaris

#Die Datei SW-EK-LM4F120XL-9453.exe herunterladen und nach ~/stellaris 
kopieren:
#Quelle: http://www.ti.com/tool/sw-ek-lm4f120xl

#SDK-extrahieren (./sdk)
unzip -x -d ./sdk SW-EK-LM4F120XL-9453.exe
cd ./sdk


#####+patch makedefs.patch
--- makedefs  2012-09-06 08:40:38.000000000 +0200
+++ makedefs  2015-05-02 20:16:26.438320141 +0200
@@ -144,17 +144,17 @@
 # Get the location of libgcc.a from the GCC front-end.
 #
 LIBGCC=${shell ${CC} ${CFLAGS} -print-libgcc-file-name}
-
+NEWLIB=/home/pi/stellaris/newlib-2.2.0
 #
 # Get the location of libc.a from the GCC front-end.
 #
-LIBC=${shell ${CC} ${CFLAGS} -print-file-name=libc.a}
-
+#LIBC=${shell ${CC} ${CFLAGS} -print-file-name=libc.a}
+LIBC=${NEWLIB}/arm-none-eabi/newlib/libc.a
 #
 # Get the location of libm.a from the GCC front-end.
 #
-LIBM=${shell ${CC} ${CFLAGS} -print-file-name=libm.a}
-
+#LIBM=${shell ${CC} ${CFLAGS} -print-file-name=libm.a}
+LIBM=${NEWLIB}/arm-none-eabi/newlib/libm.a
 #
 # The command for extracting images from the linked executables.
 #
@@ -245,7 +245,7 @@
         --entry ${ENTRY_${notdir ${@:.axf=}}} 
\
         ${LDFLAGSgcc_${notdir ${@:.axf=}}} 
\
         ${LDFLAGS} -o ${@} $(filter %.o %.a, ${^}) 
\
-        '${LIBM}' '${LIBC}' '${LIBGCC}'
+        '${LIBM}' '${LIBC}'
   @${OBJCOPY} -O binary ${@} ${@:.axf=.bin}
 endif
#####-end makedefs-patch

#makedefs patchen
patch -p0 < makedefs.patch

#sdk compilieren
make
#
cd ./boards/ek-lm4f120xl/blinky

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.