Forum: Compiler & IDEs printf retarget unter GCC-ARM


von Michael W. (Gast)


Lesenswert?

Hallo zusammen,

ich möchte nur ungern auf mein geliebtes "printf" verzichten, und so 
will ich dieses unter CooCox ARM-GCC zum Leben erwecken.

In einer Keil Umgebung war dazu lediglich die Implementierung von fputc 
erforderlich. Das habe ich gemacht
1
int fputc(int ch, FILE *f){
2
  while (!USART_GetFlagStatus(USART3, USART_FLAG_TXE));
3
  USART_SendData(USART3, (uint16_t) ch);
4
  return ch;
5
}

und nun konnte ich zunächst nicht linken:
1
       [cc] sbrkr.c:(.text+0xc): undefined reference to `_sbrk'
2
       [cc] c:/program files/arm-none-eabi-gcc-4_6/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/armv7e-m\libg.a(lib_a-writer.o): In function `_write_r':
3
       [cc] writer.c:(.text+0x10): undefined reference to `_write'
4
...
5
...

Hier fehlten offenbar Funktionsimplementierungen. Ich habe diese unter C 
Library (syscallc.c) bei den Komponenten gefunden. Jetzt linkt es.
Beschreibung: C Library: Implement the minimal functionality required to 
allow newlib to link
The component implement the minimal functionality required to allow libc 
to link. When you call some functions in the C subroutine library, but 
compile error occurs, you need to check this component and then try.

Erste Frage
Was heißt das nun? Was hat es mit "newlib" auf sich? Was ist "newlib" 
?Ich würde gerne verstehen, was da passiert...

Gleichzeitig habe ich dann auch gesehen, dass es eine schlanke 
Implementierung der printf Funktionen gibt unter Retarget printf: 
Implementation of printf(), sprintf() to reduce memory footprint 
(printf.c)

Zweite Frage
 was soll man nun nehmen? In welcher Library ist das Original printf 
denn drin (ich dachte die ist unter libc...), und wieso kann printf dann 
einfach überladen werden? Für welches von den beiden (das Original bzw. 
die neue Implementierung) entscheidet sich der Linker denn?

Dritte Frage

Und dann gibt es noch in der Configuration/Linker die Auswahl:

- not use C Library  --> keine Library (gibt es dann eine default lib 
???)
- use Base C Library  --> -lc
- retarget   --> -lnosys

Was ist in diese libnosys drin?

Ich muss zugeben, hier einigermaßen verwirrt und planlos zu sein. Wann 
verwende ich denn keine, die Base C Library und wann die retarget?

Ich sehe keinen roten Faden mehr, wie man hier korrekt vorgeht. Kann mir 
jemand auf die Sprünge helfen, oder sagen, wo man das alles nachlesen 
kann?

Danke,
Michael

von user (Gast)


Lesenswert?


von Michael W. (Gast)


Lesenswert?

Meine brennendste Frage:

wieso kann man printf overloaden? Es muss doch in einer Standard Library 
drin sein. Abgesehen von meinem "Nicht-Verständnis" was ich hier 
eigentlich tue funktioniert das retarget printf aber 
ausgezeichnet...Vielleicht sol man das nicht hinterfragen und einfach 
verwenden... ;-)

von Karl H. (kbuchegg)


Lesenswert?

Michael W. schrieb:
> Meine brennendste Frage:
>
> wieso kann man printf overloaden?

Das folgt aus der Art und Weise wie dieser spezielle Linker offenbar 
arbeiten

> Es muss doch in einer Standard Library
> drin sein.

Ist es auch.

Aber wenn du dem Linker selbst eine printf Implementierung vorsetzt, 
noch ehe er die Standard Library gesehen hat, dann sucht er sich in der 
Standard-Library das printf gar nicht mehr.

Das ganze ist also einfach nur eine Frage, in welcher Reihenfolge der 
Linker die verfügbaren Quellen untersucht. Und die Standard-Library 
kommt zum Schluss und muss alle Funktionen liefern, die in den vorher 
untersuchten Files (seien es Object-Files oder Libraries) nicht 
vorkamen.

von Michael W. (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
...
> Das ganze ist also einfach nur eine Frage, in welcher Reihenfolge der
> Linker die verfügbaren Quellen untersucht. Und die Standard-Library
> kommt zum Schluss und muss alle Funktionen liefern, die in den vorher
> untersuchten Files (seien es Object-Files oder Libraries) nicht
> vorkamen.

Aha, danke, das war mir bisher nicht so klar.

von Michael W. (Gast)


Lesenswert?

Eine Frage noch:

Wo sucht der ARM-GCC Linker nach Libraries? Was ist das 
Standardverzeichnis, bzw. wo ist dieses definiert?

Beispiel:

1)

Gebe ich bei den Linker optionen an: "base Library", dann schaut die 
Linker Zeile so aus:
-mcpu=cortex-m4; -mthumb; -g; -nostartfiles; -Map=uart_test.map; -O0; 
--gc-sections; -lm; -lgcc; -lc; -L${linkdir}; 
-T${linkdir}/arm-gcc-link.ld;

Was bedeutet ${linkdir} - eine ENV Variable gibt es nicht, die so heißt.

2)

Gebe ich hingegen an

"not use C Library", dann wird daraus

-mcpu=cortex-m4; -mthumb; -g; -nostartfiles; -Map=uart_test.map; -O0; 
--gc-sections; -L${linkdir}; -T${linkdir}/arm-gcc-link.ld;

Hier wird keine Library angegeben, trotzdem findet der Linker z.B 
printf. Wieso? Gibt es da eine Default Library, die immer dazugelinkt 
wird?

Danke!

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.