The standard ‘C’ printf function and its derivatives can be extremely useful, but in a resource-constrained embedded system it is often just too big. Whilst some compilers provide an integer-only version to reduce bloat, this version is highly configurable so you can trim away all the bells and whistles you don’t actually use to reduce it to minimal size.
Sending your output to a serial port (or any other interface) just requires you to provide a function to write a single character to that port.
The functions provided by your compiler are often not thread-safe either, using static buffers to do some of the formatting. This version uses no static buffers, making it suitable for RTOS-based systems.
The original target for this function was the 8-bit AVR family with the WinAVR GCC compiler. It has also been used with the Raisonance and Cosmic STM8 compilers.
The project is maintained on github and can be freely downloaded and used in open source and commercial products under the MIT license.
Why printf?
When I’m working on an embedded system I almost always include a serial port if the port pins are available on the microcontroller as I find it invaluable for debugging. It is sometimes said that this method is outdated and that the availability of cheap JTAG program and debug interfaces for small microcontrollers renders such old-school methods obsolete. Debuggers certainly have their place, but for monitoring a system in-situ it’s hard to beat the good old serial port.
The majority of my work requires real time operation and you simply cannot stop the micro on a breakpoint to see what is going on. Imagine trying that with an engine management system – will the crankshaft stop instantaneously and the gases stop circulating? What you need in this instance is something which will output useful information without compromising the main activity of the microcontroller. And that is what serial output can do, generating a stream of data to be collected offline.
Of course you don’t need printf to do that as you can easily write your own functions to output an 8-bit value, a 16-bit value, etc. But printf is just so convenient to use – one function for many data types.
You do need an efficient interrupt or poll-driven serial port driver, especially if you need to output data from within an interrupt service routine, and you generally want to use as high a baud rate as can be managed.
It is easy to log serial data to a file using one of the many free terminal emulation programs available. Usually I use TeraTerm for this, but another popular alternative is Termite.
Getting information out over a serial line is a lot easier then using JTAG when the board is buried within the bowels of the hardware. You could even hang a Bluetooth module on the port and stream the data out wirelessly if there is no way of getting wires out.