blackmagic/UsingRTT.md

11 KiB

Using RTT

When debugging arm processors, there are three ways for the target to print debug messages on the host: Semihosting, Serial Wire Output SWO, and Real-Time Transfer RTT.

Black Magic Probe (BMP) is an open source debugger probe that already implements Semihosting and Single Wire Output. This patch adds Real-Time Transfer RTT output to usb serial port.

  • RTT is implemented, not as a user program, but as a serial port device. To read RTT output, use a terminal emulator and connect to the serial port.

  • A novel way to detect RTT automatically, fast and convenient.

Use

This example uses linux as operating system. For Windows and MacOS see the Operating Systems section.

In one window open a terminal emulator (minicom, putty) and connect to the usb uart:

$ minicom -c on -D /dev/ttyBmpTarg

In another window open a debugger:

$ gdb
(gdb) target extended-remote /dev/ttyBmpGdb
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt
(gdb) run
^C
(gdb) monitor rtt status
rtt: on found: yes ident: off halt: off channels: auto 0 1 3
max poll ms: 256 min poll ms: 8 max errs: 10

The terminal emulator displays RTT output from the target, and characters typed in the terminal emulator are sent via RTT to the target.

gdb commands

The following new gdb commands are available:

  • monitor rtt

    switch rtt on

  • monitor rtt enable

    switch rtt on

  • monitor rtt disable

    switch rtt off

  • monitor rtt poll max_poll_ms min_poll_ms max_errs

    sets maximum time between polls, minimum time between polls, and the maximum number of errors before RTT disconnects from the target. Times in milliseconds. It is best if max_poll_ms/min_poll_ms is a power of two. As an example, if you wish to check for RTT output between once per second to eight times per second: monitor rtt poll 1000 125 10.

  • monitor rtt status

    show status.

rtt found state
rtt: off found: no rtt inactive
rtt: on found: no searching for rtt control block
rtt: on found: yes rtt active
rtt: off found: yes corrupt rtt control block, or target memory access error

A status of rtt: on found: no indicates bmp is still searching for the rtt control block in target ram, but has not found anything yet. A status of rtt: on found: yes indicates the control block has been found and rtt is active.

  • monitor rtt channel

    enables the first two output channels, and the first input channel. (default)

  • monitor rtt channel number...

    enables the given RTT channel numbers. Channels are numbers from 0 to 15, inclusive. Eg. monitor rtt channel 0 1 4 to enable channels 0, 1, and 4.

  • monitor rtt ident string

    sets RTT ident to string. If string contains a space, replace the space with an underscore _. Setting ident string is optional, RTT works fine without.

  • monitor rtt ident

    clears ident string. (default)

  • monitor rtt cblock

    shows rtt control block data, and which channels are enabled. This is an example control block:

(gdb) mon rtt cb
cbaddr: 0x200000a0
ch ena cfg i/o buf@        size head@      tail@      flg
 0   y   y out 0x20000148  1024 0x200000c4 0x200000c8   2
 1   y   n out 0x00000000     0 0x200000dc 0x200000e0   0
 2   n   n out 0x00000000     0 0x200000f4 0x200000f8   0
 3   y   y in  0x20000548    16 0x2000010c 0x20000110   0
 4   n   n in  0x00000000     0 0x20000124 0x20000128   0
 5   n   n in  0x00000000     0 0x2000013c 0x20000140   0
 6   n   n in  0x00000000     0 0x00000000 0x00000000   0
 7   n   n in  0x00000000     0 0x00000000 0x00000000   0
 8   n   n in  0x00000000     0 0x00000000 0x00000000   0
 9   n   n in  0x00000000     0 0x00000000 0x00000000   0
10   n   n in  0x00000000     0 0x00000000 0x00000000   0
11   n   n in  0x00000000     0 0x00000000 0x00000000   0
12   n   n in  0x00000000     0 0x00000000 0x00000000   0
13   n   n in  0x00000000     0 0x00000000 0x00000000   0
14   n   n in  0x00000000     0 0x00000000 0x00000000   0
15   n   n in  0x00000000     0 0x00000000 0x00000000   0

Channels are listed, one channel per line. The columns are: channel, enabled, configured, input/output, buffer address, buffer size, address of head pointer, address of tail pointer, flag. Each channel is a circular buffer with head and tail pointer.

Note the columns ena for enabled, cfg for configured.

Configured channels have a non-zero buffer address and non-zero size. Configured channels are marked yes y in the column cfg . What channels are configured depends upon target software.

Channels the user wants to see are marked yes y in the column enabled ena. The user can change which channels are shown with the monitor rtt channel command.

Output channels are displayed, and Input channels receive keyboard input, if they are marked yes in both enabled and configured.

The control block is cached for speed. In an interrupted program, monitor rtt will force a reload of the control block when the program continues.

Identifier string

It is possible to set an RTT identifier string. As an example, if the RTT identifier is "IDENT STR":

$ gdb
(gdb) target extended-remote /dev/ttyBmpGdb
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt ident IDENT_STR
(gdb) monitor rtt
(gdb) run
^C
(gdb) monitor rtt status
rtt: on found: yes ident: "IDENT STR" halt: off channels: auto 0 1 3
max poll ms: 256 min poll ms: 8 max errs: 10

Note replacing space with underscore _ in monitor rtt ident.

Setting an identifier string is optional. RTT gives the same output at the same speed, with or without specifying identifier string.

Operating systems

Configuration instructions for windows, linux and macos.

Windows

After configuration, Black Magic Probe shows up in Windows as two USB Serial (CDC) ports.

Connect arm-none-eabi-gdb, the gnu debugger for arm processors, to the lower numbered of the two COM ports. Connect an ansi terminal emulator to the higher numbered of the two COM ports.

Sample gdb session:

(gdb) target extended-remote COM3
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt
(gdb) run

For COM port COM10 and higher, add the prefix \\.\, e.g.

target extended-remote \\.\COM10

Target RTT output will appear in the terminal, and what you type in the terminal will be sent to the RTT input of the target.

linux

On linux, install udev rules. Disconnect and re-connect the BMP. Check the device shows up in /dev/ :

$ ls -l /dev/ttyBmp*
lrwxrwxrwx 1 root root 7 Dec 13 07:29 /dev/ttyBmpGdb -> ttyACM0
lrwxrwxrwx 1 root root 7 Dec 13 07:29 /dev/ttyBmpTarg -> ttyACM2

Connect terminal emulator to /dev/ttyBmpTarg and gdb to /dev/ttyBmpGdb .

In one window:

minicom -c on -D /dev/ttyBmpTarg

In another window :

gdb
(gdb) target extended-remote /dev/ttyBmpGdb
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt
(gdb) run

MacOS

On MacOS the tty devices have different names than on linux. On connecting blackmagic to the computer 4 devices are created, 2 'tty' and 2 'cu' devices. Gdb connects to the first cu device (e.g.: target extended-remote /dev/cu.usbmodemDDCEC9EC1), while RTT is connected to the second tty device (minicom -c on -D /dev/tty.usbmodemDDCEC9EC3). In full:

In one Terminal window, connect a terminal emulator to /dev/tty.usbmodemDDCEC9EC3 :

minicom -c on -D /dev/tty.usbmodemDDCEC9EC3

In another Terminal window, connect gdb to /dev/cu.usbmodemDDCEC9EC1 :

gdb
(gdb) target extended-remote /dev/cu.usbmodemDDCEC9EC1
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt
(gdb) run

RTT input/output is in the window running minicom.

Notes

  • Design goal was smallest, simplest implementation that has good practical use.

  • RTT code size is 3.5 kbyte - the whole debugger 110 kbyte.

  • Because RTT is implemented as a serial port device, there is no need to write and maintain software for different host operating systems. A serial port works everywhere - linux, windows and mac. You can even use an Android mobile phone as RTT terminal.

  • Because polling occurs between debugger probe and target, the load on the host is small. There is no constant usb traffic, there are no real-time requirements on the host.

  • RTT polling frequency is adaptive and goes up and down with RTT activity. Use monitor rtt poll to balance response speed and target load for your use.

  • Detects RTT automatically, very convenient.

  • When using RTT as a terminal, sending data from host to target, you may need to change local echo, carriage return and/or line feed settings in your terminal emulator.

  • Architectures such as risc-v may not allow the debugger access to target memory while the target is running. As a workaround, on these architectures RTT briefly halts the target during polling. If the target is halted during polling, monitor rtt status shows halt: on.

  • Measured RTT speed.

debugger char/s
bmp stm32f723 stlinkv3 49811
bmp stm32f411 black pill 50073
bmp stm32f103 blue pill 50142

This is the speed at which characters can be sent from target to debugger probe, in reasonable circumstances. Test target is an stm32f103 blue pill running an Arduino sketch. Default monitor rtt poll settings on debugger. Default RTT buffer size in target and debugger. Overhead for printf() calls included.

Compiling firmware

To compile with RTT support, add ENABLE_RTT=1.

Eg. for STM32F103 blue pill:

make clean
make PROBE_HOST=stlink ENABLE_RTT=1

or for the STM32F411 Black Pill:

make clean
make PROBE_HOST=f4discovery BLACKPILL=1 ENABLE_RTT=1

Setting an ident string is optional. But if you wish, you can set the default RTT ident at compile time. For STM32F103 Blue Pill:

make clean
make PROBE_HOST=stlink ENABLE_RTT=1 "RTT_IDENT=IDENT\ STR"

or for STM32F411 Black Pill:

make clean
make PROBE_HOST=f4discovery BLACKPILL=1 ENABLE_RTT=1 "RTT_IDENT=IDENT\ STR"

Note the backslash \ before the space.