I have used semihosting more and more in my projects. However, there are several disadvantage of using it:
- Without special handlers, it only works with an active debug connection going on. Without a debugger attached, the application blocks otherwise.
- Because it needs debugger interactions, it is rather slow (only several hundreds of bytes per second)
The good news is that Segger supports with their debug probes a faster approach with what they name Real Time Terminal (RTT). And it even runs without a debugger attached to the board: all what I need is a Segger J-Link probe (or Segger J-Link OpenSDA) plus a telnet client.
Similar to semihosting, RTT provides a bidirectional channel between the target and the host. This can be used for sending/receiving text and data. Have a look at https://www.segger.com/jlink-real-time-terminal.html to understand how RTT works.
💡 Currently RTT does not support file I/O what is now supported by the Segger Semihosting implementation. So I can send/receive data over communication channels with RTT, but there is no logic implemented to open/store files. Unless I would add a special RTT client on the host. There is a dedicated RTT channel for reading/writing to a file, but this is for a single file only. This is not enough to dump gcov trace and coverage data, as this would need multiple files. Maybe Segger will add generic file I/O in RTT in the future?
The difference between RTT and normal semihosting is that RTT is handled at the probe level, and not at the debugger level. That makes RTT much, much faster.
In the following I describe how to use RTT in an application. I’m using Kinetis Design Studio V3.0.0 with the Kinetis SDK, but the steps can be applied to any other environment.
First, download the Segger RTT Implementation and example files from https://www.segger.com/jlink-real-time-terminal.html (Section “Example Code”).
Add the following files to your project:
Using RTT in Application
The Segger software package comes with several examples, including using VT100 terminal color codes or implementing a simple menu system.
SEGGER_RTT_WriteString(0, "Hello World from SEGGER RTT!\r\n");
The following functions are present in the API:
|SEGGER_RTT_Read()||Read data from an input buffer.|
|SEGGER_RTT_Write()||Write data to an output buffer.|
|SEGGER_RTT_WriteString()||Write a zero-terminated string to an output buffer.|
|SEGGER_RTT_printf()||Write a formatted string to an output buffer.|
|SEGGER_RTT_GetKey()||Get one character from input buffer 0.|
|SEGGER_RTT_HasKey()||Check if a character is available in input buffer 0.|
|SEGGER_RTT_WaitKey()||Wait for a character to be available in input buffer 0 and get it.|
|SEGGER_RTT_ConfigUpBuffer()||Configure an up (output) buffer.|
|SEGGER_RTT_ConfigDownBuffer()||Configure a down (input) buffer.|
|SEGGER_RTT_Init()||Initialize RTT Control Block structure when using RAM only targets.|
|SEGGER_RTT_SetTerminal()||Set the “virtual” Terminal to use for output on channel 0 via Write and WriteString.|
|SEGGER_RTT_TerminalOut()||Send a zero-terminated string via a “virtual” terminal.|
RTT is using a telnet connection on localhost:19021. You can use any telnet client. I’m using a client in Eclipse (see “Serial Terminal View in Eclipse Luna“). This gives me the ‘Target Explorer Terminals’ view:
In the view, I open a new Terminal with the icon:
Next, I configure that I want to connect to the localhost on telnet port 19021:
With this, I can send and receive strings inside Eclipse:
Of course it is possible to use any other telnet client.
Using Segger JLinkRTTViewer
Another way is to use the Segger RTT viewer, in
and then connect to the board/Segger J-Link:
Using the Segger RTT is a better way than normal semihosting, as it is faster and more efficient to use. Yes, it does *not* hook into the normal standard library printf() stuff, but anyway, I want to avoid printf() wherever possible. Yes, it does not support generic file I/O yet, but at least it can read/write one log file. And yes, it depends on having a Segger J-Link or J-Link OpenSDA available. But it is a really cool and convenient feature for anyone using debug probes from Segger.
I have put an example project for Kinetis Design Studio and GNU ARM Embedded (launchpad) tools on Segger RTT Example for FRDM-K64F on GitHub.
Happy Realtiming 🙂