Forum: Mikrocontroller und Digitale Elektronik Probleme beim Linken mit arm-none-eabi-gcc (yagarto)


von Obs (Gast)


Lesenswert?

Hallo Community,

ich hab seit heute folgendes Problem beim Linken mit dem 
yagarto-Compiler:
1
 
2
arm-none-eabi-gcc -T ../../cpu/arm//atsam3s4/atsam3s4-flash.ld -L../../cpu/arm//atsam3s4 -march=armv7-m -mcpu=cortex-m3 -mthumb -Wl,-Map=mapfile -nostartfiles   hello-world.co obj_deRFusb-13E00/contiki-main.o contiki-deRFusb-13E00.a -latsam3s4 -o hello-world.deRFusb-13E00
3
c:/yagarto-20121222/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib\libc.a(lib_a-impure.o):(.data+0x0): multiple definition of `_impure_ptr'
4
rm hello-world.co
5
../../cpu/arm//atsam3s4\libatsam3s4.a(flash_stdio.o):(.data+0x428): first defined here
6
c:/yagarto-20121222/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
7
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.20.0/newlib/libc/reent/sbrkr.c:58: undefined reference to `_sbrk'
8
c:/yagarto-20121222/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
9
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.20.0/newlib/libc/reent/writer.c:58: undefined reference to `_write'
10
c:/yagarto-20121222/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
11
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.20.0/newlib/libc/reent/closer.c:53: undefined reference to `_close'
12
c:/yagarto-20121222/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
13
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.20.0/newlib/libc/reent/fstatr.c:62: undefined reference to `_fstat'
14
c:/yagarto-20121222/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
15
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.20.0/newlib/libc/reent/isattyr.c:58: undefined reference to `_isatty'
16
c:/yagarto-20121222/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
17
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.20.0/newlib/libc/reent/lseekr.c:58: undefined reference to `_lseek'
18
c:/yagarto-20121222/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
19
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\reent/../../../../../newlib-1.20.0/newlib/libc/reent/readr.c:58: undefined reference to `_read'
20
collect2.exe: error: ld returned 1 exit status
21
make: *** [hello-world.deRFusb-13E00] Error 1

Ich hatte das Projekt ein paar Tage liegen lassen und als ich das letzte 
Mal kompiliert habe, ging noch alles. Seit heute kommen diese 
Fehlermeldungen. Ich habe eigentlich am Compileraufruf oder an 
Linkerskripten usw. nichts geändert, nur an meinem C-Code. Es scheint ja 
damit anzufangen, dass _inpure_ptr sowohl in libc.a als auch in der 
uC-spezifischen libatsam3s4.a (benutze ATSAM3S4) definiert wird. Ich bin 
mir nicht mal ganz sicher, was in libatsam3s4.a alles definiert ist, ich 
hab das Projekt nur so übernommen und zunächst lief auch alles. 
Witzigerweise liefert eine Google-Suche zu libatsam3s4.a 0 Treffer:D Und 
auch wenn man sich die restlichen Fehlermeldungen ansieht, die auch 
allesamt libc.a betreffen, scheint da ja irgendwo der Fehler zu liegen. 
Brauche ich die libc.a überhaupt oder ist die C-Standardfunktionalität 
schon in libatsam3s4.a enthalten? Wie bewege ich den Linker dazu nicht 
mehr gegen libc.a zu linken? Und wieso hat vorher alles funktioniert und 
jetzt plötzlich nicht mehr? Danke schon mal für die Hilfe.

von Jim M. (turboj)


Lesenswert?

Versuch mal "-nodefaultlibs" oder "-nostdlib".

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


Lesenswert?

Obs schrieb:
> Und auch wenn man sich die restlichen Fehlermeldungen ansieht, die auch
> allesamt libc.a betreffen, scheint da ja irgendwo der Fehler zu liegen.

Die sehen mir eher danach aus, als würdest du irgendwo printf()
aufrufen.  Der Rattenschwanz an undefinierten Systemrufen ist dann
das, was du für das printf() als Basis in deinem Projekt bereitstellen
müsstest, wobei ein Großteil davon einfach nur als stub implementiert
werden kann.  _sbrk() musst du aber vernünftig implementieren, denn
printf braucht ein malloc().

Beispiele dafür gibt's im Netz.

(Die newlib benutzt ein Unix-Modell für die Implementierung.  Obige
Funktionen wären in einem unixoiden Betriebssystem als Syscalls
realisiert.)

von Obs (Gast)


Lesenswert?

Hi, danke für die schnellen Antworten. Ich rufe in der Tat printf auf, 
sogar recht häufig. Aber ich hab eine eigene printf-Implementierung und 
die hat vorher auch ohne Probleme funktioniert. printf wird dazu auf die 
serielle Schnittstelle umgeleitet.

Wenn ich versuche mit "-nodefaultlibs" oder "-nostdlib" zu linken, 
bekomme ich Fehlermeldungen wegen undefinierter Referenzen auf alle 
möglichen anderen Funktionen wie memcpy, strcmp, usw.

von Obs (Gast)


Lesenswert?

Kann es sein, dass der Linker jetzt plötzlich versucht printf aus der 
libc.a zu ziehen statt meine eigene zu verwenden?

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


Lesenswert?

Obs schrieb:
> Aber ich hab eine eigene printf-Implementierung

Das darfst du nicht.

Funktionsnamen aus der Standardbibliothek sind (im hosted mode, das
ist aber die Voreinstellung, wenn du kein -ffreestanding angibst)
tabu.  (Es sind "reservierte Bezeichner", die du in deiner Anwendung
nicht anderweitig belegen darfst.)

Wenn du nicht das printf() aus der Bibliothek nehmen willst (natürlich
lässt sich auch das auf die serielle Schnittstelle lenken, eben indem
man all die genannten Funktionen implementiert), dann nenne es myprintf
oder sowas.

von Obs (Gast)


Lesenswert?

Ach so. Ja jetzt wo ich’s lese kommt es mir bekannt vor, dass man nicht 
einfach Funktionsnamen aus der Standardbibliothek verwenden darf ^^. 
Aber genau genommen ist es auch nicht meine eigene Implementierung von 
printf, sondern die aus der at91lib. Ich verstehe aber immer noch nicht 
wo jetzt das Problem liegt, denn zum einen ging es vorher alles 
problemlos und printf hat auch problemlos funktioniert. Aber ich 
verstehe auch die Fehlermeldungen nicht. Scheinbar ist _inpure_ptr 
sowohl in der atsam3s4.a und in libc.a vorhanden und ich weiß nicht 
warum bzw. warum das jetzt auf einmal en Problem sein soll. Weder 
atsam3s4.a und libc.a wurden angerührt. Und was bedeuten die anderen 
Fehlermeldungen? „newlib-1.20.0/newlib/libc/reent“ klingt irgendwie nach 
Reentrantfunktionalität, aber wo kommt das her und was genau fehlt da 
jetzt bzw. wo liegt das Problem?

von Obs (Gast)


Lesenswert?

Ok, für die, die es interessiert: das Problem habe ich jetzt nach der 
Holzhammermethode gelöst: Einfach zu einer früheren Version 
zurückspringen, bei der das Kompilieren respektive das Linken noch 
funktioniert hat und dann nach und nach die Neuerungen aus der neuen 
Version eingepflegt, bis es irgendwann nicht mehr ging. Jörg lag gar 
nicht so falsch. Aber es lag nicht am printf, sondern an einem Aufruf 
von putchar, dass ich an einigen Stellen als schnelles printf verwendet 
habe. Wenn ich putchar nicht aufrufe, kompiliert und linkt er ohne 
Probleme. Die printf-Aufrufe stören in komischerweise nicht. Auch fputc 
stört ihn nicht. Nur wenn ich versuche putchar zu verwenden, kommen 
dieser seltsamen Fehler. Ich habe mal einen neuen Thread 
(Beitrag "Probleme mit newlib / arm-none-eabi-gcc") dazu aufgemacht.

von Karl Z. (griffin27)


Lesenswert?

ich hab gerade ein ähnliches problem gehabt mit sscanf()
diese funktion ist scheinbar in der stdio.c von Atmel nicht 
implementiert, und daher greift der linker auf die newlib zu.

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.