SEGGER RTT in Embedded Systems
- Alessandro Salvato
- 21 feb
- Tempo di lettura: 6 min
Aggiornamento: 1 mar
Real-Time Transfer for High-Performance Logging, Monitoring, and Interactive I/O (Black Box & White Box Testing)
1) Why RTT exists (the real problem it solves)
Embedded debugging often ends up constrained by the same recurring bottlenecks:
UART logging steals resources (pins, peripheral configuration, IRQ/DMA bandwidth).
Logging throughput is often too slow for high-frequency signals.
Adding logging changes timing (“probe effect”), sometimes hiding race conditions or real-time issues.
In some targets, the serial channel is not available at all (no free pins, already used for production I/O, or physically inaccessible).
SEGGER RTT (Real-Time Transfer) is designed to bypass these limitations by using a very pragmatic approach:
Put log data into RAM, and let the debug probe read it through the debug interface.
No UART, no additional pins, and typically no interrupts required.
2) RTT in one sentence
RTT is a RAM-based, debugger-assisted bidirectional communication channel between an embedded target and a host PC, typically used for monitoring and interactive I/O.
3) What you need: hardware and software ecosystem
Hardware side
RTT is “exploitable by means of J-Link” debug probes.
RTTIn practice:
A supported MCU with a debug port (SWD/JTAG)
A J-Link (model selection affects throughput potential)
Software side
RTT can be used from multiple SEGGER tools, including: RTT
RTT Viewer (fastest way to start: “serial terminal, but via RTT”)
Ozone (debugger UI + RTT integration)
SystemView (runtime analysis, event tracing, profiling context)
Embedded Studio (IDE integration)
This is an important point: RTT is not “just a logging trick”. It’s a channel that can feed different analysis layers depending on the tool.
4) How RTT works under the hood (conceptual architecture)
RTT uses a control block and one or more ring buffers in target RAM. The firmware writes data into those buffers. The J-Link reads the memory and streams it to the host application.
Conceptually:
Target firmware
writes log bytes into an “up” buffer (target → host)
optionally reads commands from a “down” buffer (host → target)
Debug probe
continuously reads/writes RAM through SWD/JTAG, without needing target peripherals
Key consequence:
Because RTT primarily exploits RAM access, throughput is typically much higher than most embedded output methods used for PC logging.
5) Performance: why RTT is fast
Since only RAM is exploited, the performance of SEGGER RTT is significantly higher than any other technology used to output data to a host PC.
In practice, RTT performance depends on:
J-Link model
Different models yield different max transfer rates.
Target interface speed
SWD/JTAG speed settings and target stability matter.
Target buffer size
Larger buffers reduce overflow risk and allow bursty logging.
Logging pattern
One big string vs many small prints (printf overhead and lock behavior can matter).

Buffer “knobing” (tuning)
RTT is tunable. You can choose buffer sizes and behavior to balance:
RAM footprint
Maximum sustained logging rate
Loss tolerance (drop vs block)
This is the real lever to adapt RTT to:
hard real-time loops
verbose debugging sessions
production-like stress testing

6) Integration in firmware (what actually changes in your project)
RTT is written in ANSI C and can be integrated into basically any embedded codebase.
Typical minimal file set (as in your PPT)
Copy/import these into your firmware project:
RTT directory
SEGGER_RTT.c
SEGGER_RTT.h
SEGGER_RTT_printf.c
Config directory
SEGGER_RTT_Conf.h
This “copy & paste” style integration is one reason RTT is widely adopted in real embedded teams: it doesn’t force architecture changes.
Look at the official GitHub repo -> https://github.com/SEGGERMicro/RTT
7) RTT usage patterns: printf and scanf (output + command injection)
A) Printf-style logging
RTT supports printf-like output (often the starting point):
debug logs
runtime metrics
watchpoints without a watch window
event counters
time stamps
state transitions
B) Scanf-style interactive input
RTT also supports interactive I/O (host → target).
This is a huge enabler for:
“command console” on bare-metal targets
runtime parameter tuning (gains, thresholds, modes)
fault injection commands
toggling verbose levels without reflashing
If you’ve ever built a “debug shell” over UART… RTT can offer the same workflow without owning the UART.
8) RTT in testing: Black Box vs White Box (and how to use it correctly)
RTT is powerful, but it’s not a pure black-box tool because it requires firmware modification.
8.1 Black Box testing with RTT (what is possible)
In strict terms, black-box testing means the tester does not depend on internal implementation details. They validate behavior through external interfaces and observable outputs.
RTT can still be used in black-box-like workflows in two practical ways:
(1) “Black box at system level, RTT as a telemetry tap”
You run tests that treat the system as a black box (inputs/outputs), but you additionally collect RTT telemetry for:
post-run diagnostics
failure context
performance counters
timing evidence
The test verdict can still be based on external outputs, while RTT provides observability that helps explain failures.
(2) “Black box from the tester perspective”
Sometimes the test operator doesn’t know the internal code, but the firmware image includes RTT instrumentation. The tester reads logs but does not interpret internal logic—only uses logs as signals.
This is common in:
validation labs
manufacturing tests
field support builds (special debug firmware)
What RTT enables in black-box tests:
Non-intrusive high-rate telemetry without extra pins.
Logging during scenarios where UART is impractical.
Controlled command injection (if enabled) to run standardized test commands.
Key limitation
Even if your test methodology is black-box, RTT requires you to embed support in firmware. That makes RTT not truly black-box by definition.
8.2 Why RTT is fundamentally “White Box”
To use RTT you introduce firmware-level changes that imply: recompile, new code, RAM usage, buffer tuning.
That’s the core of white-box testing:
you exploit knowledge (and access) to internal implementation
you instrument internal variables/paths
you verify internal states, not only outputs
RTT fits white-box perfectly because it supports:
Any variable accessible (you decide what to print)
Multi-channel logging (separate streams for application/driver/safety layers)
Layered observability (application state + driver diagnostics + error counters)
Interactive command injection (scanf)
In other words:
RTT turns the firmware into a “transparent system” while it is running.
8.3 Practical guidance: choosing Black-box-like vs White-box RTT usage
Here’s a simple decision model:
Use RTT in a black-box-like way when:
you want test results to remain tied to external I/O behavior
RTT is only for post-mortem or telemetry support
you want minimal instrumentation (e.g., heartbeat + fault codes + timestamps)
Use RTT as true white-box when:
you need to validate internal state machines
you are chasing race conditions / timing jitter
you’re tuning algorithms and need internal observability
you need interactive control and fault injection during runtime
9) Risks and “gotchas” (what can go wrong)
Even though RTT is “non-intrusive” in the sense of not using UART/interrupts/pins, it can still affect your system if misused.
9.1 Too much logging can hurt performance
Too logging may lead a performance decrease.
This can happen due to:
CPU time spent formatting strings (printf)
buffer contention / internal locks
blocking behavior if buffer fills
cache/memory bandwidth impact on some targets
Mitigation strategies
Prefer short, structured logs over verbose text
Use throttling (log every N cycles)
Switch between debug levels at runtime via RTT input
Increase buffer sizes appropriately
If needed, log binary events instead of long strings (tool-dependent)
9.2 RAM footprint matters
RTT uses RAM for buffers and the control block.
On small MCUs, you must plan this intentionally.
9.3 Debug connection dependency
RTT is best when the debug probe is connected and stable. For unattended field operation, you typically ship a different telemetry approach.
10) Example: how I’d structure RTT channels in a real project
A clean multi-channel setup (conceptually) could look like:
Channel 0 – Application
mode transitions, state machine edges, control outputs
Channel 1 – Driver/HAL
peripheral init status, error counters, IRQ rate metrics
Channel 2 – Safety/Diagnostics
fault classification, plausibility checks, watchdog cause, reset reason
Channel 3 – Test Harness / Commands
command injection and acknowledgements
This maps naturally to how embedded teams debug: separate concerns, avoid one “junk drawer” log stream.
11) Final takeaways
RTT is one of those tools that, once adopted, often becomes the default debugging channel because it combines:
High performance thanks to RAM-based transfer
No UART and no extra pins
Flexible integration (ANSI C, drop-in files)
White-box superpowers (any variable, multi-channel, command injection)
Black-box-friendly workflows when used as a passive telemetry tap (even though it’s not strictly black-box by definition)




Commenti