Electronics Design AU
Testing

How Does SEGGER RTT Debug Logging Work?

Last updated 3 July 2026 · 6 min read

Direct Answer

SEGGER RTT (Real-Time Transfer) is a debug logging mechanism that moves data between a target microcontroller and a host PC through the existing SWD or JTAG debug connection — no UART peripheral, no extra wiring, and none of semihosting's severe performance penalty. Firmware writes log messages into a small ring buffer allocated in the target's own RAM (typically via `SEGGER_RTT_printf()` or `SEGGER_RTT_Write()`); the host-side J-Link software reads that buffer directly out of target memory over the debug connection without halting the CPU, so logging has minimal impact on real-time behaviour. This makes RTT the standard choice for production and near-production debug logging on any target already using a SEGGER J-Link (or J-Link-compatible) debug probe, in preference to both semihosting (extremely slow, since it traps to the debugger on every call) and dedicated UART logging (fast, but consumes a UART peripheral, pins, and a separate cable).

Detailed Explanation

Getting diagnostic output out of a running microcontroller is a surprisingly constrained problem: a UART needs a physical peripheral, pins, and a cable; semihosting works over the existing debug connection but is slow enough to change the timing behaviour of whatever it's trying to observe; and neither is ideal for logging inside a time-critical interrupt handler or a real-time control loop. SEGGER RTT solves this by using the debug connection that's already present for programming and debugging, without semihosting's CPU-halting overhead. For the broader embedded debugging toolset RTT fits into, see How Do You Debug Embedded Firmware?; for the debug connections RTT rides on top of, see What Is SWD? and What Is JTAG?.

How RTT Actually Moves Data

RTT works through a small, fixed-location data structure and ring buffer allocated in the target's own RAM by the RTT library linked into the firmware. Firmware writes to this buffer through calls like SEGGER_RTT_printf() or SEGGER_RTT_Write() — ordinary memory writes, no peripheral access involved. On the host side, the J-Link software locates this structure in target memory (by searching for a known signature, or from a fixed address if configured) and reads new data out of the buffer directly through the debug connection's memory-access capability — the same mechanism the debugger already uses to inspect variables and set breakpoints. Critically, reading RTT data does not require halting the target CPU, which is the key difference from semihosting (where each call traps into the debugger and stops execution until it's serviced).

RTT vs Semihosting vs UART Logging

  • Semihosting routes debug I/O through a special breakpoint instruction that the debugger intercepts and services — simple to set up, but each call can cost milliseconds due to the CPU stopping and the debugger round-trip, making it unsuitable for logging inside tight loops, ISRs, or anywhere timing matters.
  • UART logging is fast and doesn't need a debugger attached at all, but consumes a physical UART peripheral and GPIO pins, and needs a separate cable or USB-to-serial adapter to actually read it — a real cost on pin-constrained designs, and an extra piece of lab setup during development.
  • RTT avoids both problems: no UART peripheral or pins consumed, and orders of magnitude faster than semihosting because the host reads the buffer without stopping the target. The trade-off is that it requires a SEGGER J-Link or J-Link-compatible debug probe to be attached and running the appropriate host-side software (RTT Viewer, J-Link RTT Logger, or an IDE's integrated RTT console) — it's a development and lab tool, not a field communication channel.

Buffer Overflow Behaviour

Because the RTT buffer is finite (commonly configured from a few hundred bytes up to several kilobytes, depending on available RAM and logging volume), firmware bursts that outpace the host's read rate will eventually fill it. RTT's overflow handling is configurable per buffer:

  • Skip — new data is discarded when the buffer is full; the reader loses the newest data during a burst, but firmware execution is never affected.
  • Trim — similar skip-on-full behaviour tuned for RTT's formatted output functions.
  • Block if buffer full — firmware execution pauses at the write call until the host has drained enough buffer space. This guarantees no log data is lost, but means firmware can stall indefinitely if no debugger is attached to drain the buffer — a configuration that needs to be deliberately chosen, not left as an accidental default in a production build.

Design Considerations

  • Choose the overflow mode deliberately, and be explicit about which builds use which mode. Non-blocking (Skip) is the safer default for anything that might run without a debugger attached; reserve blocking mode for lab debugging sessions where guaranteed log capture matters more than never stalling.
  • Size the RTT buffer for actual logging burst volume, not just steady-state output — a burst of log lines during a fault condition (often exactly when the log data matters most) is the most likely scenario to overflow an undersized buffer.
  • Don't assume every debug probe supports RTT — confirm the specific probe (genuine J-Link, J-Link OB on a dev board, or a third-party probe with OpenOCD RTT support) before designing a logging strategy entirely around it, particularly for production test/debug fixtures that might standardise on a lower-cost probe.
  • Use RTT for development and lab diagnostics, not as a field telemetry channel — it depends entirely on a debug probe being physically attached and running host software, which is not a deployment-appropriate requirement for a shipped product.

For embedded firmware debugging strategy, logging architecture, and production diagnostics tooling, Zeus Design's firmware team develops and debugs embedded systems across STM32, ESP32, and nRF platforms.

Common Mistakes

  • Leaving blocking overflow mode enabled in a production build — without a debugger permanently attached, firmware can stall indefinitely at an RTT write call waiting for buffer space that will never be freed.
  • Undersizing the RTT buffer for the actual logging pattern — a buffer sized for steady low-rate logging silently drops data during exactly the high-volume burst (a fault, an error cascade) an engineer most needs to capture.
  • Assuming RTT works identically across all debug probes — genuine SEGGER J-Link hardware has full, mature RTT support; other probes' RTT support (where it exists at all) can lag in feature completeness and reliability, and should be verified for the specific probe and toolchain in use rather than assumed.
  • Using RTT (or any debugger-dependent logging) as the only diagnostic channel in a field-deployed product — a mechanism that requires a physically attached debug probe has no value once the product has left the lab; production diagnostics need a channel that works without a debugger present.

Frequently Asked Questions

Do I need a SEGGER J-Link to use RTT?
Native, fully-supported RTT requires a genuine SEGGER J-Link or a J-Link-compatible on-board debugger (many evaluation and development boards ship with J-Link OB firmware on their integrated debug probe). Some other debug tooling — including OpenOCD — has added RTT protocol support for certain non-J-Link probes, but coverage and reliability vary by probe and OpenOCD version; verify RTT support for a specific probe and toolchain combination before depending on it, rather than assuming parity with genuine J-Link hardware.
Is RTT safe to leave enabled in production firmware?
It's commonly left in production builds, since the RTT control block is inert (just a small RAM buffer and a fixed data structure) when no debugger is attached — firmware keeps writing to the ring buffer and older data is simply overwritten or dropped depending on the configured overflow mode, with no functional impact on the running application. The one configuration that is genuinely unsafe in production is the blocking overflow mode (waiting for the host to drain the buffer before continuing) — if no debugger is ever attached in the field, firmware configured this way can stall indefinitely waiting for a reader that will never arrive.
Can RTT carry more than text log messages?
Yes. RTT supports multiple independent channels and arbitrary binary data, not just printf-style text — SEGGER's own SystemView (RTOS task and interrupt timeline tracing) is itself built on top of RTT as its transport mechanism, streaming structured binary trace events rather than text. A firmware project can use one RTT channel for human-readable log text and additional channels for structured or binary diagnostic data simultaneously.

References

Related Questions

Related Forum Discussions