Every embedded developer has faced the same problem: getting data out of a running target without disrupting its real-time behavior. UART printf is the classic approach, but it consumes a peripheral, requires dedicated pins, and introduces blocking delays that distort timing-sensitive code. SEGGER’s Real Time Transfer (RTT) solves this by using the debug probe’s existing JTAG/SWD connection, no additional hardware, no additional pins, and critically, minimal CPU overhead on the target.
How RTT Works
RTT uses a small control block in target RAM that contains ring buffers for bidirectional communication between the target and host. The J-Link debug probe reads and writes these buffers through the standard debug interface (JTAG or SWD) using background memory access, the same mechanism the probe uses to read variables during debugging. The target CPU is never halted.
The architecture consists of three components:
-
SEGGER_RTT control block: A structure placed in target RAM containing pointers to up and down ring buffers. The J-Link probe locates this control block automatically by scanning RAM for a known ID string.
-
Up channels (target to host): Ring buffers where the target firmware writes data. The J-Link probe continuously reads these buffers in the background and forwards data to the host application. Multiple up channels are supported for separating different data streams (debug output, sensor data, profiling events).
-
Down channels (host to target): Ring buffers where the host writes data that the target firmware reads. Used for configuration commands, parameter updates, or interactive debug input.
RTT Code Integration
Adding RTT to a project requires including SEGGER’s RTT source files (freely available from SEGGER) and calling a handful of functions. A minimal example:
#include "SEGGER_RTT.h"
int main(void) {
SEGGER_RTT_Init();
// Channel 0 is the default terminal channel
SEGGER_RTT_printf(0, "System started, clock: %u Hz\n", SystemCoreClock);
while (1) {
uint32_t sensor_val = read_sensor();
SEGGER_RTT_printf(0, "Sensor: %u\n", sensor_val);
// Write binary data on channel 1
SEGGER_RTT_Write(1, &sensor_val, sizeof(sensor_val));
}
}
The SEGGER_RTT_printf function formats and writes to the specified channel. SEGGER_RTT_Write sends raw binary data. Both are non-blocking in the default mode, if the buffer is full, the write returns immediately without waiting. Alternative blocking and trim modes are available per channel.
RTT vs SWO vs UART
| Characteristic | RTT | SWO | UART |
|---|---|---|---|
| Additional Hardware | None (uses debug probe) | None (uses debug probe) | UART transceiver + cable |
| Additional Pins | None | 1 pin (SWO) | 2 pins (TX/RX) |
| Direction | Bidirectional | Target to host only | Bidirectional |
| Speed | High, well beyond typical UART rates (probe and target dependent) | Limited by SWO clock | Typically 115.2 kbps to 1 Mbps |
| CPU Overhead | Minimal (short write to a RAM buffer) | Low (DWT/ITM hardware) | Moderate (ISR or DMA) |
| Timing Impact | Negligible | Low | Can be significant |
| Multiple Channels | Yes (configurable) | Yes (ITM stimulus ports) | Requires multiple UARTs |
| Works While Halted | No (target must run) | No | No |
| Availability | Any J-Link + RAM | Cortex-M with SWO pin | Any MCU with UART |
When to use RTT: General-purpose debug output, sensor data streaming, interactive command shells, logging in timing-critical code, and any scenario where UART pins are unavailable or the UART peripheral is already in use.
When to use SWO: Hardware-assisted event tracing via the Cortex-M Data Watchpoint and Trace (DWT) unit. SWO is generated by dedicated hardware with no software involvement for hardware-triggered events, making it useful for exception tracing and PC sampling.
When to use UART: Production debug interfaces that must work without a debug probe, field diagnostics, and communication with external equipment.
Practical Use Cases
Debug Logging Without UART
The most common use case. Replace printf over UART with SEGGER_RTT_printf and eliminate the UART dependency entirely. The debug output appears in the J-Link RTT Viewer application or in Embedded Studio’s integrated RTT terminal. No board modification, no additional cables.
Streaming Sensor Data for Analysis
Write sensor readings as binary data on a dedicated RTT channel. On the host side, the J-Link SDK (licensed separately from SEGGER for every J-Link model) or a custom application reads the binary stream and plots, logs, or processes the data. RTT’s high throughput, which depends on the J-Link model and target, handles continuous sensor streams that would overwhelm UART.
Interactive Debug Console
Use a down channel to accept commands from the host and an up channel to return responses. This creates an interactive console for runtime configuration, register dumps, state inspection, and test control, without consuming a UART. The RTT Viewer application provides a terminal interface for interactive use.
SystemView RTOS Analysis
SEGGER SystemView uses RTT as its data transport. RTOS task switches, ISR entry/exit events, and custom application events stream from the target through RTT to SystemView on the host, providing real-time visualization of system behavior with minimal target intrusion.
Automated Testing
CI/CD pipelines can use RTT to capture test output from firmware running on physical hardware, check pass/fail results, and log diagnostic data, all through the same J-Link connection used for flashing. No UART cables to manage in the test rack.
Performance Considerations
RTT speed depends on the J-Link model, the target’s debug interface speed, and the buffer configuration:
- Buffer size: Larger buffers reduce the frequency of J-Link background reads but consume more target RAM. For most applications, 1 KB per channel is a reasonable starting point. High-throughput binary streams may benefit from 4 KB or larger.
- J-Link model: The ULTRA and PRO models, rated at download speeds up to 4 MB/s, achieve higher background access rates than the BASE Compact, rated at up to 1 MB/s.
- Write mode: The default skip mode drops data when the buffer is full (non-blocking). Block mode waits until space is available (blocking). Trim mode truncates the current write. Choose based on whether data integrity or timing predictability matters more for your use case.
Getting Started with RTT in India
GSAS provides all J-Link models with local stock, INR invoicing, and technical support from offices in Bengaluru, Chennai, Hyderabad, Delhi NCR, Mumbai, and Pune. The RTT source code is included in the free J-Link Software and Documentation Pack, download from SEGGER’s website and integrate into any project within minutes.
Also appears in:
Interested in SEGGER tools?
Talk to our application engineers for personalized tool recommendations.
More from SEGGER
View all →