EmbDev.net

Forum: ARM programming with GCC/GNU tools arm-elf-gcc _sbrk errors


von Fairuz I. (mdpai)


Rate this post
useful
not useful
Hi,
I tried to compile an empty main function (just to test the toolchain) 
but i got these errors.

fairuz@ubuntu:~/test$ arm-elf-gcc -mcpu=arm7tdmi-s test.c
/opt/gnuarm/lib/gcc/arm-elf/4.4.1/../../../../arm-elf/lib/libc.a(lib_a-e 
xit.o):  In function `exit':
/home/fairuz/build-newlib/arm-elf/newlib/libc/stdlib/../../../../../newl 
ib-1.17.0/newlib/libc/stdlib/exit.c:65:  undefined reference to `_exit'
/opt/gnuarm/lib/gcc/arm-elf/4.4.1/../../../../arm-elf/lib/libc.a(lib_a-s 
brkr.o):  In function `_sbrk_r':
/home/fairuz/build-newlib/arm-elf/newlib/libc/reent/../../../../../newli 
b-1.17.0/newlib/libc/reent/sbrkr.c:60:  undefined reference to `_sbrk'
collect2: ld returned 1 exit status


This is my main

void main (void){}

I compile my own toolchain using gcc 4.4.1, binutils 2.19.1, newlib 
1.17, GDB 6.8, insight 6.8-1

I've read somewhere that this kind of error is caused by newlib syscall 
and they suggest to add  --disable-newlib-supplied-syscalls option when 
compiling newlib. I've did this but I still got the same errors.

Anyone have some ideas on this matter?

Thanks for your time,

Kind  regards,
Fairuz

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Fairuz Ismail wrote:
> Hi,
> I tried to compile an empty main function (just to test the toolchain)
> but i got these errors.
>
> fairuz@ubuntu:~/test$ arm-elf-gcc -mcpu=arm7tdmi-s test.c

So far I have never used "one-stop" compile and link with small 
controllers but separted compililation and linking. As far as I know the 
standard startup-code gets linked and the linker uses the default 
linker-scipt if the compiler is called like shown.

> /opt/gnuarm/lib/gcc/arm-elf/4.4.1/../../../../arm-elf/lib/libc.a(lib_a-e xit.o):
> In function `exit':
> /home/fairuz/build-newlib/arm-elf/newlib/libc/stdlib/../../../../../newl 
ib-1.17.0/newlib/libc/stdlib/exit.c:65:
> undefined reference to `_exit'
> /opt/gnuarm/lib/gcc/arm-elf/4.4.1/../../../../arm-elf/lib/libc.a(lib_a-s 
brkr.o):
> In function `_sbrk_r':
> /home/fairuz/build-newlib/arm-elf/newlib/libc/reent/../../../../../newli 
b-1.17.0/newlib/libc/reent/sbrkr.c:60:
> undefined reference to `_sbrk'
> collect2: ld returned 1 exit status

Take a look into the source-code of exit in the newlib source-tree. I 
expect this calls _exit(). _sbrk is a syscall, see the 
newlib-documentation (somewhere at the end). It's usually the task of 
the developer to provide this function. You may try to provide your own 
_exit() function in the source. Interface can be seen in the 
newlib-source-code (void exit(int); IRC). This will make the linker 
"happy" but will be just a little step further.

> This is my main
>
> void main (void){}

Try at least with
void main(void) { while(1) {} }

Also try with command-line option -nostartfiles.

>
> I compile my own toolchain using gcc 4.4.1, binutils 2.19.1, newlib
> 1.17, GDB 6.8, insight 6.8-1
>
> I've read somewhere that this kind of error is caused by newlib syscall
> and they suggest to add  --disable-newlib-supplied-syscalls option when
> compiling newlib. I've did this but I still got the same errors.

When using this option you have to provide the syscalls yourself. sbrk 
is such a syscall.

> Anyone have some ideas on this matter?

If you do not have to build the toolchain on your own I suggest to use a 
ready-mady toolchain. Codesourcery also provides it's G++ package 
(arm-none-eabi target) for Linux hosts. The lite version is free. This 
will save some work and time.

Anyway, I suggest to read a little bit about startup-code and 
linker-scripts. Search the net for examples made for the GNU-toolchain 
and your controller (or at least a controller with the same ARM core). 
These examples usually include startup-code, linker-script and makefile. 
Even if you do not want to use make/makefiles you can see the needed 
steps to build an applicaiton from looking at the output of "make all".

von Günter F. (Company: Atmel) (gfuchs)


Rate this post
useful
not useful
I tried to post an answer to a similar question on www.at91.com but have 
problems with submitting to their forum. My answer is similar to the 
ones in this thread, but I thought I go a little further and cover also 
the next step which is debugging. I figure once somebody can build with 
the Yagarto toolchain, she wants to start now debugging. So the the few 
paragraphs below cover briefly how to create an Eclipse managed project 
and how to debug under Eclipse using a SAM-ICE on an AT91SAM9 target.

The linker complains about unsatisfied references to functions that are 
called from Yagarto's newlib system library (version 1.18). You have to 
supply these functions in another module that you have to make part of 
the project. Yagarto provides such a module at 
http://www.yagarto.de/download/yagarto/syscalls.c. Yagarto's library 
takes up quite some code space. For instance, the same TWI project (my 
own based on the at91sam9m10-ek-softpack-1.9 example) is about 13 kB in 
size when using Keil's library version but 50 kB using Yagarto's 
library. (I think Keil's equivalent to Yagarto's syscalls.c is 
<softpack-1.9 Keil example folder>at91lib/utility/retarget.c.) The 
syscalls.c module contains mainly stubbed functions. Their "flesh" is 
taken out being surrounded by "#if 0". If you like to have trace 
functionality (dbgu.c in Atmel AT91 library) via a USART  you have to 
bring this code to life, for instance for _write_r():
1
int _write_r (struct _reent *r, int file, char * ptr, int len)
2
{
3
  int index;
4
5
  // GF: Re-entrancy structure is not used!
6
  for (index = 0; index < len; index++)
7
  {
8
    if (ptr[index] == '\n')
9
      DBGU_PutChar('\r');
10
11
    DBGU_PutChar(ptr[index]);
12
  }
13
14
  return len;
15
}

What you need to have installed:

- Yagarto (www.yagarto.de)

- Eclipse with CDT (www.eclipse.org)

- GNU ARM plugin (add to Eclipse->Help->Software Updates 
http://gnuarmeclipse.sourceforge.net/updates)

- JTAG device and driver, and gdb server (I am working with a SAM-ICE 
from Segger and its gdb server, www.segger.com.)



How to create an Eclipse managed project using Yagarto:

- Select "New->C Project" from the Eclipse "File" menu. A window pops up 
in which you can select what kind of project you like to create.

- Select Yagarto toolchain from the right pane (titled "Toolchains") 
inside this popup window.

- Select "ARM Cross Target Application->Empty Project" from the left 
pane (titled "Project type") inside this window.

- Enter a name into the "Project name" edit box.

- Press "Next" button. The popup window changes to "Select 
Configurations".

- You can leave the "Debug" and "Release" configuration selected or 
deselect one of them. One step later you can manage configurations in 
the project properties window.

- Press the "Finish" button. The popup window closes and the created 
project is added to the "Project Explorer" panel. Right now it only 
contains Yagarto includes.

- Add your project files by right-clicking on your project name in the 
"Project Explorer" panel and selecting "Import". As an exercise you 
could choose one of the AT91 examples that come with the softpack. By 
the way, "Import" copies the files into your project folder, but you can 
also just point to files and / or folders by selecting "New->File" or 
"New->Folder" instead of "Import". In the resulting popup window "New 
..." press the "Advanced" button. This shows you a checkbox labeled 
"Link to the folder / file in the file system" where you can point to 
your source folder / files.

- Configure your project by right-clicking on it and selecting 
"Properties". A "Properties <project name>" window pops up. I am not 
going into all the details but only the ones that relate to the ARM 
Eclipse plugin.

- Expand "C/C++ Build" in the left pane and select "Settings".

- Under the "Tool Settings" tab above the right frame click on "Target 
Processor" and select your target processor from the "Processor" 
drop-down list on the right.

- If you are not yet familiar with choosing all the settings go through 
every entry ("Debugging", "Additional Tools", etc.) and tabs, try to 
understand them, and select them as needed. Important for instance are 
include folders ("Directories" entry) and compilation switches 
("Preprocessor" entry).  The AT91 softpack comes with GNU makefile 
examples. You can look at them and choose the Eclipse project settings 
according to these make files.

- Finally you are ready to build your project. Select Project->Build 
Project from the Eclipse menu. The output of the compiler is displayed 
in the Console window usually docked at the bottom of the Eclipse main 
window. There you could compare the output of your project managed by 
Eclipse with the output generated by a makefile and check whether you 
missed any compiler flags or modules.



How to configure the debugger:

- Add the gdb server to the list of external tools: Select Run->External 
Tools->External Tools Configurations. Enter an identifying name, the 
path and executable filename, and the working directory into the 
appropriate fields.

- Open the "Debug Configurations" window by selecting Run->Debug 
Configurations.

- Under the "Main" tab give this debug configuration a name ("Name"), 
browse to your project ("Project"), and select the binary ("C/C++ 
Application"), commonly a .elf file.

- Under the "Debugger" tab enter the gdb executable ("GDB Command"), in 
my case C:\yagarto\bin\arm-none-eabi-gdb.exe. "Command Set" is 
"Standard". "Protocol Version" is "mi". Check the "Use remote target" 
checkbox. "JTAG Device" is "Generic". "Host name or IP address" is 
"localhost ". "Port number" for the SAM-ICE is 2331.

- Under the "Startup" tab uncheck all boxes and enter the following 
three lines under "Initialization Commands":

monitor reset
source 
C:\Projects\AVR32workspace\SAM9M10_Yagarto\resources\at91sam9m10-ek-ddra 
m.gdb
load

The entry in the second line "source..." is what I am using. Atmel 
provides such gdb initialization files ("<example 
folder>/resources/gdb/*.gdb") with their examples that use the GNU ARM 
toolchain. If you like to stop at main instead of at the first startup 
instruction enter "continue" under "Run Commands", check the "Set 
breakpoint at:" box, and enter "main" in its field.

- Under the "Source" tab make sure that your project configuration is 
listed. After you have started a debug session and Eclipse cannot find 
the source an incorrect entry might be the cause. To fix this error 
delete the old entry and add the correct one by browsing to it.

- The "Common" tab you can leave untouched.

- Press the "Close" button and our Eclipse debugger should be ready to 
fly!



How to start a debug session:

- Start the GDB server by selecting Run->External Tools-><your gdb 
server>. In my case, the Segger gdb server window comes up. Of course 
you want to have the ICE and the target connected and powered up at this 
point.

- Select Run->Debug and, voila, the debug script in "source ... *.dbg" 
should start communicating with the gdb server. The Eclipse console 
shows what the debug scripts echoes, in my case how it initializes 
DDRAM. This is done after few seconds, and Eclipse switches to the Debug 
View allowing you to admire your work.

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
The message includes valuable information. Please concider to create a 
page in the Wikki (menu-item Articles the the left).

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.