Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

rvdbg User Guide

中文

rvdbg uses one rvdbg.toml to flash, debug and inspect rustvisor boards. With a Lauterbach probe it uses TRACE32 PowerView; with StellarLINK it runs openocd-stellar as a separate process. Build firmware with your project’s own build system: rvdbg deploys existing images and helps inspect the target.

This guide covers Apple Silicon macOS and Linux x86_64/aarch64 hosts. The board defaults generated by rvdbg init target SR6P6. Before using another board, check scripts, core names, memory access ports and OTP ranges.

Start with your task

TaskReadExpected outcome
First useQuick startInstall dependencies, configure, flash and inspect
Change images, probes or coresConfigurationIdentify effective images, backend and ports
Update code or symbolsFlashing and verificationChoose flash/load and handle multiple images
Breakpoints and steppingDebuggingConnect an IDE/GDB and understand target state changes
Diagnose a running programInspectionInspect PC, faults, memory, clocks and acceptance conditions
Logs and packetsRTT and FDXLocate buffers and choose a transport
Scripts and agentsAutomationInterpret JSON, exit codes and session boundaries
Failed operationsTroubleshootingFind the next check from the symptom

Follow the table in order on your first visit; use task pages directly afterwards. Standard Markdown relative links work in GitHub and Obsidian. The mdBook website adds “Referenced by” sections to show which pages depend on the current page.

Backend differences

CapabilityTRACE32StellarLINK / OpenOCD
Flash, verify, status, halt and resumeSupportedSupported
IDEsVS Code and RustRover/LSP4IJ over DAPVS Code/Cortex-Debug and GDB
Ordinary RAM, RTT and FDXRuntime access through AD:Runtime access through MEM-AP
Debug symbolsrvdbg loadGDB reads the ELF
PER register namesreg, watchUse addresses or check files instead
PRACTICEeval, cmd, doUnsupported
Trace exporttrace, fault --traceUnsupported
Clock diagramclock --htmlText/JSON tree only

Shared command names do not imply that every option works on both backends. See configuration for selection and individual task pages for restrictions.

Understand what an operation changes

Inspection commands such as status, mem, fault, verify and check without --halt do not automatically reset or halt the target to obtain a value. Some register reads will therefore fail. Distinguish ordinary RAM from MMIO with read side effects; see inspection.

flash writes Flash and resets the target; reset resets and halts it. halt, go and run-until change execution state. load loads symbols and resumes when necessary. IDE connection can also execute board reset hooks; see debugging.

ram --write changes target RAM. FDX sends can trigger firmware actions. cmd and do depend on the PRACTICE content and can perform arbitrary target operations.

Use rvdbg --help and rvdbg <command> --help for full arguments. This guide explains workflows and interpretation; consult your installed version’s help and rvdbg init output for defaults. See maintaining this guide for local previews and link conventions.


From installation to your first flash

中文

Follow one SR6P6 workflow: start with successfully built ELF images, connect the board and probe, generate configuration, flash and inspect the result. rvdbg does not compile firmware.

Install rvdbg and its backend

On Apple Silicon macOS or Linux, use Homebrew:

brew install haoyibits/tap/rvdbg
rvdbg --version

The formula also installs openocd-stellar. TRACE32 users must separately install PowerView and t32debugadapter.

Alternatively, install a release binary:

curl -fsSL https://github.com/haoyibits/rustvisor-debug/releases/latest/download/install.sh | sh

The script defaults to ~/.local/bin, which must be on PATH. Set RVDBG_INSTALL_DIR for another directory or RVDBG_VERSION for a specific release. It does not install openocd-stellar. To install from source, run in this repository:

cargo install --path crates/rustvisor-debug

If Gatekeeper blocks a macOS binary downloaded in a browser, verify its release source, then remove quarantine from the actual binary:

xattr -d com.apple.quarantine /path/to/rvdbg

Prepare the probe

TRACE32: PowerView is discovered under ~/t32 by default; set trace32.sys for another installation. Remote API must use TCP. An existing config.t32 can contain:

RCL=NETTCP
PORT=20000
REMOTEHOSTDENY

When no RCL= is defined, rvdbg supplies TCP Remote API startup arguments restricted to local access. If RCL= is already present, its protocol and port must match trace32.rcl_port. Remote API has no authentication and allows PRACTICE and host commands; retain the local access restriction.

StellarLINK: use openocd-stellar, rather than an OpenOCD build without Stellar support. The default SR6P6 EVB script is board/sr6p6_evb.cfg. VS Code needs Cortex-Debug; direct GDB use needs arm-none-eabi-gdb.

Generate configuration in the firmware project

Run these commands in the project being debugged, rather than rvdbg’s own source tree:

cd ~/work/rustvisor-sdk
rvdbg init
$EDITOR rvdbg.toml

init refuses to overwrite an existing file. Check the generated SR6P6 [project] defaults:

[project]
program = "boot_diagnostic"
elf = "target/thumbv8r-none-eabihf/release/boot_diagnostic"
extra_elf = ["target/thumbv8r-none-eabihf/release/scenario-guest"]

Replace paths with your actual build products. Use extra_elf = [] for no extra images. Declare hypervisor and Guest images together; see multiple-image flashing.

Check what will be operated on

rvdbg config

Check the configuration path, image existence, detected probes and selected backend. With both probes connected TRACE32 wins by default. To select StellarLINK for this invocation:

rvdbg --backend openocd config

A successful config check does not validate target power, JTAG or Flash operations. See configuration for backend and core selection.

Flash and inspect

After confirming the images and board:

rvdbg flash
rvdbg verify
rvdbg status

flash erases/writes and resets the target, running it after normal completion. Without an explicit path, verify checks every configured image; exit code 0 means the loadable contents match. status reports running/halted state and PC/CPSR when halted.

A content match does not prove successful boot or correct application behavior. Continue with RTT or project checks. On failure, use troubleshooting; skipping verification or enabling OTP writes is not a general fix.

Run rvdbg vscode for IDE configuration or bare rvdbg for an interactive session.


Configure a project and select a backend

中文

Configuration determines the images, backend and core an operation uses. After changes, run rvdbg config before commands that change target state.

Configuration discovery and paths

rvdbg searches upward from the current directory for the nearest rvdbg.toml. Its directory is the project root. Select another file explicitly:

rvdbg --config /work/firmware/rvdbg.toml config

Project-relative paths, including image paths, are based on the configuration directory. OpenOCD config entries are script names resolved by OpenOCD, such as board/sr6p6_evb.cfg; add script directories through search. Bare executable names in executable/gdb are searched on PATH.

Use rvdbg init for the full commented template. Unknown sections and keys are rejected; remove obsolete fields.

Backend selection

The first explicit choice wins:

  1. --backend trace32 or --backend openocd on the command line.
  2. [project] backend = "trace32" or "openocd".
  3. Probe discovery: Lauterbach or a running PowerView selects TRACE32; StellarLINK selects OpenOCD; both selects TRACE32.
rvdbg --backend openocd status
rvdbg --backend trace32 status

An explicit backend does not make a disconnected probe or unavailable server usable. TRACE32 inspection needs PowerView already running. OpenOCD inspection reuses an existing Tcl service or starts an instance without resetting the target. See debugging for session lifetimes.

Fields to check first

SectionFieldsPurpose
[project]elf, extra_elf, program, backendImages, TRACE32 symbol program and backend
[trace32]sys, config, host, rcl_portInstallation, startup configuration and Remote API
[trace32.target]cpu, cores, mem_access, jtag_clock, dual_portTarget and runtime access
[trace32.flash]chip, script, argsFlash script selection and arguments
[trace32.rtos]config, menu, show_tasksOptional RTOS awareness
[openocd]executable, config, search, commandsOpenOCD and board initialization
[openocd]tcl_port, gdb_port, gdb_target, coreControl connection, GDB core and inspection core
[openocd]memory_ap, timeout, otpPhysical memory access, operation timeout, OTP ranges
[rtt]symbol, control_block_address, poll_intervalControl block and polling
[fdx]symbolLink symbol, default RUSTVISOR_FDX
[clock]e.g. XOSC = "40MHz"Board frequencies not encoded in registers

An absent/empty program is derived from the primary ELF filename. It identifies a TRACE32 symbol program, not an image path. trace32.host is a host platform directory within the TRACE32 installation, not a Remote API network address; normally leave it empty for platform detection.

The generated SR6P6 defaults include:

[openocd]
executable = "openocd-stellar"
config = ["board/sr6p6_evb.cfg"]
search = []
commands = []
tcl_port = 6666
gdb_port = 3333
gdb_target = "sr6p6.k0c0.core"
gdb = "arm-none-eabi-gdb"
memory_ap = "sr6p6.axi"
timeout = 600
otp = [{ start = 0x29F87000, size = 0x1000 }]

gdb_target selects the GDB core. When core is unset, inspection/control commands such as halt, go, fault and check use that core too. A different core does not move the IDE’s GDB connection. memory_ap names the physical-memory MEM-AP and cannot be replaced with a core name. Names come from the board script.

Tcl and GDB ports must differ. Use separate ports for simultaneous projects to avoid reusing another project’s service.

Environment overrides

Image overrides apply to both backends; TRACE32 overrides follow backend configuration rules. Environment values take precedence over TOML and defaults:

ELF=build/el2.elf EXTRA_ELF="build/guest.elf" rvdbg config

Apply the same prefix to the actual operation or export it in the shell. An override on config alone does not persist to the next command.

VariableEffect and empty values
ELF, PROJECT_ROOTPrimary image or image-resolution root; empty ignored; the latter does not select a config file
EXTRA_ELFShell-style image list; empty explicitly clears it
PROGRAM_NAMETRACE32 symbol program; empty applies
T32_SYS, then T32SYSInstallation directory; empty ignored
T32_HOST, T32_EXE, T32_BIN, T32_CONFIG, T32_DEBUG_ADAPTERHost platform directory and executable paths; empty ignored
T32_CPU, T32_CORES, T32_MEMACCESS, T32_JTAG_CLOCK, T32_DUALPORTTarget settings; empty applies
T32_FLASH_CHIPScript matching chip; empty ignored
T32_FLASH_SCRIPT, T32_FLASH_ARGSExplicit script and shell-style arguments; empty clears
T32_RCL_PORT, T32_DAP_PORT, T32_DAP_BACKEND_PORTRemote API and frontend/backend DAP ports
T32_DAP_BACKEND_TIMEOUT, T32_TIMEOUTAdapter and TRACE32 operation timeouts
RTT_SYMBOLRTT symbol; empty ignored

Clearing EXTRA_ELF changes the flash/verification image set. TRACE32 erase ranges come from the script and do not shrink automatically with that list.

Local files

LocationContents
<project>/.rvdbg/history, openocd.log
<project>/.tracebridge/PowerView logs, toolbar scripts, clock HTML and trace exports
~/.config/rvdbg/flash/Local flash scripts
~/.config/rvdbg/clock/Local clock descriptions

With XDG_CONFIG_HOME, libraries live under $XDG_CONFIG_HOME/rvdbg/. Keep licensed or confidential board material in local libraries. Public examples use fictional registers and are not working board configurations.


Flash, load symbols and verify

中文

Confirm the image set and backend first.

CommandWhen to useTarget effect
rvdbg flashProgram contents must changeWrite Flash, reset and normally run
rvdbg loadLoad current ELF symbols into TRACE32No code write or reset; resume if needed
rvdbg verifyCompare target contents with local ELFRead and compare; no automatic halt/reset

load does not deploy newly compiled code. Symbols that do not match the target invalidate breakpoint locations, PC names and stack interpretation.

Declare all images together

[project]
elf = "build/el2.elf"
extra_elf = ["build/guest.elf", "build/other-guest.elf"]

flash handles the primary and every extra image in one operation. TRACE32 load loads their symbols; verify without an ELF argument checks all of them.

TRACE32 uses FLASH.ReProgram ALL /Erase: script-declared sectors may be erased even when no image writes them this time. Do not replace extra_elf with separate hypervisor/Guest flashes or casually clear the list for a partial update.

TRACE32: script to execution

rvdbg flash starts PowerView if needed. A flash script must support PREPAREONLY: initialize the target and declare Flash, then return for rvdbg to program it. An already-up system is taken down first to avoid running the flash algorithm under application state such as MPU settings.

The main sequence is:

script PREPAREONLY
FLASH.ReProgram ALL /Erase
Data.LOAD.Elf <primary-image>
Data.LOAD.Elf <extra-image> /NoClear    # once per extra image
FLASH.ReProgram OFF
SYStem.Down
SYStem.Up

Debug setup and symbol loading follow, then execution resumes if needed. This does not automatically run rvdbg’s own segment comparison; use rvdbg verify to check contents.

An explicit script wins; otherwise match chip, falling back to trace32.target.cpu. Search the local rvdbg/flash library before TRACE32’s demo/*/flash scripts:

rvdbg chips SR6P6
rvdbg flash --chip SR6P6
rvdbg flash --script '~~/demo/arm/flash/my_chip.cmm'

Automatic selection needs suitable ; @Chip: metadata and PREPAREONLY support. Exact matches beat wildcards; more specific wildcards win. Specify a script if ambiguity remains. rvdbg supplies CPU= when the script accepts it and no explicit argument exists; use [trace32.flash] args for other arguments.

flash and load do not interrupt an active PRACTICE script. See troubleshooting for PowerView is busy.

The normal path executes reset init, flash write_image erase for each image, compares loadable segments through memory_ap, then executes reset run.

rvdbg --backend openocd flash
rvdbg --backend openocd flash --no-run

--no-run leaves the target halted; --no-verify skips comparison after programming. These and --write-otp are OpenOCD-only. TRACE32 --chip/--script cannot be used with OpenOCD.

Keep verification enabled normally. Differences return 3: inspect the image, address and readback before deciding what to do.

OTP protection

Before writing, compare image content intersecting openocd.otp. Equal content needs no change; different content is refused unless --write-otp is explicit. Attempts to change a bit from 0 to 1 are always refused because OTP cannot be erased.

The SR6P6 default protects the UTEST boot-record range: start = 0x29F87000, size = 0x1000. Ranges are configured rather than automatically discovered for every chip. --no-verify does not disable OTP checks.

On differences, first check the image, boot record and range. The operator should enable --write-otp only for an intended permanent change.

Check what is on the board

rvdbg verify
rvdbg verify build/el2.elf
rvdbg --backend trace32 verify --t32

Comparison uses file contents of ELF PT_LOAD segments at their LMA (p_paddr), not all initialized runtime RAM. Data copied into RAM during startup is checked at its load location. Use check files for BSS and application state.

Without a path, verify checks all configured images; with a path it checks only that ELF. Differences return 3; read/parse failures return 1.

TRACE32 --t32 additionally runs Data.LOAD.Elf /DIFF /PHYSLOAD /NoRegister /NosYmbol /NoClear for cross-checking without changing target memory, PC or symbols.

After a content match, use status and checks to establish program progress, then connect an IDE.


Debugging and interactive sessions

中文

Start with a deployed program. Confirm local and target contents match and the ELF contains debug information; an ELF suffix alone does not imply source line tables.

Choose the target state change

CommandBehavior
rvdbg statusInspect state without automatically halting
rvdbg attachConnect without reset, preserving running/halted state
rvdbg haltHalt the selected core
rvdbg goResume the selected core
rvdbg resetReset the chip and halt at the reset vector
rvdbg run-until <symbol-or-address>Run a halted core to a temporary hardware breakpoint
rvdbg downTRACE32 SYStem.Down

TRACE32 inspection/control needs PowerView already running. rvdbg open starts or reuses it. rvdbg load loads symbols but also resumes a halted target.

For example:

rvdbg halt
rvdbg run-until rustvisor_boot_main --timeout 30
rvdbg status

The symbol must exist and remain reachable. run-until does not first halt a running core. Stopping elsewhere returns 3. Timeout does not mean the target is halted: on StellarLINK it keeps running while the tool attempts to remove the breakpoint. Check status next. OpenOCD uses A32 hardware breakpoints; do not assume this works for another instruction set.

VS Code

rvdbg vscode

Configurations are merged into .vscode/launch.json and tasks.json, preserving existing entries and backing up modified files as *.bak.<timestamp>. Select the matching configuration in Run and Debug:

ConfigurationConnectionPreparation and effects
TRACE32: AttachHidden task starts rvdbg’s DAP proxyPowerView running, symbols loaded
StellarLINK: AttachCortex-Debug connects to rvdbg debugFlash first; SR6P6’s board script resets the core when GDB connects

The name “Attach” does not guarantee preservation of the current fault scene. Record inspection results before opening an IDE if necessary.

The TRACE32 proxy handles Restart by resetting through Remote API and resuming. It returns empty Locals lists to avoid crashes in some t32debugadapter versions on FreeRTOS interrupt frames; registers, stack, watch expressions, breakpoints and stepping remain available.

Generated files contain absolute rvdbg/config paths. Regenerate after moving the project or executable.

RustRover / JetBrains (TRACE32)

Install LSP4IJ, then run:

rvdbg rustrover

This creates .run/TRACE32 Attach.run.xml. Select TRACE32: Attach and Debug; LSP4IJ starts and connects to the DAP proxy. For StellarLINK use VS Code/Cortex-Debug or GDB.

Keep the service running in one terminal:

rvdbg --backend openocd debug

In another, load the actual primary image and connect on the default port:

arm-none-eabi-gdb build/el2.elf -ex 'target extended-remote :3333'

The service normally stops when GDB detaches; rvdbg debug --keep runs until Ctrl-C. Reusing a session’s OpenOCD leaves its lifetime under that session’s control. Load extra image symbols yourself in a manual GDB session; generated VS Code configuration does this for extra_elf.

gdb_target selects the debug core; inspection core can differ, as explained in configuration. External halt/resume commands affect the same core GDB is debugging; these are not isolated sessions.

Interactive commands

Run bare rvdbg. The following is illustrative; prompts depend on the backend and target state:

$ rvdbg
rvdbg [...]> status
rvdbg [...]> halt
rvdbg [...]> fault
rvdbg [...]> mem my_buffer 4
rvdbg [...]> go
rvdbg [...]> quit

Use help [command], Tab completion, backend trace32|openocd, reconnect, and quit/exit. Use reconnect after changing probes. History lives in .rvdbg/history. Ctrl-C interrupts waiting RTT/FDX/run-until commands without ending the session; command failures also leave it open.

A StellarLINK session keeps one OpenOCD shared by commands and GDB. TRACE32 inspection, ram and fdx share a lazily established connection. Failure drops it; the next command reconnects, without replaying the failed command. flash, load and open manage connections separately.

Custom TRACE32 operations

rvdbg eval 'Register(PC)'
rvdbg cmd 'Break.Set my_function /Program /Onchip'
rvdbg do scripts/trace_setup.cmm

eval evaluates expressions, cmd executes PRACTICE commands and do runs a script and waits. Scripts stopped by errors are cleaned up and reported; dialogs and STOP remain for the operator. Effects depend on content and may include register writes, reset and flashing.

See inspection for trace setup/export and troubleshooting for missing sources, ports and busy scripts.


Inspect the target and run checks

中文

Decide whether you need execution state, fault context, program contents or an application condition. Inspection does not automatically halt to satisfy a read; check --halt is an explicit exception.

TRACE32 needs a running PowerView. StellarLINK reuses an OpenOCD Tcl service or starts one without reset. Use troubleshooting on connection failure before resetting a useful fault scene.

From execution state to a fault report

rvdbg status
rvdbg halt
rvdbg status
rvdbg fault

The first command observes state; halt explicitly changes it. When halted, status reports PC, symbol offset and decoded CPSR. fault reports AArch32 Hyp exception context: vector, HSR, HDFAR/HIFAR, ELR_hyp and SPSR_hyp. An arbitrary halt does not establish that a valid Hyp fault occurred.

StellarLINK core/coprocessor reads require a halted core; Hyp registers additionally require EL2. Failure while halted in Guest EL1 does not imply absent register values. Break at a suitable hypervisor location. TRACE32 can substitute HC15: for some Hyp reads from EL1; StellarLINK cannot.

After recording the result, decide whether to resume, reset or redeploy using debugging commands.

One value or a RAM buffer?

CommandIntended objectUnits and restrictions
mem <address-or-symbol> [count]A few memory words, TRACE32 address classes, supported coprocessor addressesDefaults to one 32-bit word
ram <address-or-symbol> [count]Known valid ordinary RAMBulk aligned 32-bit words; never MMIO/coprocessors
ram <address-or-symbol> --write <values…>Write ordinary RAMChanges target memory; confirm ownership/address
reg <names…>TRACE32 PER registers/fieldsCase-sensitive; full path may be necessary
rvdbg mem my_buffer 4
rvdbg ram my_buffer 64 --json
rvdbg --backend trace32 reg HSR HSCTLR.C

ram accesses TRACE32 AD: or StellarLINK MEM-AP while cores run. Alignment/range checks cannot establish that an address is ordinary RAM; consult the project’s layout. A multiword buffer concurrently updated by firmware is not necessarily a consistent snapshot. Use a firmware protocol or explicit halt as appropriate.

For ordinary RAM you control:

rvdbg ram my_buffer --write 0x12345678 0

Read MMIO with mem or project checks, after checking register semantics. A read-clear register can change hardware state even without an explicit write command.

TRACE32 reg resolves PER names/fields and reads through PowerView. Ambiguous names with different addresses produce candidate paths; use a full path. watch opens PER.Watch on supporting PowerView versions; displaying a window is not an acceptance record.

Turn observations into check files

Keep checks in the firmware project, for example checks/boot.toml. This example assumes a real idle_loop symbol:

description = "Stopped at the idle loop"

[[check]]
name = "PC is in the idle loop"
read = { core = "PC" }
expect = { in_symbol = "idle_loop" }
rvdbg check checks/boot.toml --dry-run
rvdbg check checks/boot.toml --halt

--dry-run resolves names/symbols without target reads; parsing success does not establish acceptance. --halt halts when core/coprocessor reads need it and leaves the core halted. Resume explicitly with rvdbg go.

Read formBackend
read = { addr = "AD:0x..." }Both, subject to supported address classes
read = { core = "PC" }Both; halted core required
read = { clock = "CORE" }Both; clock description required
read = { reg = "SCTRL" }TRACE32 PER
read = { expr = "..." }TRACE32 PRACTICE

Numeric predicates include eq, ne, nonzero, range, in_symbol, one_of, with mask where applicable. eq/ne/one_of accept "sym:name+offset". variants = ["debug"] selects checks for a variant:

rvdbg check checks/boot.toml --variant debug --json

Exit codes are 0 for all conditions met, 3 for executed checks that fail, and 1 for execution errors. The public check example includes fictional registers/values and older tracebridge command examples. With rvdbg, use rvdbg check and real project conditions.

verify checks ELF load contents; check evaluates current observations. See flashing and verification.

Clock trees and board inputs

rvdbg clock
rvdbg clock XOSC=40MHz
rvdbg --backend trace32 clock --html

Choose a description with --tree or match the configured chip against the local rvdbg/clock library. [clock] provides facts unavailable from registers, such as crystal frequency; command arguments can override inputs temporarily.

Output shows source, frequency and calculation. off means disabled; ? means missing inputs or unknown sources. Warnings such as not locked come from description rules. Read failures mark affected clocks as errors and return 1. Accuracy depends on both sampled registers and correct formulas/board inputs.

TRACE32-only --html creates .tracebridge/clock.html with module and active-source views. Use the fictional clock example for syntax, real chip manuals for formulas, and respect material licensing.

Export recorded trace (TRACE32)

rvdbg does not configure ETM or board trace hardware. Use a project script, run to the desired point, then export while halted:

rvdbg halt
rvdbg do scripts/trace_setup.cmm
rvdbg run-until batch_done --timeout 30
rvdbg trace --last 3000 --json > trace.json

The script and symbol must exist in your project. fault --trace attaches recent records. rvdbg exports existing PowerView records, resolves symbols again and leaves the raw export in .tracebridge/trace.ad. Cycle columns need cycle-accurate trace configuration; address records alone cannot establish cycle counts.


RTT logs and FDX communication

中文

RTT and FDX exchange data through target RAM while firmware runs. TRACE32 uses runtime access, usually requiring dual_port = "ON"; StellarLINK uses the configured MEM-AP. Firmware must implement and initialize its buffers; host commands do not create a firmware protocol.

NeedUse
Continuous character logs or terminal inputRTT channel 0
Send a packet and wait for an agreed replyFDX
Inspect ordinary RAM directlymem / ram

RTT: locate the control block

rvdbg rtt
rvdbg rtt --output-only
rvdbg rtt --replay

The default symbol is _SEGGER_RTT. --output-only disables keyboard forwarding. --replay resets the up-channel read offset to zero to display buffered contents; it is not a full historical log replay. Ctrl-C exits and restores terminal settings.

Configuration and temporary overrides:

[rtt]
symbol = "_SEGGER_RTT"
control_block_address = ""
poll_interval = 0.02
rvdbg rtt --symbol _SEGGER_RTT --poll 0.02
rvdbg rtt --cb 0x60000000 --output-only

Replace the example address with the actual control-block address. --cb bypasses symbol lookup, not missing firmware initialization, unreadable memory or cache coherency issues. TRACE32 also needs the correct project.program. See troubleshooting if it keeps waiting.

rustvisor uses FDX BufferE links, normally named RUSTVISOR_FDX. Two adjacent channels in a static region carry traffic to the target and to the host. Both backends can access them through RAM.

rvdbg fdx
rvdbg fdx --guest 0

The first command uses the primary ELF. --guest 0 means the first project.extra_elf entry, not VMID 0 or hardware core 0. In interactive mode each input line is one packet, and received packets print one per line. The terminal follows a link reopened after target reset.

--symbol selects another symbol; --address bypasses symbol lookup. See configuration for image selection. A supplied address must identify a valid FDX link.

Scripted packets and timeouts

These messages are examples for firmware implementing that protocol:

rvdbg fdx --send "boot single" --expect "ok boot" --timeout 10 --json

All --send packets are sent in order, followed by all --expect waits in order. Repeat either option for multiple packets. --timeout applies separately to link opening, send space and each expected packet; it is not a total command deadline. Missing an expected packet returns 3.

FDX transports messages; firmware defines their effects, which may include booting, measurement or state changes. --json only changes output formatting. See automation for result handling.

Buffer ownership

Only one host program may drive an FDX link at a time. Do not share it concurrently among a board runner, rvdbg fdx and PowerView FDX.* windows. Avoid competing RTT readers updating the same channel read offset too.

rvdbg fdx --close modifies RAM to mark a link closed. It is for the specific case where a board is held in reset and RAM retains an old open link, not a general host-disconnect button. Do not use it while firmware or a runner owns the link.


Scripts, JSON and AI agents

中文

Distinguish single commands, judged by process exit code, from persistent pipe sessions, judged by each command’s end record. Fix the configuration and images, record the rvdbg version, and bound waits in both cases.

Single commands: check the exit code

rvdbg status --json
rvdbg verify --json
rvdbg check checks/boot.toml --variant debug --json

Put --json after command arguments, especially for cmd, eval and do, which consume remaining text. Inspection uses an envelope like this; result depends on the command:

{"command":"ram","ok":true,"exit_code":0,"result":{"symbol":null,"address":"0x60000000","words":[1],"hex":["0x00000001"]}}

This is a format example, not a board observation. --json does not guarantee JSON-only stdout for every command or failure stage. Early configuration errors may only appear on stderr; do not merge stderr into JSON input.

CodeMeaningHandling
0Completed, conditions metParse the result as needed
1Execution failurePreserve errors; distinguish config, connection and read failures
2Usage errorFix arguments rather than retrying target operations
3Executed but unexpected resultPreserve differences or failed conditions; not a connection failure

Code 3 includes verify differences, failed checks, run-until stopping elsewhere and FDX expected-packet timeouts. Do not blindly retry flash, reset or protocol messages: retries change the target again.

A read-only status client:

import json
import subprocess

completed = subprocess.run(
    ["rvdbg", "status", "--json"],
    capture_output=True, text=True, timeout=15,
)
if completed.returncode != 0:
    raise SystemExit(completed.stderr or completed.stdout)
report = json.loads(completed.stdout)
if not report["ok"]:
    raise SystemExit(report)
print(report["result"])

For commands returning 3, save structured stdout before classifying the exit code. Flashing needs a deadline covering real programming time; do not copy the 15-second example unchanged.

Multiple commands: an NDJSON pipe session

rvdbg --json enables machine sessions when stdin is a pipe rather than a terminal:

printf '%s\n' 'status' 'quit' | rvdbg --json

It emits ready first, then executes commands line by line, appending end after each command’s own output. The following omits command results and uses illustrative values:

{"ready":true,"version":"0.1.25","config":"/work/project/rvdbg.toml","backend":"openocd","reason":"..."}
{"end":"status","ok":true,"exit_code":0,"error":null}
{"end":"quit","ok":true,"exit_code":0,"error":null}

ready: true means the protocol loop started, not that target checks passed. Check backend, connection information and actual results. An undetermined backend can be null.

Drive the process as follows:

  1. Read ready and confirm version, configuration path and backend.
  2. Write one command and flush; collect output through its corresponding end.
  3. Inspect ok, exit_code and error before deciding the next operation.
  4. Send quit or close stdin, then wait for exit and collect stderr.

Inspection, ram and single-shot FDX provide structured output. flash and load may still emit progress text. Preserve these lines as logs and recognize agreed JSON record types rather than assuming identical structure on every line. Continuous rtt/bare fdx are unsuitable as normal requests in this loop; use bounded FDX operations.

A session can exit 0 on EOF even after a command failed. Consume every end record. Failed commands do not stop the input loop. If failure should abort a sequence, wait for end before sending the next command rather than queueing destructive operations upfront.

Apply deadlines to startup, commands and shutdown. Drain stderr continuously to avoid filling a log pipe. After connection loss inspect target state before replaying operations.

rustvisor-sdk board runner

The current SDK integration drives installed rvdbg (at least 0.1.24, or the runner’s RVDBG executable override) through rvdbg --json, using one session per flash. ELF, EXTRA_ELF and PROGRAM_NAME select images; the test plan belongs to the SDK runner.

Use ready/end and command results as the interface, not colored tables. Record images, configuration, version and reports to distinguish content matches, acceptance conditions and correct application behavior. The Rust backend integration document describes a different path from the SDK’s current subprocess integration.

AI agents

rvdbg skill
rvdbg skill --dir /path/to/agent/skills

The default destination is $CLAUDE_CONFIG_DIR/skills or ~/.claude/skills. Reinstall after upgrading rvdbg. The skill explains command selection, backend restrictions and confirmation requirements for state changes. Agents must not add --write-otp automatically.

Lauterbach t32mcp handles general TRACE32 breakpoints, stepping, stacks and interactive debugging; rvdbg handles deployment, specialized inspection, verification, clocks and RAM/FDX workflows. They share PowerView, which runs one PRACTICE script at a time. StellarLINK uses rvdbg/GDB; see debugging.

If granting agents confirmation-free commands, restrict actual arguments using the operation effects. check accepts --halt and ram accepts --write; broad prefixes cannot classify all calls as read-only.


Troubleshoot by symptom

中文

Preserve errors and target context before deciding whether the problem is configuration, service, probe or target. rvdbg config describes the intended operation; rvdbg status observes execution. Resetting first can destroy the fault scene.

No probe, or the wrong backend

For no probe found or unexpected selection, inspect discovered USB devices, PowerView and fixed backend settings with rvdbg config. Both probes default to TRACE32; choose rvdbg --backend openocd ... for StellarLINK. In an interactive session, run reconnect after changing probes.

Explicit selection bypasses discovery, not physical connection requirements. A successful target-state read is the next confirmation. See configuration.

TRACE32 port responds but connection fails

Symptoms include no PowerView on RCL port ..., not a usable TRACE32 RCL endpoint, or startup never becoming ready.

  • If PowerView is absent, run rvdbg open before inspection.
  • If config.t32 defines RCL=, confirm NETTCP and a PORT= matching trace32.rcl_port.
  • If the port belongs to another service, identify the listener rather than treating it as Remote API.
  • Check .tracebridge/powerview.log, installation paths and startup configuration.

Keep local-access restrictions enabled. See quick start and configuration.

OpenOCD fails to start or reuses another session

Inspect executable, board scripts and ports with rvdbg config, then read .rvdbg/openocd.log. Confirm openocd-stellar, available scripts, target power and probe wiring.

rvdbg reuses existing Tcl services. Avoid accidental shared ports across projects and do not terminate an unidentified debugging service just to clear a conflict. Assign separate ports and re-establish the intended connection.

Command or option is TRACE32-only

On ... is available with TRACE32 only, check the chosen backend. PER names, PRACTICE, trace and clock HTML have no direct StellarLINK equivalents. Use verified addresses or check files where appropriate; a PER name is not a physical address. See the capability table and inspection.

Core or Hyp registers are unreadable

For ... can only be read while the core is halted, distinguish memory from core state. Explicitly use rvdbg halt or check --halt when needed. StellarLINK Hyp reads additionally require EL2; break at a suitable hypervisor location. An EL1 read failure does not imply zero Hyp registers. check --halt leaves the core halted; see inspection.

PowerView is busy

flash, load, reset and do refuse to overwrite an active PRACTICE script. Another tool may own it, or it may be stopped at a dialog, STOP or an error. Identify it in PowerView and wait; if abandonment is intended, the operator should end it before retrying.

Increasing timeouts does not resolve script-stack contention. See debugging.

Flash timeout, differences or OTP refusal

SymptomNext step
Programming is still progressingCheck trace32.operation_timeout / openocd.timeout; inspect TRACE32 AREA output
verify returns 3Save the first differing address; check local images, load addresses and the complete image set
Another image disappearedCheck extra_elf, especially TRACE32 full-range erase behavior
OTP differsCheck boot records, protection ranges and whether any change was intended

Neither --no-verify nor --write-otp is a general retry option. See flashing.

IDE shows only assembly, or wrong breakpoints

Confirm ELF/target agreement, then check DWARF line information. Rust release builds can enable debug = true; rebuild and verify/redeploy normally rather than assuming the resulting ELF still matches the board.

TRACE32 must load correct symbols; GDB must load primary and extra ELF symbols. Regenerate IDE files after moving the project. Empty TRACE32 Locals is deliberate proxy behavior; see debugging.

RTT is silent or FDX receives no reply

Confirm firmware initialization, symbols/addresses and the TRACE32 program name for RTT. --cb only bypasses lookup.

For FDX, check the primary/--guest N image, implemented message protocol, exclusive ownership, expected reply and timeout. Do not repeatedly send state-changing packets to an unknown link. See channels.

A script succeeds despite a failed check

In rvdbg --json pipe mode, inspect every end record. Process exit 0 can mean only that the input loop ended normally, even after a command returned 3. Use single-shot commands or implement per-command result handling.


Maintain this guide

中文

Chinese task pages are flat within docs/guide/cn/, with matching English files under docs/guide/en/. Each language is its own mdBook with its own SUMMARY.md and book.toml; the root README.md is the language entry on GitHub and in Obsidian, and site/ holds the language page of the website. Keep short topics in one file; add directories only for substantial independently maintained topics. README.md provides entry points and SUMMARY.md the mdBook order; neither replaces the content.

Follow one concrete operation

State project, backend, images and endpoints. Explain prerequisites, commands, target effects, expected results and next steps on failure. Put backend differences beside the affected step.

Explain side effects at first use, distinguishing flash, reset, halt, symbol loading, live RAM and firmware messages. Ordinary RAM examples do not generalize to MMIO. Mark sample addresses, symbols, messages and fictional registers that must be replaced.

Check behavior against current CLI definitions, initialization template, configuration parser, session protocol and backend implementation. Links to main track the main branch; select the appropriate tag/commit for a specific release.

Source and simulated tests establish implementation/expectations, not a successful board run. Hardware claims need dates, images, backend, criteria and evidence locations. Guide examples are not measurement records.

Use standard relative Markdown links such as [configuration](configuration.md) across GitHub, mdBook and Obsidian. Keep one primary explanation of each behavior and link to it where needed.

Open docs/guide/ as an Obsidian vault and use Markdown link format. At build time tools/docs/links.py adds “Referenced by” to English pages and “引用此页” to Chinese pages. It changes build content only and does not count generated backlinks as new references.

Add every page to SUMMARY.md; validation rejects omissions, duplicates and broken local destinations. Use repository web URLs for sources/examples outside the guide. Reference links are supported; fenced/inline code examples do not count as references.

Maintain matching filenames and coverage in both languages, and keep direct language-switch links. Links into the other language (../cn/…) are allowed only as language switches: they are checked but produce no backlinks. All other links stay within the book.

Build and check locally

Run at repository root with Python 3.10+ and mdBook 0.5.4. These are documentation dependencies, not rvdbg runtime dependencies:

cargo install mdbook --version 0.5.4 --locked
python3 -m venv target/docs-venv
. target/docs-venv/bin/activate
python -m pip install -r tools/docs/requirements.txt
python -m unittest discover -s tools/docs -p 'test_*.py'
tools/docs/build.sh

build.sh builds both books and the language page into target/guide/ and checks every rendered link: open index.html to choose a language, cn/index.html for Chinese, or en/index.html for English. For live rebuilding of one book use mdbook serve docs/guide/en --open (language switches then point at the other book, which serve does not build). The published site is https://rvdbg.docs.haoyichen.com; CI deploys it from main, locally cd docs && npx wrangler deploy after build.sh. Keep the virtual environment active because mdBook invokes python3 for the preprocessor. See the mdBook preprocessor documentation.

Check navigation, backlinks and long tables visually, then run git diff --check. HTML checks cover local files and fragments, not external site availability or board behavior.