Forum: Compiler & IDEs undefined reference to sprintf


von Johannes (Gast)


Lesenswert?

Hallo,

ich verwende das AT91SAM7S64 Board von Olimex zusammen mit dem 
ARM-Tiny-USB und der mitgelieferten OpenOCD-Yagarto-Toolchain-Eclipse.

Ich möchte den Befehl sprintf() verwenden. Dazu habe ich stdio.h 
eingebunden. Trotzdem kommt die Fehlermeldung: undefined reference to 
sprintf

Woran kann dies liegen?

Hier ein Auszug aus dem Makefile:
1
NAME   = demo_at91sam7_h256_blink_flash
2
3
# variables 
4
CC      = arm-elf-gcc
5
LD      = arm-elf-ld -v -lc
6
AR      = arm-elf-ar
7
AS      = arm-elf-as
8
CP      = arm-elf-objcopy
9
OD    = arm-elf-objdump
10
11
CFLAGS  = -I./ -c -fno-common -O0 -g
12
AFLAGS  = -ahls -mapcs-32 -o crt.o
13
LFLAGS  =  -Map main.map -Tdemo_at91sam7_h256_blink_flash.cmd
14
CPFLAGS = --output-target=binary
15
ODFLAGS  = -x --syms
16
17
OBJECTS = crt.o  main.o timerisr.o timersetup.o isrsupport.o lowlevelinit.o blinker.o
18
19
20
# make target called by Eclipse (Project -> Clean ...)
21
clean:
22
  -rm -f $(OBJECTS) crt.lst main.lst main.out main.bin main.hex main.map main.dmp
23
24
         
25
#make target called by Eclipse  (Project -> Build Project)
26
all:  main.out
27
  @ echo "...copying"
28
  $(CP) $(CPFLAGS) main.out main.bin
29
  $(OD) $(ODFLAGS) main.out > main.dmp
30
31
main.out: $(OBJECTS) demo_at91sam7_h256_blink_flash.cmd 
32
  @ echo "..linking"
33
  $(LD) $(LFLAGS) -o main.out $(OBJECTS) libgcc.a
34
35
crt.o: crt.s
36
  @ echo ".assembling crt.s"
37
  $(AS) $(AFLAGS) crt.s > crt.lst




Und hier ein Auszug aus main.c
1
#include <stdio.h>
2
#include <string.h>
3
#include "AT91SAM7S256.h"
4
#include "board.h"
5
6
7
//  *******************************************************
8
//               Global Variables
9
//  *******************************************************
10
unsigned int  FiqCount = 0;    // global uninitialized variable
11
12
13
//  *******************************************************
14
//                     MAIN
15
//  ******************************************************/
16
int  main (void) {
17
  unsigned long  j;                // loop counter (stack variable)
18
  unsigned long  IdleCount = 0;          // idle loop blink counter (2x)
19
20
  char buff_send[50];
21
  unsigned int status;
22
23
  // Initialize the Atmel AT91SAM7S256 (watchdog, PLL clock, default interrupts, etc.)
24
  // ---------------------------------------------------------------------------------
25
  LowLevelInit();
26
27
28
  // Turn on the peripheral clock for Timer0
29
  // ---------------------------------------
30
31
  // pointer to PMC data structure
32
  volatile AT91PS_PMC  pPMC = AT91C_BASE_PMC;
33
34
35
  sprintf((char*)buff_send, "Status: %i\r\n", status);

Kann mir da jemand helfen?

Schönen Gruß,
Johannes

: Verschoben durch Admin
von Johannes (Gast)


Lesenswert?

Kann es sein, dass dies irgendetwas mit "newlib" zu tun hat? Wenn ja, 
wie löse ich das Problem?

von Mark B. (markbrandis)


Lesenswert?

Kann sein, dass ein #include <stdio.h> nicht ausreicht, sondern dass man 
die für sprintf() benötigte Bibliothek extra hinzulinken muss.

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Es spart unnötige Sucherei, wenn man den Linker (*-ld) und Assembler 
(-as) nicht direkt aufruft. Beide können indirekt vom Compiler-Frontend 
(*-gcc) gerufen werden.

Mit Yagarto kommt meines Wissens ein Beispiel für AT91SAM7S. Von 
atmel.com gibt es ein "Software-Package" zum AT91SAM7S-Eval-Board. Gut 
auch "Building bare-metal ARM Systems with GNU" bei state-machine.com 
(Quantum Leaps). Vielleicht sind noch meine Beispiele hilfreich: 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index_at91.html 
("gamma")

Ansonsten: testweise -lc aus definition LD entfernen und hinter 
($OBJECTS) im LD-Aufruf ergänzen.

von Johannes (Gast)


Lesenswert?

Hallo Thomas,

kannst du mir das genauer beschreiben?
Wie soll es indirekt vom -gcc aufgerufen werden?
Ich habe gerade mehrere Versuche im Makefile gestartet. Aber alle mit 
dem Ergnis, dass irgendein Fehler aufgetreten ist.

Kannst du mir bitte dazu ein Beispiel geben mit dem ich arbeiten kann? 
Ich kenn mich mit den Makefile nicht aus und bin immer sehr zu frieden, 
wenn es so läuft wie es soll und ich nichts ändern muss...

Schönen Gruß,
Johannes

von Rolf Magnus (Gast)


Lesenswert?

Johannes schrieb:

> Wie soll es indirekt vom -gcc aufgerufen werden?

Du benutzt einfach gcc statt ld zum Linken. gcc wiederum ruft dann ld 
auf, übergibt ihm aber zusätzlich zu den Argumenten von dir noch 
weitere, die für das Linken von C-Code notwendig sind.

> Ich habe gerade mehrere Versuche im Makefile gestartet. Aber alle mit
> dem Ergnis, dass irgendein Fehler aufgetreten ist.

Naja, dann hast du wohl irgendwas falsch gemacht. Viel mehr kann man so 
nicht sagen.

von Johannes (Gast)


Lesenswert?

Ich habe jetzt -lc nach OBJECTS gehängt und bekomme jetzt folgende 
Fehlermeldung:
1
GNU ld (GNU Binutils) 2.18
2
arm-elf-ld: region flash is full (main.out section .text)
3
arm-elf-ld: region flash is full (main.out section .text)
4
arm-elf-ld: section .text [00000000 -> 00013d7b] overlaps section .data [00000000 -> 00000837]
5
c:\gccfd\yagarto\bin\../arm-elf/lib\libc.a(lib_a-syscalls.o): In function `_sbrk':
6
C:\msys\1.0\home\yagarto\newlib-build\arm-elf\newlib\libc\sys\arm/../../../../../../newlib-1.16.0/newlib/libc/sys/arm/syscalls.c:506: undefined reference to `end'
7
make: *** [main.out] Error 1
8
make: Target `all' not remade because of errors.

Aber ich werde daraus nicht schlau. Ich habe auf meinem Rechner nirgends 
einen Ordner namens "newlib-1.16.0". Aber anscheinend dann ja doch, wenn 
er den Inhalt einer Datei davon bemängelt.

Servus,
Johannes

von Rolf Magnus (Gast)


Lesenswert?

Johannes schrieb:
> Ich habe jetzt -lc nach OBJECTS gehängt und bekomme jetzt folgende
> Fehlermeldung:

-lc ist einer der nötigen Linker-Parameter, die gcc automatisch für dich 
mit angehängt hätte. Abhängig vom Zielsystem und der Compilerversion 
gibt es aber meist noch einige andere, die notwendig sind.

Johannes schrieb:
> arm-elf-ld: region flash is full (main.out section .text)
> arm-elf-ld: region flash is full (main.out section .text)
> arm-elf-ld: section .text [00000000 -> 00013d7b] overlaps section .data 
[00000000 -> 00000837]

Das klingt aber auch schon mal seltsam. Dein Flash ist voll und deine 
Daten- und Code-Sektion überschneiden sich?

> c:\gccfd\yagarto\bin\../arm-elf/lib\libc.a(lib_a-syscalls.o): In function 
`_sbrk':
> C:\msys\1.0\home\yagarto\newlib-build\arm-elf\newlib\libc\sys\arm/../../ 
../../../../newlib-1.16.0/newlib/libc/sys/arm/syscalls.c:506:  undefined reference 
to `end'

Klingt für mich, als wäre das Linkerskript unvollständig.

> Aber ich werde daraus nicht schlau. Ich habe auf meinem Rechner
> nirgends einen Ordner namens "newlib-1.16.0".

Das dürfte sich eher auf den Rechner beziehen, auf dem diese newlib 
compiliert wurde.

von Johannes (Gast)


Lesenswert?

So, da es anscheinend immer schwieriger wird, bin ich jetzt auf ein 
Beispiel vom Thomas Martin umgestiegen. Und bisher sieht es aus, als 
würde alles funktionieren... Jetzt muss ich nur noch meinen Code dort 
einbauen.
Danke an alle!

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.