Getting printf Output from Target to Debugger

 

Debug OutputErich Styger recently posted a great tutorial on how to add console functionality using Single Wire Output (SWO) on ARM Cortex-M targets.

This inspired me to write a more general post on debug output (“printf”) implementations on embedded target, including SWO and RTT.

Debug Output from a Target

There are different methods to get debug output from the target application.

Since the early days of embedded systems, there have been hardware dependent solutions like using a UART or USB CDC. But a UART may already be used by the application and CDC requires a USB stack and a USB connector on the target hardware.

The first software solution is semihosting. With semihosting, the CPU halts to print output and is restarted “behind the scenes” by the debugger. Printing one message can take anywhere from several milliseconds to more than one hundred milliseconds, as it is an expensive operation. The debugger needs to realize that the target has stopped execution, reads registers and memory, writes memory, and can then restart the CPU. This means the target CPU does not run for this period of time. Therefore semihosting can simply not be used for applications which require real time behaviour, such as communication stacks. Additionally the semihosting implementation is debugger dependent, and applications which use semihosting might not run without a debugger connected.

And then there are ARM’s SWO trace port and SEGGER’s Real Time Transfer (RTT).

Single Wire Output

SWO is a single pin interface designed by ARM for Cortex-M3,M4, and M7 devices. The pin can be connected to the debug probe with the standard debug connector and used with the SWD interface (not JTAG). The target MCU can stream data packets on this pin, similar to a UART TX pin, with a clock rate, derived from the CPU clock. The CPU clock speed needs to be known to set up SWO on the debugger. This is especially critical if parts of the application shall make output at startup before PLL init or of the clock speed changes while the application is running. SWO does not stop the CPU such as semihosting to send output. The output speed via SWO is dependent on the configured SWO speed. The data packets, i.e. the debug output packets, are encoded in a special format. This allows sending up to 32 packet types (stimuli) but also causes a bit of protocol overhead, which slows things down to ~1.5 us/char at 10 MHz SWO speed. This means that outputting 80 characters takes about 120 us. To use SWO from multiple tasks in an RTOS or from interrupt routines, interrupts should be disabled during SWO output, which might influence the real time behaviour of the system.

Although SWO is most commonly used to print debug messages. It can also be used to record interrupt entry/exit and function entry/exit, to periodically sample the PC value or variables in memory, or for event notification.

Erich gives a complete introduction to using SWO for debug messages, how to set it up on the target, and how to get the output on the host computer.

Real Time Transfer

RTT is SEGGER’s solution for a debug terminal. It combines the advantages of SWO with the features of other methods. RTT is a software only solution and does not require additional hardware on the target device, other than the standard debug connection. It can be used with any J-Link, even with the tiny on-board models like J-Link OB, OpenSDA, or converted ST-LINKs.

RTT allows very high transfer speeds without affecting the real-time behaviour of a target. There is no protocol overhead and printing a message can be done in one microsecond or less, basically only the time to do a single memcpy(). Because RTT is that fast, output can be made thread safe by locking interrupts with least influence on the real time behaviour of the system. Output messages are read by J-Link and transferred to the host, while the target application is running.

Similar to a UART, RTT is bi-directional. You can send input to the target application from the host computer. Bi-directional communication allows you to control the target system without any additional input device. With RTT it is possible to implement a full-functional terminal.

The RTT implementation source code is freely available to be used in any system, providing functionality and freedom.

The use of RTT on the host computer is flexible and easy. The J-Link software includes the RTT Viewer, a GUI, which can be used in parallel to any debugger tool. You can also use a Telnet client to connect to a debug session (on port 19031) and communicate with the target. Some debuggers even integrate RTT directly. Embedded Studio and the stand-alone debugger Ozone can show target output via RTT in their Terminal windows and do not require any additional tool.

Summary

Debug Output Speed Comparison
Speed comparison of a printf call with different implementations

Prior to SWO debug output from an embedded target has only been possible with inefficient or hardware-dependent methods.

With SWO ARM designed a quick solution. It is light-weight and fast, but has some draw-backs, as it is only available on some Cortex-M devices, requires an additional pin to be connected to the MCU, and is uni-directional.

RTT combines all advantages of SWO and adds more features. It is faster than SWO, not limited to Cortex-M only, allows bi-directional communication via the standard debug connection, and is least intrusive to be usable in any real time requiring system.

There is no reason to use SWO anymore when you can use RTT instead.