 
 
 
 
 
 
 
 
 
 
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:
void putchar (char c) {
while (!TI) /* assumes UART is initialized */
;
TI = 0;
SBUF = c;
}
The default printf() implementation in printf_large.c does not support float (except on ds390). To enable this 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.
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
 | 
-
 | - | 
-
 | - | 
| float format | - | 
%f
 | 
-
 | - | 
%f3.9
 | - | 
| float formats %e %g | - | 
-
 | 
-
 | - | 
-
 | - | 
| field width | x | 
x
 | 
-
 | x | 
x
 | - | 
| string speed3.10, 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.11, 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.12 | 
| long speed3.13, 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.14, 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 HEAD_SIZE=2048And then link it with:
sdcc main.rel _heap.rel
 
 
 
 
 
 
 
 
