Skip to the content.

Trice over RTT

Contents

Allows Trice over the debug probe without using a pin or UART.

The RTT target sources come from SEGGER’s official SEGGERMicro/RTT repository. Trice includes the unmodified SEGGER_RTT.c, SEGGER_RTT.h, and SEGGER_RTT_ConfDefaults.h from commit 4d8feab3150f86f37a9d323ddc88d6cdf5673072 (2026-06-03), together with the SEGGER license. The source snapshot is independent of the J-Link host-tool version: installing J-Link V9.84 does not replace the sources compiled into your firmware. SEGGER removed the RTT source ZIP from the J-Link installation package in V8.68; obtain source updates from its GitHub repository instead.

The library includes a fallback SEGGER_RTT_Conf.h. Put your project and generated include directories first, then src, and src/default_conf last:

-Iproject -Igenerated -Isrc -Isrc/default_conf

Your project’s SEGGER_RTT_Conf.h takes precedence and replaces the entire fallback configuration. SEGGER’s SEGGER_RTT_ConfDefaults.h first includes that selected configuration, then fills in missing settings with #ifndef defaults. This is the same principle as Trice’s triceConfig.h and triceDefaultConfig.h. New project headers need only define their deviations; they no longer need to copy all vendor defaults and CPU-specific lock implementations. The Trice fallback keeps only its channel counts, C implementation selection, ARM memory barriers, and native Windows lock policy. An empty project header is valid for RTT itself, but selects SEGGER’s three up-/down-channel slots, not Trice’s one-slot defaults; its compiler-selected assembly and Windows lock defaults may also need overrides. Do not put a configuration directly in src: SEGGER’s quoted include searches that directory before the -I directories, which would hide your project configuration. The fallback provides one up-channel with a 1024-byte buffer, one down-channel with a 16-byte buffer, and non-blocking output that skips a write if the buffer is full. It uses the C implementation without requiring external RTT assembly files or embOS on Windows. It retains SEGGER’s CPU-specific interrupt locks; check the interrupt-priority and cache settings for your target before relying on concurrent RTT access. Native host builds use no-op locks and need a project-specific configuration for concurrent RTT writers. Adding the fallback include path does not enable RTT in triceConfig.h or make every file in src necessary for your application.

When updating an existing project, copy all three vendor files and retain SEGGER_RTT_LICENSE.md. Keep your existing SEGGER_RTT_Conf.h: full configurations from older RTT releases remain usable, and their explicitly defined values and lock macros take precedence over the new defaults. Do not replace them with an empty header. Trice derives matching TRICE_... values from the selected SEGGER configuration automatically. Only explicit overrides in triceConfig.h need to match; Trice checks them at compilation. The optional SEGGER_RTT_ASM_ARMv7M.S is not shipped here. Use RTT_USE_ASM=0 when compiling only the C implementation. Project configurations still need appropriate memory barriers, interrupt locks and cache settings for their CPU. Trice’s optimized 32-bit writer directly accesses the RTT control block, so a future vendor update must also be checked against that path.

(back to top)

1. For the impatient (2 possibilities)

The default SEGGER tools only suport RTT channel 0.

1.1.1. Setup TCP4 server providing the trace data

This is just the SEGGER J-Link server here for demonstration, but if your target device has an TCP4 interface, you can replace this with your target server.

ms@DESKTOP-7POEGPB MINGW64 ~/repos/trice (main)
$ jlink
SEGGER J-Link Commander V7.92g (Compiled Sep 27 2023 15:36:46)
DLL version V7.92g, compiled Sep 27 2023 15:35:10

Connecting to J-Link via USB...O.K.
Firmware: J-Link STLink V21 compiled Aug 12 2019 10:29:20
Hardware version: V1.00
J-Link uptime (since boot): N/A (Not supported by this model)
S/N: 770806762
VTref=3.300V


Type "connect" to establish a target connection, '?' for help
J-Link>connect
Please specify device / core. <Default>: STM32G0B1RE
Type '?' for selection dialog
Device>
Please specify target interface:
  J) JTAG (Default)
  S) SWD
  T) cJTAG
TIF>s
Specify target interface speed [kHz]. <Default>: 4000 kHz
Speed>
Device "STM32G0B1RE" selected.


Connecting to target via SWD
InitTarget() start
SWD selected. Executing JTAG -> SWD switching sequence.
DAP initialized successfully.
InitTarget() end - Took 36.3ms
Found SW-DP with ID 0x0BC11477
DPv0 detected
CoreSight SoC-400 or earlier
Scanning AP map to find all available APs
AP[1]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x04770031)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xF0000000
CPUID register: 0x410CC601. Implementer code: 0x41 (ARM)
Found Cortex-M0 r0p1, Little endian.
FPUnit: 4 code (BP) slots and 0 literal slots
CoreSight components:
ROMTbl[0] @ F0000000
[0][0]: E00FF000 CID B105100D PID 000BB4C0 ROM Table
ROMTbl[1] @ E00FF000
[1][0]: E000E000 CID B105E00D PID 000BB008 SCS
[1][1]: E0001000 CID B105E00D PID 000BB00A DWT
[1][2]: E0002000 CID B105E00D PID 000BB00B FPB
Memory zones:
  Zone: "Default" Description: Default access mode
Cortex-M0 identified.
J-Link>

Now the TCP4 server is running and you can start the Trice tool as TCP4 client, which connects to the TCP4 server to receive the binary log data:

$ trice l -p TCP4 -args="127.0.0.1:19021" -til ../examples/G0B1_inst/til.json -li ../examples/G0B1_inst/li.json -d16 -pf none

In this G0B1_inst example we use the additional -d16 and -pf none switches to decode the RTT data correctly.

This is a demonstration and test for the -port TCP4 usage possibility. Using RTT with J-Link is more easy possible as shown in the next point.

1.2. Start using JLinkRTTLogger

1.3. JLinkRTTLogger Issue

mkdir -p ./temp
rm -f ./temp/trice.bin
touch ./temp/trice.bin
tmux new -s "tricerttlog" -d "JLinkRTTLogger -Device STM32G0B1RE -If SWD -Speed 4000 -RTTChannel 0 ./temp/trice.bin"
trice log -p FILE -args ./temp/trice.bin -pf none -prefix off -hs off -d16 -ts16 "time:offs:%4d Β΅s" -showID "deb:%5d" -i ../../demoTIL.json -li ../../demoLI.json -stat
tmux kill-session -t "tricerttlog"

(back to top)

2. Segger Real Time Transfer (RTT)

        -args string
        Use to pass port specific parameters. The "default" value depends on the used port:
        port "COMn": default="", use "TARM" for a different driver. (For baud rate settings see -baud.)
        port "J-LINK": default="-Device STM32F030R8 -if SWD -Speed 4000 -RTTChannel 0 -RTTSearchRanges 0x20000000_0x1000",
                The -RTTSearchRanges "..." need to be written without extra "" and with _ instead of space.
                For args options see JLinkRTTLogger in SEGGER UM08001_JLink.pdf.
        port "ST-LINK": default="-Device STM32F030R8 -if SWD -Speed 4000 -RTTChannel 0 -RTTSearchRanges 0x20000000_0x1000",
                The -RTTSearchRanges "..." need to be written without extra "" and with _ instead of space.
                For args options see JLinkRTTLogger in SEGGER UM08001_JLink.pdf.
        port "BUFFER": default="0 0 0 0", Option for args is any byte sequence.
         (default "default")

(back to top)

3.1.1. First step (to do if some issues occur - otherwise you can skip it)

Video

See also https://github.com/stlink-org/stlink

3.1.2. Second step

3.2. Some SEGGER tools in short

3.2.1. JLink.exe

3.2.2. JLinkRTTLogger.exe

3.3. JLinkRTTClient.exe

3.4. JLinkRTTViewer.exe

(back to top)

4. Segger RTT

(back to top)

(back to top)

6. Additional Notes (leftovers)

(back to top)

7. Further development

libusb-1.0.23\examples\bin64> .\listdevs.exe
2109:2811 (bus 2, device 8) path: 6
1022:145f (bus 1, device 0)
1022:43d5 (bus 2, device 0)
0a12:0001 (bus 2, device 1) path: 13
1366:0105 (bus 2, device 10) path: 5
libusb-1.0.23\examples\bin64> .\listdevs.exe
2109:2811 (bus 2, device 8) path: 6
1022:145f (bus 1, device 0)
1022:43d5 (bus 2, device 0)
0a12:0001 (bus 2, device 1) path: 13

(back to top)

8. NUCLEO-F030R8 example

Info: https://www.st.com/en/evaluation-tools/nucleo-F030r8.html

./ref/STLinkReflash.PNG

./ref/J-LinkRTT.PNG

(back to top)

9. Possible issues

(back to top)

10. OpenOCD with Darwin (macOS)

Terminal 1:

brew install open-ocd
...
cd ./trice/examples/G0B1_inst
openocd -f openocd.cfg
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
srst_only separate srst_nogate srst_open_drain connect_deassert_srst

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : J-Link STLink V21 compiled Aug 12 2019 10:29:20
Info : Hardware version: 1.00
Info : VTarget = 3.300 V
Info : clock speed 2000 kHz
Info : SWD DPIDR 0x0bc11477
Info : [stm32g0x.cpu] Cortex-M0+ r0p1 processor detected
Info : [stm32g0x.cpu] target has 4 breakpoints, 2 watchpoints
Info : starting gdb server for stm32g0x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : rtt: Searching for control block 'SEGGER RTT'
Info : rtt: Control block found at 0x20001238
Info : Listening on port 9090 for rtt connections
Channels: up=1, down=0
Up-channels:
0: Terminal 1024 0
Down-channels:

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections

Terminal 2:

ms@MacBook-Pro G0B1_inst % trice l -p TCP4 -args localhost:9090  -pf none -d16
Nov 14 17:32:33.319451  TCP4:       triceExamples.c    10        0_000  Hello! πŸ‘‹πŸ™‚
Nov 14 17:32:33.319463  TCP4:
Nov 14 17:32:33.319463  TCP4:         ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
Nov 14 17:32:33.319463  TCP4:         🎈🎈🎈🎈  NUCLEO-G0B1RE   🎈🎈🎈🎈
Nov 14 17:32:33.319463  TCP4:         πŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒπŸƒ
Nov 14 17:32:33.319463  TCP4:
Nov 14 17:32:33.319463  TCP4:
Nov 14 17:32:33.406455  TCP4:       triceExamples.c    16        0_037 2.71828182845904523536 <- float number as string
Nov 14 17:32:33.505116  TCP4:       triceExamples.c    17        0_087 2.71828182845904509080 (double with more ciphers than precision)
Nov 14 17:32:33.607518  TCP4:       triceExamples.c    18        0_117 2.71828174591064453125 (float  with more ciphers than precision)
Nov 14 17:32:33.707851  TCP4:       triceExamples.c    19        0_146 2.718282 (default rounded float)
Nov 14 17:32:33.807685  TCP4:       triceExamples.c    20        0_175 A Buffer:
Nov 14 17:32:33.908202  TCP4:       triceExamples.c    21        0_204 32 2e 37 31 38 32 38 31 38 32 38 34 35 39 30 34 35 32 33 35 33 36
Nov 14 17:32:34.007148  TCP4:       triceExamples.c    22        0_254 31372e32  31383238  34383238  34303935  35333235
Nov 14 17:32:35.007949  TCP4:       triceExamples.c    23        0_301 ARemoteFunctionName(2e32)(3137)(3238)(3138)(3238)(3438)(3935)(3430)(3235)(3533)(3633)
Nov 14 17:32:35.112304  TCP4:       triceExamples.c    24              100 times a 16 byte long Trice messages, which not all will be written because of the TRICE_PROTECT:
Nov 14 17:32:35.307567  TCP4:       triceExamples.c    26        0_379 i=44444400 aaaaaa00
Nov 14 17:32:35.408257  TCP4:       triceExamples.c    27    0,000_002 i=44444400 aaaaaa00
Nov 14 17:32:35.509022  TCP4:       triceExamples.c    26        0_441 i=44444401 aaaaaa01
Nov 14 17:32:35.609439  TCP4:       triceExamples.c    27    0,000_002 i=44444401 aaaaaa01
Nov 14 17:32:35.710201  TCP4:       triceExamples.c    26        0_504 i=44444402 aaaaaa02
...

TODO: Working example with SEGGER_RTT J-Link and Open OCD

(back to top)