code size with c libs?!

Guest #1171220
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.
Guest #1171221
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
Guest #1171222
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'
Guest #1171223
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
Guest #1171224
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

Reply

Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.

Formatting
  • [c]C-Code[/c]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.