Tuesday, 8 October 2013

Serial Port STDIO

In previous post I covered the basics of configuring and using the Atmega's USART as a standard RS232 port. This post will be more a little addendum to the previous one. In our program of course we can manually send strings using the serial_send/serial_poll_send routines, but we can use the serial port in more convenient and transparent way. If our application implements only some kind of CLI system or basically treats the serial IO as a Serial Console we can configure libc to use our serial IO routines for stdio functions like printf. What we have to do is to create an input output file streams and instruct avr-libc to use those. Let's have a look at the code bellow:

The code refers to the serial IO routines implemented by libpca. First of all _serial_putc/_serial_getc are just a wrappers, interface adapters sort of speak, to adapt our serial IO API to the library's one. In serial_install_stdio() we simply create two file streams, one to be used as STDOUT (and associate the necessary output routine) and one for input. Next we assign our custom streams to the standard library stdio streams utilized all over the stdio library. And that's the whole magic. Those are the internals which can be used as a reference, let's have a look how it can be done with libpca

As usual, let's clone the newest version of the library and create a project directory:

git clone pca
mkdir serial_stdio
cd serial_stdio

Our example program looks as follows:

After connecting to the Arduino's serial port (ttyACM0 in my case), we can see the output produced by printf(). That's great !

screen /dev/ttyACM0 9600

There is a small remark regarding the AVR libc printf routines. Since we're talking about embedded device, the default implementation is very limited (in order to save program space) and does not support floats. When trying to print a float value, we'll see a '?' instead of the number. We can enable the support for the floating point numbers though, by explicitly providing a linker flags (avr libc stdio.h):

-Wl,-u,vfprintf -lprintf_flt -lm

Those must be appended to the LDFLAGS variable in the Makefile. as usual the example code can be downloaded here.

No comments:

Post a Comment