Linker Problem wegen _sbrk() trotz newlib_stubs.c/mini_cpp.cpp

Gast #2125908
Lesenswert?

Hallo,
ich kämpfe gerade mit dem Problem, mit CodeSourcery 4.5.1 für den 
STM32F103RE ein C++ ein kleines Programm zu erstellen.
Die Compilation des Programms (blinkende LED mit einem new Statement, um 
den g++ zu "provozieren") klappt, beim Linken gibt es die in vielen 
Threads beschriebenen Probleme mit der newlib (u.a. fehlende _sbrk()).

Deshalb habe ich zwei Dateien dazugelinkt: newlib_stubs.c (für _sbrk()) 
und mini_cpp.cpp ( new und delete Ersatz, der malloc und free direkt 
aufruft).
Quellen:
https://sites.google.com/site/stm32discovery/open-source-development-with-the-stm32-discovery/getting-newlib-to-work-with-stm32-and-code-sourcery-lite-eabi
http://svnmios.midibox.org/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fprogramming_models%2Ftraditional%2Fmini_cpp.cpp&rev=846&sc=1

Allerdings, das Problem bleibt. Es ist, als ob er Linker die Dateien 
glatt ignoriert. Hier der Aufruf:
1
 arm-none-eabi-g++ -v -o elf/main.elf obj/main.o obj/system_stm32f10x.o  
2
obj/startup_stm32f10x.o obj/stm32f10x_rcc.o  obj/stm32f10x_gpio.o  obj/newlib_stubs.o obj/core_cm3.o obj/mini_cpp.o -TSTM32F10x_512k_64.ld 
3
-LC:/Entwicklung/CodeSourcery/arm-none-eabi/lib/thumb2 
4
-LC:/Entwicklung/CodeSourcery/lib/gcc/arm-none-eabi/4.5.1/thumb2 -nostartfiles -Wl--cref,--gc-sections
Die Ausgabe des Linkers ist im Attachment. Hat jemand eine Idee?

Grüße
schnack
Angehängte Dateien:
Gast #2127060
Lesenswert?

Hallo Martin,
den Link auf Deine Seite habe ich (natürlich :-) schon in anderen 
Threads gefunden und - nach bestem Wissen und Gewissen - genutzt. Die 
newlib_stubs.c entspricht ja Deiner syscalls.c - soweit ich das sehen 
kann. Das Verständnis Deines Makefile erfordert allerdings etwas 
solidere Erfahrung, als ich sie derzeit mitbringe. Deshalb bin ich mir 
auch nicht sicher, ob ich beim "Übertragen" der Linker Optionen etwas 
wichtiges übersehen habe.

Ich bin schon am Grübeln, ob ich die Nutzung der newlib mit den Stubs 
gleich ganz sein lasse und statt malloc/free aus der Lib eine eigene 
"primitiv"-Allokation aufmache. Denn im Grunde will ich ja nur in der 
Lage sein, Speicher zur Laufzeit zu allokieren, um aus 
Konfigurationsdaten Objekte zu erzeugen, die dann aber ständig erhalten 
bleiben. Eine Freigabe per free() muß noch nicht einmal unterstützt 
werden. Ich frage mich nur, ob ich damit (für meine Kenntnisse) ein zu 
großes großes Fass aufmache.., habe aber dennoch schon mal 
http://developers.stf12.net/cpp-demo/gcc-linker-script-and-stm32-a-tutorial 
angelesen.

Ich mache mich jetzt mal an den Vorschlag, die .map Datei zu erzeugen.

Grüße
schnack
Gast #2127415
Lesenswert?

Hallo Klaus,
an der Signatur hat es anscheinend nicht gelegen. Ich habe sie etwas 
modifizieren müssen (size -> incr):
1
void* _sbrk_r(struct _reent* r, ptrdiff_t incr) {
2
    //caddr_t _sbrk(int incr) {
3

4
    extern char _ebss; // Defined by the linker
5
    static char *heap_end;
6
    char *prev_heap_end;
7
[..]

Leider hat dies nichts geändert.. schade - aber danke!
Grüße
schnack
Gast #2127464
Lesenswert?

Hi,
ich habe noch einmal nachgeschaut. Der Linker-Fehler ist:

1
C:/Entwicklung/CodeSourcery/arm-none-eabi/lib/thumb2\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
2
sbrkr.c:(.text+0x12): undefined reference to `_sbrk'

In der newlib gibt es die Datei sbrkr.c mit dem Abschnitt:
1
void *
2
_DEFUN (_sbrk_r, (ptr, incr),
3
     struct _reent *ptr _AND
4
     ptrdiff_t incr)
5
{
6
  char *ret;
7
  void *_sbrk(ptrdiff_t);
8

9
  errno = 0;
10
  if ((ret = (char *)(_sbrk (incr))) == (void *) -1 && errno != 0)
11
    ptr->_errno = errno;
12
  return ret;
13
}

Demnach war die alte Signatur wohl doch passend, hm.
Grüße
schnack
Gast #2128712
Lesenswert?

Hi,
inzwischen habe ich das Problem dadurch "umgangen", daß ich nun 
tatsächlich einen ersten Wurf gebaut habe, um new() minimal zu 
implementieren.
Dazu habe ich einen kleinen Teil aus der core_cm3.c und dem Code für 
_sbrk() verwendet (siehe Anhang: mini_cpp.cpp).
Das Linken damit klappt. Ein Code wie:
1
int main(void)
2
{
3
  int* g1 = new int;
4
  *g1 = 34;
5

6
  int* g2 = new int;
7
  *g2 = 898;
8
[..]
läßt sich damit korrekt compilieren und ausführen (im Debugger geprüft). 
Weitere Tests müssen natürlich folgen.

Irritierend:
1. In Eclipse Galileo läßt sich mit dem Debugger arm-none-eabi-gdb.exe 
(Version 4.5.1) mit dem JLink EDU nicht arbeiten (Fehlermeldungen), nach 
dem Übergang auf die CodeSourcery Version 4.4.1 klappte das durchaus 
(bei absolut gleichem Setup des HW Debugging).
2. Wenn ich den arm-none-eabi-g++/gcc zum Linken einsetze (Version 
4.4.1) , klappt das Linken, wie  beschrieben. Ein Linken mit 
arm-none-eabi-ld klappt auf spektakuäre Weise nicht : Der Linker 
erzeugt keine elf-Datei, liefert auch keinen Fehler- er macht einfach 
nichts.. (??). Es sieht dann so aus - der Fehler wird erst im zweiten 
Befehl offenbar:
1
make all 
2
..linking
3
arm-none-eabi-ld -v -o elf/main.elf  obj/main.o obj/system_stm32f10x.o  obj/startup_stm32f10x.o obj/stm32f10x_rcc.o  obj/stm32f10x_gpio.o obj/mini_cpp.o -TSTM32F10x_512k_64.ld -nostartfiles     
4
GNU ld (Sourcery G++ Lite 2010q1-188) 2.19.51.20090709
5
arm-none-eabi-objdump -S elf/main.elf > elf/main.lst
6
c:\Entwicklung\CodeSourcery\bin\arm-none-eabi-objdump.exe: 'elf/main.elf': No such file
7
make: *** [target] Error

Grüße
schnack
Angehängte Dateien:
Gast #2128756
Lesenswert?

> Es ist auch unüblich, den Linker direkt aufzurufen
Ok.
> Wenn du direkt den gcc mit ld tauscht ohne die Optionen anzupassen, dann
> geht das schief.
Nun ja. Ich kann ja schlecht das Gegenteil behaupten. Allerdings 
verstehe ich nicht, wieso der Linker still und leise abschmiert. Das ist 
doch kein Problem der Optionen..?
Grüße
schnack

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren