Using ‘printf’ in microcontrollers

We, as electronics enthusiasts, daily write hundreds of firmware code segments for various microcontrollers. Unlike software, when it comes to debugging microcontroller code, the challenges we face are much more fundamental. I believe that the most common method for debugging firmware is using the good old printf (just like the cout in C++ and println in Java).

When we develop conventional C code for Linux systems, printf works without any hassle. However, to enable the same functionality in microcontrollers, we need to peel away a layer in the C library and find out how exactly printf works.

How printf works?

As you may already know, printf function is implemented within the C library. I will not go through the full printf function definition. If you want you can read http://blog.hostilefork.com/where-printf-rubber-meets-road/. It’s one of the best write-ups I have seen.

However, the important part is, at the end of this function chain, printf calls another function called write. This is a standard system call in Linux, a part of kernel API. However, for microcontrollers, we don’t have such liberties and thus, we have to implement this function ourselves.

The standard implementation is as follows,

int

_write(int file, char *ptr, int len)

{

int DataIdx;

for (DataIdx = 0; DataIdx < len; DataIdx++)

{

__io_putchar(*ptr++);

}

return len;

}

This function basically accepts a character buffer as an argument and invokes another function for each character in that buffer. This new function is, as you can see, __io_putchar.

Let’s say your microcontroller has a UART module which can be used as standard input output module. For the time being, let’s assume that the module is properly configured. A psuedo implementation of __io_putchar looks like,

int __io_putchar(int ch){

uint8_t data = (uint8_t)ch;

UART_Transmit(data);

return 0;

}

For each character you have in printf above function will get invoked and the characters will stream out from the UART module.

This is what you need to do in three steps,

  1. Configure UART module
  2. Implement _write function
  3. Implement __io_putchar function

You are set to use printf as you wish now.

Please note that different toolchains might have different function prototypes for write and ioputchar functions. However, the underlying idea will be the same.

If you have any microcontroller or toolchain specific questions, please post them in the comments section.

Happy coding!

Advertisements

One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s