As usual on embedded systems you have to provide your own getchar() and putchar() routines. SDCC does not know whether the system connects to a serial line with or without handshake, LCD, keyboard or other device. And whether a lf to crlf conversion within putchar() is intended. You'll find examples for serial routines f.e. in sdcc/device/lib. For the mcs51 this minimalistic polling putchar() routine might be a start:
int putchar (int c) {
while (!TI) /* assumes UART is initialized */
;
TI = 0;
SBUF = c;
return c;
}
The default printf() implementation in printf_large.c does not support float (except on ds390), only <NO FLOAT> will be printed instead of the value. To enable floating point output, recompile it with the option -DUSE_FLOATS=1 on the command line. Use —model-large for the mcs51 port, since this uses a lot of memory. To enable float support for the pic16 targets, see 4.7.9.
If you're short on code memory you might want to use printf_small()
instead of printf(). For the mcs51 there additionally
are assembly versions printf_tiny()
(subset of printf using less than 270 bytes) and printf_fast()
and printf_fast_f()
(floating-point aware version of printf_fast) which should fit the
requirements of many embedded systems (printf_fast() can be customized
by unsetting #defines to not support long variables and field
widths). Be sure to use only one of these printf options within a
project.
Feature matrix of different printf options on mcs51.
mcs51
|
printf |
printf USE_FLOATS=1
|
printf_small
|
printf_fast |
printf_fast_f
|
printf_tiny |
---|---|---|---|---|---|---|
filename
|
printf_large.c |
printf_large.c
|
printfl.c
|
printf_fast.c |
printf_fast_f.c
|
printf_tiny.c |
”Hello World” size
small / large |
1.7k / 2.4k |
4.3k / 5.6k
|
1.2k / 1.8k
|
1.3k / 1.3k |
1.9k / 1.9k
|
0.44k / 0.44k |
code size
small / large |
1.4k / 2.0k |
2.8k / 3.7k
|
0.45k / 0.47k (+ _ltoa)
|
1.2k / 1.2k |
1.6k / 1.6k
|
0.26k / 0.26k |
formats
|
cdiopsux |
cdfiopsux
|
cdosx
|
cdsux |
cdfsux
|
cdsux |
long (32 bit) support
|
x |
x
|
x
|
x |
x
|
- |
byte arguments on stack
|
b |
b
|
-
|
- |
-
|
- |
- |
%f
|
-
|
- |
%f3.8
|
- | |
float formats %e %g
|
- |
-
|
-
|
- |
-
|
- |
field width
|
x |
x
|
-
|
x |
x
|
- |
string speed3.9,
small / large |
1.52 / 2.59 ms |
1.53 / 2.62 ms
|
0.92 / 0.93 ms
|
0.45 / 0.45 ms |
0.46 / 0.46 ms
|
0.45 / 0.45 ms |
int speed3.10,
small / large |
3.01 / 3.61 ms |
3.01 / 3.61 ms
|
3.51 / 18.13 ms
|
0.22 / 0.22 ms |
0.23 / 0.23 ms
|
0.25 / 0.25 ms3.11 |
long speed3.12,
small / large |
5.37 / 6.31 ms |
5.37 / 6.31 ms
|
8.71 / 40.65 ms
|
0.40 / 0.40 ms |
0.40 / 0.40 ms
|
- |
float speed3.13,
small / large |
- |
7.49 / 22.47 ms
|
-
|
- |
1.04 / 1.04 ms
|
- |
As of SDCC 2.6.2 you no longer need to call an initialization routine before using dynamic memory allocation and a default heap space of 1024 bytes is provided for malloc to allocate memory from. If you need a different heap size you need to recompile _heap.c with the required size defined in HEAP_SIZE. It is recommended to make a copy of this file into your project directory and compile it there with:
sdcc -c _heap.c -D HEAP_SIZE=2048And then link it with:
sdcc main.rel _heap.rel