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 sourceforge.net 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 often 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. I beg to differ.
If your embedded application does not need to work in real time then that may well be true, but the majority of my work does require 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 that will output useful information without compromising the main activity of the microcontroller. And that is what printf, or any other serial output function can do, generating a stream of data to be collected offline.
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.