www.mikrocontroller.net

Mikrocontroller.net Forum WinARM / Yagarto / ARM-GCC > Linker error, undefined reference to `_sbrk'

Posted by Jerry Milner (jrmymllr)
on 06.06.2008 03:23
I'm trying to compile an MP3 decoder (Helix) with CodeSourcery for ARM
Cortex-M3, and can't shake this error:

arm-none-eabi/lib/thumb2\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text+0xc): undefined reference to `_sbrk'
collect2: ld returned 1 exit status


I've spent hours searching the Internet for info on the error, and hours
fiddling with things trying to fix it.  I can compile a simple LED blink
program.  I believe this error is related to "syscall", but I don't
understand what I need to do to fix it.  Wouldn't this be handled by the
compiler?  If not, would it be possible that the micro vendor (Luminary)
provides a library with the missing piece?  I'd gladly read a small book
to resolve this problem, but don't know what or where to look for it.
Posted by Martin Thomas (mthomas)
on 06.06.2008 16:18
Jerry Milner wrote:
> I'm trying to compile an MP3 decoder (Helix) with CodeSourcery for ARM
> Cortex-M3, and can't shake this error:
> 
> arm-none-eabi/lib/thumb2\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
> sbrkr.c:(.text+0xc): undefined reference to `_sbrk'
> collect2: ld returned 1 exit status
> 
> 
> I've spent hours searching the Internet for info on the error, and hours
> fiddling with things trying to fix it.  I can compile a simple LED blink
> program.  I believe this error is related to "syscall", but I don't
> understand what I need to do to fix it.  

The fix is to provide the requested function _sbrk.

> Wouldn't this be handled by the compiler? 

No, it's not related to the compiler but to the libc (=newlib). I expect 
the MP3-decoder source from the Helix community uses malloc. It seem 
that in the CS newlib configuration malloc calls the reentrant version 
of _sbrk_r which is already in libc.a and _sbrk_r calls _sbrk which has 
to be provided.

> If not, would it be possible that the micro vendor (Luminary)
> provides a library with the missing piece?  

Sure, they could add this to the driver-library. But it's not that 
difficult to add it yourself.

> I'd gladly read a small book to resolve this problem, but don't know 
> what or where to look for it.

(1) I expect you are using the linker-script form the Luminary 
Driver-Library (standalone.ld). Modify this script a little bit:

[...]
.bss :
{
  _bss = .;
  *(.bss*)
  *(COMMON)
  _ebss = .;
  . = ALIGN (8);
  _end = .;
} > SRAM

PROVIDE(__HEAP_START = _end );
[...]

(2) create a file syscalls.c and add the following code:

/* based on a example-code from Keil for CS G++ */

/* for caddr_t (typedef char * caddr_t;) */
#include <sys/types.h>

extern int  __HEAP_START;

caddr_t _sbrk ( int incr )
{
  static unsigned char *heap = NULL;
  unsigned char *prev_heap;

  if (heap == NULL) {
    heap = (unsigned char *)&__HEAP_START;
  }
  prev_heap = heap;
  /* check removed to show basic approach */

  heap += incr;

  return (caddr_t) prev_heap;
}

(3) make sure the file is compiled and the object-code from it gets 
linked

This should get you started (not tested here). You can add additional 
"out of heap-space" checks later if needed.

Hope this helps.

EDIT: added include
Posted by Jerry Milner (jrmymllr)
on 07.06.2008 01:52
Martin Thomas wrote:

> This should get you started (not tested here). You can add additional 
> "out of heap-space" checks later if needed.
> 
> Hope this helps.
> 
> EDIT: added include


Thank you!  I initially tried to get it to compile, but that was without 
the include.  I didn't spend much extra time on it until now.  It's 
compiling....now I have a place to start.