Tutorial: Printf() with (and without) Processor Expert


In this post I tapped into how to print messages to a console using  the Kinetis/Freedom board. I’m not a fan of printf() for multiple reasons: It is simply a bad thing for embedded systems programming. But as many have asked for it, here is how to say “hello” from the Freedom Board using printf():

Hello World on the Terminal

Hello World on the Terminal

I’m using the Freedom KL25Z board with the CodeWarrior for MCU 10.3 and gcc build tools. But steps are  generic for any board and tool chains.

ANSI Library and printf()

The first thing to know about printf() is that ANSI specifies what it should do in terms of accepted arguments and formating, but does not specify how to send/receive the character stream, because the underlying hardware can be very different: which SCI/COM/UART used, which baud, which communication settings/etc. As such, a typical library implementation as in CodeWarrior comes with the implementation of the printf() functionality itself, but *without* the low-level UART implemenation. That low-level UART implementation and support is part of the application, not the library.

Low Level UART Support

In order for printf() to print things to a UART, it depends on low-level UART functions and settings. Basically it needs this functionality (function names are generic):

  • read_console(): reading characters from the console.
  • write_console(): writing characters to the console.
  • open_console(): opening and initializing the console. This includes register initialization, baud settings and allocation of buffers.
  • close_console(): the counterpart of open_console() to free up the port and memory.

Creating the project

:idea: I’m using here Processor Expert. But if you do not like it, or if you want to go without it: either copy the code or do the same thing without it (but then you need to read the microcontroller manual in much more details).

I create a new project with File > New > Bareboard Project. I give a project name, specify the microcontroller, select the connection, and then there is this dialog which asks me about I/O support:

New Bareboard Project IO Support

New Bareboard Project IO Support

The important thing to know about this I/O support is: it does not add the low-level UART functionality (because it does not know which port/UART/baud/etc). What it does is it will configure to use the correct library in the build tool settings.

:idea: If you decide not to use Processor Expert, then you need to copy/paste or create the needed low-level I/O functions. Best if you start with a Processor Expert working version, and then copy/paste things.

EWL Library Settings

So really what the above option does: it sets the library used in the project settings. CodeWarrior offers different libraries, where EWL is the default (EWL = Embedded Warrior Libraries). The EWL are a more optimized and right library for embedded systems. Below you see the different library selections depending on what you have selected in the wizard (so you can easily change this after the project is created):

EWL Library Settings

EWL Library Settings

Using printf()

Time to try it out e.g. in main():

#include <stdio.h>
...
for(;;) {
  printf("hello world!\r\n");
}
...

:!: I always make sure that I have <stdio.h> included if using printf().

But building it, I will have several errors:

Build Failed

Build Failed

So this is to my point from above: the Low Level UART Support is missing.

Adding Low Level UART Support

The simplest thing is to use Processor Expert:

:idea: if not using Processor Expert: have a look in C:\Freescale\CW MCU v10.3\MCU\ARM_GCC_Support\UART for example implementations not using Processor Expert

For this I add the ConsoleIO component from the Processor Expert Components Library view to the project:

ConsoleIO in Components Library

ConsoleIO in Components Library

:idea: right-click and ‘Add to Project’ or double-click to add it to the project.

Configuring ConsoleIO

The component shows up with errors because I need to configure it first:

ConsoleIO in Project with Errors

ConsoleIO in Project with Errors

I select the Serial_LDD and open the inspector for it (right-click on it and select ‘Inspector’). As I want to use the OpenSDA CDC, I configure it to use UART0 with 38400 baud using PTA1 and PTA2:

Console configured for FRDM-KL25Z and OpenSDA

Console configured for FRDM-KL25Z and OpenSDA

Now the errors are resolved, and I can generate code:

Generate Processor Expert Code

Generate Processor Expert Code

:idea: To see what code has been generated,  double click on the ConsoleIO and Serial_LDD.

Building the project is now fine too: and with no errors.

:idea: If things are not working: Verify your UART settings are correct, and that OpenSDA CDC is working properly. Unplugging and plugging the USB port might help for when the USB port is stuck on the host.

Downloading it to the target and running it should show now some text on the terminal:

Hello World on the Terminal

Hello World on the Terminal

Summary

Printf() and the likes need low-level UART drivers. An easy way is to have it provided by Processor Expert. If not using Processor Expert, then Processor Expert can be used as a base for copy-pasting the code, or the examples provided in CodeWarrior can be used.

Just be aware that printf() usually adds a lot overhead to the application, and is a common source of stack and buffer overflow. So use it carefully ;-)

Happy Printf-ing :-)

About these ads

20 thoughts on “Tutorial: Printf() with (and without) Processor Expert

  1. Hi, in your tutorial of LCD, you put this code:

    for(;;) {
    uint8_t cnt;
    uint8_t buf[5];

    LCD1_GotoXY(2,1);
    UTIL1_Num16uToStr(buf, sizeof(buf), cnt);
    LCD1_WriteString((char*)buf);
    cnt++;
    WAIT1_Waitms(100);
    }

    How I should write the line code for sending the string data by “Printf()”?

  2. Pingback: Be Aware of the Baud Problem | MCU on Eclipse

  3. Pingback: printf() with the FRDM-KL25Z Board and without Processor Expert | MCU on Eclipse

  4. Hello Erich,

    I’m with problems to use other serial ports besides the PTA1 and PTA2.
    Indeed, i used this ports and the SD Card, but i couldn’t inlcude a serial communication in PTC3 and PTC4 in this project (didnt work).

    I dont know why, but, the PTC3 and PTC4 worked well without the SD card.
    Do you know why this happens ? In some projects sometimes i can use others ports (e.g. PTE0 and PTE1), in others dont.. this doesn’t make sense to me

  5. Hi, I would like to use my KL25Z to display in the terminal an input from other device. In the user manual I read the following: “The primary serial port interface signals are PTA1 and PTA2. These signals are connected to both the OpenSDA and to the J1 I/O connector. ” So I think I just have to connect the RX and TX from my other device to the TX and RX respectively to my KL25Z and join the GND of course. But how could I print the received data to the console? Thanks in advance.

    • If you are using the signals connected to the OpenSDA micrcontroller, then you need to make sure that the K20 does not interfer with it. It would be better if you would use a UART/SCI which is separate. And how to print things on the console: as described in this article, but using different pins.
      Having said that: you probably better use Processor Expert: it is much, much easier with it.

  6. Hi!
    If I want to create my project without processor expert…In what part of the processor expert’s code can I find the clock and ports configurations?

    • Hi jose,
      the ConsoleIo component is really only a small wraper for terminal usage and printf() as shown in this article, while the Asynchroserial is a full UART/serial componet.

  7. If you have turned on the console IO, how do you turn it off? If I select EWL_NOIO, I get an undefined reference to ‘_pformatter’ in vsnprintf.c.

    • It sounds like you are still using printf() in your application. Remove any calls to printf() and its variants from your application code.
      You might need to do a Project > Clean too and then rebuild.

      • Yep. I use sprintf for formating strings for LCD display. I needed to go back to EWL, and just not use ‘puts’ or ‘printf’. as long as I don’t use those, I don’t get any errors. Thanks!

What do you think?

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s