/picoprintf

tiny (<1 kB) sprintf() for embedded platforms

Primary LanguageCMIT LicenseMIT

pico-printf implements sprintf, snprintf, and vsnprintf for embedded platforms. Its goal is to be very small (under 1 kB in minimal config), avoid using dynamic memory, and be customizable.

pico-printf implements basic subset of format specifiers: strings, chars, decimal integers. Optionally (enabled by compile-time macro declarations) it also supports octal and hex integers, binary integers via "%b", as well as floats.

Benchmarks and Alternatives

picoprintf is compile-time customizable. This lets you control the module's footprint and only use what you need. While the table below reflects the smallest possible (chars, strings, ints) and the largest possible (simple floats, hex, oct) footprints, the actual size will be somewhere in between, depending on features enabled via the compile-time macros.

Please note the actual values depend on the exact compiler used, build-time parameters, alignment, and other variables. Thus, the values below should be treated as relative.

The code size of this and similar libraries, as reported in .map file, adding up .text and .rodata segments in bytes:

target picoprintf min picoprintf full mpaland tinyprintf nanoprintf
ARM thumb gcc 11.3.0 544 1406 4438 1528 2388
ARM 32 gcc 11.3.0 880 2318 6962 2372 3764
ARM 64 gcc 11.3.0 1192 2361 6582 3200 4612
ARM 64 clang 14.0.3 848 2044 5846 2401 4066
x86 gcc 9.4.0 697 1272 5022 3649 3681
x64 gcc 9.4.0 889 1592 5974 3782 2676

all values are collected by compiling with -Os flag

  1. copy picoprint.h and picoprintf.c into your project
  2. #include "picoprintf.h" wherever you need it
  3. (optional) adjust the #defines in picoprintf.h to include options you need (this affects the footprint in your flash, ROM, or OTP)
  4. (optional) #define snprintf pico_snprintf
  5. enjoy!

Building This Project

this chapter discusses how this project is built for benchmarking. For instructions on using picoprintf in your project, see Usage above

embedded

copy the header and the .c file into any project, build it and notice the .map file

macOS

to build for native CPU:

clang picoprintf.c picotest.c -Os -Wl,-map,pico.map

calculate the size of the module:

cat pico.map | grep 1\] | grep -o -E '\t0x[0-9A-F]*' | sed 's/\t0x[^0-9A-F]*//' | awk '{ printf "%d\n", "0x" $1 }' | awk '{s+=$1} END {print s}'

Linux

gcc picoprintf.c picotest.c -lm -Os -Wl,-Map,pico.map