In the last post, we discussed how a developer can use advanced breakpoints to improve their debugging efficiency. We saw that there are different breakpoint types (hardware, software and flash) in addition to how we can trigger a breakpoint based on evaluating an expression. In today’s post, we will explore how to setup and use printf and discuss the advantages and disadvantages that come with it.
The printf statement is a library function that allows a developer to print text data from their application to some external device. The external device could be a terminal connected to a UART, USB or it could even be the virtual debug terminal. The printf statement is useful because it allows a developer to print human readable text statements that can include a wide variety of information such as sensor readings and software states.
There are several advantages to using printf such as:
Unfortunately, there are several potential disadvantages to using printf as well which include:
When examining the printf advantages and disadvantages, a developer just needs to be aware that printf can be very useful but also can affect their applications performance if they are using a physical peripheral to receive the data. Implementing printf through the ITM or using SEGGERs Real-Time Transfer (RTT) can reduce printf transmission times to microseconds rather than tens of milliseconds using a UART at 9600 baud.
Getting printf up and running using the virtual terminal is easy. To see how easy it is, let’s try an example. Start by first creating a Synergy C project that uses the default Blinky with RTOS option. Once the project has been created and the Synergy Configuration has been generated, open the blinky_thread_entry.c file located under src. The printf statement is included in the stdio.h C library. Include this library in the blinky thread.
In order to connect printf to the virtual debug terminal, there is a “magic” function that needs to be called named initialise_monitor_handles. (Yes it’s the British spelling for initialize). The blinky task file needs a prototype for this function, so before the task code, add the following prototype:
extern void initialise_monitor_handles(void);
This function only needs to be called once. It should be called early in the task code before entering the task main loop. A developer can then add their favorite printf statement:
A developer can then compile the application and start a debug session to view their application code printing “Hello World!” into the virtual debug terminal.
Now, earlier we mentioned that the real-time performance for the system can be affected by printf. In order to measure how printf can affect the real-time performance, a developer can use the onboard LED’s to go into a low state before the printf statement and then go into a high state after the printf statement is completed. If a developer does this, they will discover that a simple “Hello World!\r\n” will take approximately 62.94 milliseconds to complete! This can be seen in the logic analyzer screen shot below:
While printf can be very useful to get debugging information from the system, as we’ve just seen, a developer needs to be very careful how they use it and which interface they use to display that debugging information. In future posts, we’ll examine how we can get printf to execute far faster so that it minimizes the real-time impact on our software.
Until next time,
Live long and profit!
Hot Tip of the Week
You may not have seen the new posting on the Synergy Gallery for the Developer Examples targeted to SSP 1.3.0. Go to the gallery here: https://synergygallery.renesas.com/ssp/utility#read and download the zip file. The examples are organized in sub-folders based on their function- timers, analog, etc. so they are easy to find. Just unzip and import the example you are interested in. These examples make good ‘test benches’ for functions or interfaces you are interested in. You can exercise serial ports, memory interfaces and other hardware resources using a convenient console interface. Cool!