Using Newlib in ARM bare metal programs

Really great and very detailed series of artistic work on ARM and emulation.

Using Newlib in ARM bare metal programs

Posted by Balau on Dec 16 of 2010.

When dealing with embedded software, I often find useful to have the standard C functions we all learn during our first programming course: printf, malloc, getchar, strncpy, …
A common way to have them is using Newlib. Newlib is an implementation of the standard C library that is specifically thought to run somewhere with low resources and undefined hardware. The idea of Newlib is to implement the hardware-independent parts of the standard C library and rely on few low-level system calls that must be implemented with the target hardware in mind.

I compiled Newlib with the CodeSourcery ARM compiler for bare-metal targets: Sourcery G++ Lite 2010.09-51. Once the toolchain is installed, the commands I used to download compile Newlib are:


$ wget ftp://sources.redhat.com/pub/newlib/newlib-1.18.0.tar.gz
$ tar xzf newlib-1.18.0.tar.gz
$ cd newlib-1.18.0/
$ ./configure --target arm-none-eabi --disable-newlib-supplied-syscalls<
$ make
$ cd ..

The “--disable-newlib-supplied-syscalls” option is necessary because otherwise Newlib compiles some pre-defined libraries for ARM that are useful in conjunction with debug features such as the RDI monitor. Many different outputs are compiled inside the arm-none-eabi subdirectory, but in particular the “libc.a” archive in the newlib directory is the one I use.

As an example, I want to compile the following “test.c” program:


#include
#include
extern char *heap_end; /* Defined in syscalls.c */

void c_entry() {
char c;
char *ptr = NULL;
size_t alloc_size = 1;
do {
c =getchar();
printf(“%d: %c\n”, c, c);

ptr = realloc(ptr, alloc_size);
if(ptr == NULL) {
puts(“Out of memory!\nProgram halting.”);
for(;;);
} else {
printf(“new alloc of %d bytes at address 0x%X\n”, alloc_size, (unsigned int)ptr);
alloc_size <<= 1;
printf("Heap end = 0x%X\n", (unsigned int)heap_end);
}
} while (1);
}

The program uses standard input/output functions and allocates more and more memory with realloc, printing some information to understand what’s going on. The idea is to use the UART serial port as the input/output, and monitor how the memory is managed. The heap_end variable is something that I will implement and use later to manage the memory allocation.

The program needs at least some basic starting code “startup.s” that I borrow from a previous example of mine about the hello word bare metal qemu post:


LDR sp, =stack_top
BL c_entry
B .

And the linker script “test.ld” again is a modified version from the hello word bare metal qemu post:


SECTIONS
{
. = 0x10000;
.ro : {
startup.o (.text)
*(.text)
*(.rodata)
}
.rw : {
*(.data)
*(.bss)
*(COMMON)
}
. = ALIGN(8);
heap_low = .; /* for _sbrk */
. = . + 0x10000; /* 64kB of heap memory */
heap_top = .; /* for _sbrk */
. = . + 0x10000; /* 64kB of stack memory */
stack_top = .; /* for startup.s */
}

more

more


and more
more

Freedom Embedded

When dealing with embedded software, I often find useful to have the standard C functions we all learn during our first programming course: printf, malloc, getchar, strncpy, …
A common way to have them is using Newlib. Newlib is an implementation of the standard C library that is specifically thought to run somewhere with low resources and undefined hardware. The idea of Newlib is to implement the hardware-independent parts of the standard C library and rely on few low-level system calls that must be implemented with the target hardware in mind.

I compiled Newlib with the CodeSourcery ARM compiler for bare-metal targets: Sourcery G++ Lite 2010.09-51. Once the toolchain is installed, the commands I used to download compile Newlib are:

The “--disable-newlib-supplied-syscalls” option is necessary because otherwise Newlib compiles some pre-defined libraries for ARM that are useful in conjunction with debug features…

View original post 515 more words

Advertisements

About minghuasweblog

a long time coder
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s