Embedded Artists


We are the leading providers of products and services around prototyping, evaluation and OEM platforms using NXP's ARM-based microcontrollers.

LPC4088DM Using printf in RTOS

When using a real-time operating system (RTOS) and more than one thread is using printf the resulting output can become garbled. An example using two threads writing to the serial port:

void printTask(const void* args) {
  const char* msg = (const char*) args;
  while (true) {
    printf(msg);
  }
}

void main() {
  Thread t1(printTask, "Message 1\n");
  Thread t2(printTask, "Message 1\n");
}


The expected output is something like this:

Message 1
Message 2
Message 1
Message 2
Message 1
Message 2
...

But due to task switching possibly occuring in the middle of printing it could become something like this:

Message 1
Message 2
MessaMessage 2ge 1
Message 2
Message 1
Message 2
...

To avoid this problem and make sure that printouts come out in the order that they were made the DMSupport library has a RtosLog class:

Import library

Public Member Functions

void  init ()
  Starts the logger thread, called from DMBoard::instance() . init()
int  printf (const char *format,...)
  Printf that works in an RTOS.
int  isr_printf (const char *format,...)
  Printf that works in an RTOS.

The init() function is automatically called by the init() function in DMBoard and the RtosLog cannot be disabled. However, there are two configuration options for the RtosLog class in the dm_board_config.h file:

This option (set by default) will change the used speed from mbed's default 9600bps to 115200bps.

#define DM_BOARD_USE_FAST_UART


This option will redirect the output from the default mbed COM port (available via the same USB cable that powers the board) to instead use the USB Device serial port.

#define DM_BOARD_USE_USBSERIAL_IN_RTOSLOG


Use the printf function in RtosLog instead of the normal print function. The example code above looks like this instead:

void printTask(const void* args) {
  RtosLog* log = DMBoard::instance().logger();
  const char* msg = (const char*) args;
  while (true) {
    log->printf(msg);
  }
}

void main() {
  // DMBoard initialization code
  ...

  // Start the two printing tasks
  Thread t1(printTask, "Message 1\n");
  Thread t2(printTask, "Message 1\n");
}

All wikipages