EmbDev.net

Forum: ARM programming with GCC/GNU tools code size with c libs?!


von jtarb (Guest)


Rate this post
useful
not useful
Im working with a LPC2131, and gnuARM 3.4.3 on linux.

Im a newbie to LPC, but I managed to figure out enough about startup
code and linker scripts to get some simple code to build and work. So
next I decided to try linking in some standard C lib stuff. First I
tried memcpy() and that only added a few K to my binary. Then I tried
sprintf(). Binary size went up to about 170k! (linking with -lc -lgcc)

So I searched the web and found out about newlib-lpc. I figured maybe
this is a size optimized version of the stdlib for LPCs...? I tried it
and finally I managed to get it to link. My binary is still about 32k.
Too big for a LPC2131.

Is this right? Is the lib code just that big? I can certainly write my
own sprintf(), but I would like to have math.h and floating point
emulation.

von Martin Thomas (Guest)


Rate this post
useful
not useful
jtarb wrote:
> Im working with a LPC2131, and gnuARM 3.4.3 on linux.
>
> Im a newbie to LPC, but I managed to figure out enough about startup
> code and linker scripts to get some simple code to build and work. So
> next I decided to try linking in some standard C lib stuff. First I
> tried memcpy() and that only added a few K to my binary. Then I tried
> sprintf(). Binary size went up to about 170k! (linking with -lc -lgcc)
>
> So I searched the web and found out about newlib-lpc. I figured maybe
> this is a size optimized version of the stdlib for LPCs...? I tried it
> and finally I managed to get it to link. My binary is still about 32k.
> Too big for a LPC2131.
>
> Is this right? Is the lib code just that big? I can certainly write my
> own sprintf(), but I would like to have math.h and floating point
> emulation.

Although the sprintf-function results in a high increase of code-size
170k is very much. I don't remember the exact number but it should be
around 30kB. If you want floating-point support siprint could be used if
you separate the result values to integers "manualy". There are other
stdio-like-libraries which I have not tried myself i.e. search for
"trio".

newlib-lpc is not a "stdlib" for LPC. It's basicly a collection of
syscalls to interface the newlib with the LPC hardware and some extras
like buffered UART-drivers. I wonder why the linking with the newlib-lpc
reduced the code-size but have not tried it myself.

Martin Thomas

von jtarb (Guest)


Rate this post
useful
not useful
> 170k is very much. I don't remember the exact number but it should be
> around 30kB. If you want floating-point support siprint could be used if
> you separate the result values to integers "manualy". There are other
> stdio-like-libraries which I have not tried myself i.e. search for
> "trio".
>
> newlib-lpc is not a "stdlib" for LPC. It's basicly a collection of
> syscalls to interface the newlib with the LPC hardware and some extras
> like buffered UART-drivers. I wonder why the linking with the newlib-lpc
> reduced the code-size but have not tried it myself.
>

I see. Yes im not sure where the 170k came from, but now I consistently
get about 33k total program size. I downloaded WinARM and tried a build
with that also. Under GNUARM 3.4.3 on linux i can just link with -lc
-lgcc and there is no complaint. I get a complete build... but its just
too big.

Under WinARM 4.1.0 I get these unresolved references (see end of
message). So is that what newlib-lpc does? Provides those functions? I
could just create my own stub functions for these then I could link and
i wouldnt need newlib-lpc right? But there is still a question as to
what my final code size might be.

thanks!


Z:\ARMLPC\Example>arm-elf-ld -nostartfiles -T LPC2131-ROM.ld -o main.out
crt0.o
main.o -lc -lgcc -Lz:\winarm\lib\gcc\arm-elf\4.1.0\
z:\winarm\bin\../arm-elf/lib\libc.a(freer.o): In function
`_malloc_trim_r':mallo
cr.c:(.text+0x48): undefined reference to `_sbrk_r'
:mallocr.c:(.text+0x64): undefined reference to `_sbrk_r'
:mallocr.c:(.text+0x84): undefined reference to `_sbrk_r'
z:\winarm\bin\../arm-elf/lib\libc.a(makebuf.o): In function
`__smakebuf':makebuf
.c:(.text+0x3c): undefined reference to `_fstat_r'
:makebuf.c:(.text+0x110): undefined reference to `isatty'
z:\winarm\bin\../arm-elf/lib\libc.a(mallocr.o): In function
`_malloc_r':mallocr.
c:(.text+0x424): undefined reference to `_sbrk_r'
:mallocr.c:(.text+0x4cc): undefined reference to `_sbrk_r'
z:\winarm\bin\../arm-elf/lib\libc.a(stdio.o): In function
`__sclose':stdio.c:(.t
ext+0xc): undefined reference to `_close_r'
z:\winarm\bin\../arm-elf/lib\libc.a(stdio.o): In function
`__sseek':stdio.c:(.te
xt+0x30): undefined reference to `_lseek_r'
z:\winarm\bin\../arm-elf/lib\libc.a(stdio.o): In function
`__swrite':stdio.c:(.t
ext+0x84): undefined reference to `_lseek_r'
:stdio.c:(.text+0xac): undefined reference to `_write_r'
z:\winarm\bin\../arm-elf/lib\libc.a(stdio.o): In function
`__sread':stdio.c:(.te
xt+0xd0): undefined reference to `_read_r'

von Fordp (Guest)


Rate this post
useful
not useful
This printf/sprintf causing bloat is a well known problem on very small
systems.

The printf family are very powerful library calls and so pull in a lot
of code when used.

There are basically two ways to solve this issue.

1) Get a reduced functionaly version of printf (I have seen iprintf used
elsewhere which is a integer only version of printf and hence much
smaller).

2) Do no call printf but write your own simple routines that call ONLY
putc().

I hope this help.

Martin, is there a reduced functionality version of printf already in
the library ? If not it would be nice to add one next version.

All the best.

FordP

von Martin Thomas (Guest)


Rate this post
useful
not useful
Fordp wrote:
> Martin, is there a reduced functionality version of printf already in
> the library ?

Yes, iprintf/siprintf is already part of the newlib included in the
WinARM-collection. iprintf does not support floating-point numbers but
has less "bloat". Please check libc.pdf in the WinARM/doc-dir. No extra
files needed just include <stdio.h> and use iprintf instead of printf.
There is also a siscanf in the newlib but it seems the prototype for
this is missing in the newlib stdio.h, but the object code is in the
.a-files so the prototype can be declared manualy in a source-file
(extern..) or added to the stdio.h in arm-elf/include.

In the efsl-arm-port and the LPC213x/214x from my web-pages (
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects ) I have
used a simple "reduced printf" (rprintf.c) which has enough
functionality for most tasks. I might be a good idea not to use "printf"
as function-name in code but a preprocessor replacement, so different
versions can be tested:

#include <stdio.h>
#define myprintf iprintf
...
myprintf("Value=%i",val);

or

#include "rprintf.h"
#define myprintf rprintf
...
rprintf_devopen(myputcfunc)
...
myprintf("Value=%i",val);

etc.


Martin Thomas

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.