@@ -85,32 +85,33 @@ Here's an example program to experiment with these options:
85
85
86
86
Now we can build and run it with the default options:
87
87
88
- $ riscv64-unknown-elf -gcc -Os -march=rv32imac -mabi=ilp32 --specs=picolibc.specs --oslib=semihost -Wl,--defsym=__flash=0x80000000 -Wl,--defsym=__flash_size=0x00200000 -Wl,--defsym=__ram=0x80200000 -Wl,--defsym=__ram_size=0x200000 -o printf.elf printf.c
89
- $ riscv64-unknown-elf -size printf.elf
88
+ $ arm-none-eabi -gcc -Os -march=armv7-m --specs=picolibc.specs --oslib=semihost --crt0=hosted - Wl,--defsym=__flash=0 -Wl,--defsym=__flash_size=0x00200000 -Wl,--defsym=__ram=0x20000000 -Wl,--defsym=__ram_size=0x200000 -o printf.elf printf.c
89
+ $ arm-none-eabi -size printf.elf
90
90
text data bss dec hex filename
91
- 8998 24 8 9030 2346 printf.elf
92
- $ qemu-system-riscv32 -chardev stdio,mux=on, id=stdio0 -semihosting-config enable=on,chardev=stdio0 -monitor none -serial none -machine virt ,accel=tcg -kernel printf.elf -nographic -bios none
91
+ 7920 80 2056 10056 2748 printf.elf
92
+ $ qemu-system-arm -chardev stdio,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -monitor none -serial none -machine mps2-an385 ,accel=tcg -kernel printf.elf -nographic
93
93
2⁶¹ = 2305843009213693952 π ≃ 3.141592653589793
94
94
95
95
Switching to float-only reduces the size but lets this still work,
96
96
although the floating point value has reduced precision:
97
97
98
- $ riscv64-unknown-elf -gcc -DPICOLIBC_FLOAT_PRINTF_SCANF -Os -march=rv32imac -mabi=ilp32 --specs=picolibc.specs --oslib=semihost -Wl,--defsym=__flash=0x80000000 -Wl,--defsym=__flash_size=0x00200000 -Wl,--defsym=__ram=0x80200000 -Wl,--defsym=__ram_size=0x200000 -o printf-float.elf printf.c
99
- $ riscv64-unknown-elf -size printf-float.elf
98
+ $ arm-none-eabi -gcc -DPICOLIBC_FLOAT_PRINTF_SCANF -Os -march=armv7-m --specs=picolibc.specs --oslib=semihost --crt0=hosted - Wl,--defsym=__flash=0 -Wl,--defsym=__flash_size=0x00200000 -Wl,--defsym=__ram=0x20000000 -Wl,--defsym=__ram_size=0x200000 -o printf-float.elf printf.c
99
+ $ arm-none-eabi -size printf-float.elf
100
100
text data bss dec hex filename
101
- 6214 24 8 6246 1866 printf-float.elf
102
- $ qemu-system-riscv32 -chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -monitor none -serial none -machine virt,accel=tcg -kernel printf-float.elf -nographic -bios none
101
+ 6360 80 2056 8496 2130 printf-float.elf
102
+
103
+ $ qemu-system-arm -chardev stdio,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -monitor none -serial none -machine mps2-an385,accel=tcg -kernel printf-float.elf -nographic
103
104
2⁶¹ = 2305843009213693952 π ≃ 3.1415927
104
105
105
106
Going to integer-only reduces the size even further, but now it doesn't output
106
107
the values correctly:
107
108
108
- $ riscv64-unknown-elf -gcc -DPICOLIBC_INTEGER_PRINTF_SCANF -Os -march=rv32imac -mabi=ilp32 --specs=picolibc.specs --oslib=semihost -Wl,--defsym=__flash=0x80000000 -Wl,--defsym=__flash_size=0x00200000 -Wl,--defsym=__ram=0x80200000 -Wl,--defsym=__ram_size=0x200000 -o printf-int.elf printf.c
109
- $ riscv64-unknown-elf -size printf-int.elf
109
+ $ arm-none-eabi -gcc -DPICOLIBC_INTEGER_PRINTF_SCANF -Os -march=armv7-m --specs=picolibc.specs --oslib=semihost --crt0=hosted - Wl,--defsym=__flash=0 -Wl,--defsym=__flash_size=0x00200000 -Wl,--defsym=__ram=0x20000000 -Wl,--defsym=__ram_size=0x200000 -o printf-int.elf printf.c
110
+ $ arm-none-eabi -size printf-int.elf
110
111
text data bss dec hex filename
111
- 2266 24 8 2298 8fa printf-int.elf
112
- $ qemu-system-riscv32 -chardev stdio,mux=on, id=stdio0 -semihosting-config enable=on,chardev=stdio0 -monitor none -serial none -machine virt ,accel=tcg -kernel printf-int.elf -nographic -bios none
113
- 2⁶¹ = 0 π ≃ *float*
112
+ 1872 80 2056 4552 11c8 printf-int.elf
113
+ $ qemu-system-arm -chardev stdio,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -monitor none -serial none -machine mps2-an385 ,accel=tcg -kernel printf-int.elf -nographic
114
+ 2⁶¹ = 0 π ≃ *float*
114
115
115
116
## Picolibc build options for printf and scanf options
116
117
@@ -119,9 +120,10 @@ number of picolibc build-time options to control the feature set (and
119
120
hence the size) of the library:
120
121
121
122
* ` -Dio-c99-formats=true ` This option controls whether support for
122
- the C99 type-specific format modifiers 'j', 'z' and 't' is included
123
- in the library. Support for the C99 format specifiers like PRId8 is
124
- always provided. This option is enabled by default.
123
+ the C99 type-specific format modifiers 'j', 'z' and 't' and the hex
124
+ float format 'a' are included in the library. Support for the C99
125
+ format specifiers like PRId8 is always provided. This option is
126
+ enabled by default.
125
127
126
128
* ` -Dio-long-long=true ` This option controls whether support for long
127
129
long types is included in the integer-only version of printf and
@@ -141,10 +143,11 @@ hence the size) of the library:
141
143
make them re-entrant. Without this option, multiple threads using
142
144
getc and ungetc may corrupt the state of the input buffer.
143
145
144
- For even more printf and scanf functionality, picolibc can be compiled
145
- with the original newlib stdio code. That greatly increases the code
146
- and data sizes of the library, including adding a requirement for heap
147
- support in the run time system. Here are the picolibc build options for that code:
146
+ For compatibility with newlib printf and scanf functionality, picolibc
147
+ can be compiled with the original newlib stdio code. That greatly
148
+ increases the code and data sizes of the library, including adding a
149
+ requirement for heap support in the run time system. Here are the
150
+ picolibc build options for that code:
148
151
149
152
* ` -Dtinystdio=false ` This disables the tinystdio code and uses
150
153
original newlib stdio code.
@@ -161,3 +164,28 @@ support in the run time system. Here are the picolibc build options for that cod
161
164
to use 64 bit values for file sizes and offsets. It also adds
162
165
64-bit versions of stdio interfaces which are defined with types
163
166
which may be 32-bits (like 'long'). This option is enabled by default.
167
+
168
+ ### Newlib floating point printf
169
+
170
+ To build the ` printf ` sample program using the original newlib stdio
171
+ code, the first step is to build picolibc with the right options. The
172
+ 'nano' printf code doesn't support long-long integer output, so we
173
+ can't use that, and we need to enable long-long and floating point
174
+ support in the full newlib stdio code:
175
+
176
+ $ mkdir build-arm; cd build-arm
177
+ $ ../scripts/do-arm-configure -Dtinystdio=false -Dio-long-long=true -Dnewlib-io-float=true
178
+ $ ninja install
179
+
180
+ Now we can build the example with the library:
181
+
182
+ $ arm-none-eabi-gcc -Os -march=armv7-m --specs=picolibc.specs --oslib=semihost --crt0=hosted -Wl,--defsym=__flash=0 -Wl,--defsym=__flash_size=0x00200000 -Wl,--defsym=__ram=0x20000000 -Wl,--defsym=__ram_size=0x200000 -o printf.elf printf.c
183
+ $ arm-none-eabi-size printf.elf
184
+ text data bss dec hex filename
185
+ 16008 824 2376 19208 4b08 printf.elf
186
+ $ qemu-system-arm -chardev stdio,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -monitor none -serial none -machine mps2-an385,accel=tcg -kernel printf.elf -nographic
187
+ 2⁶¹ = 2305843009213693952 π ≃ 3.1415926535897931
188
+
189
+ This also uses 2332 bytes of space from the heap at runtime. Tinystdio
190
+ saves 8088 bytes of text space and a total of 3396 bytes of data
191
+ space.
0 commit comments