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
| Task | Read | Expected outcome |
|---|---|---|
| First use | Quick start | Install dependencies, configure, flash and inspect |
| Change images, probes or cores | Configuration | Identify effective images, backend and ports |
| Update code or symbols | Flashing and verification | Choose flash/load and handle multiple images |
| Breakpoints and stepping | Debugging | Connect an IDE/GDB and understand target state changes |
| Diagnose a running program | Inspection | Inspect PC, faults, memory, clocks and acceptance conditions |
| Logs and packets | RTT and FDX | Locate buffers and choose a transport |
| Scripts and agents | Automation | Interpret JSON, exit codes and session boundaries |
| Failed operations | Troubleshooting | Find 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
| Capability | TRACE32 | StellarLINK / OpenOCD |
|---|---|---|
| Flash, verify, status, halt and resume | Supported | Supported |
| IDEs | VS Code and RustRover/LSP4IJ over DAP | VS Code/Cortex-Debug and GDB |
| Ordinary RAM, RTT and FDX | Runtime access through AD: | Runtime access through MEM-AP |
| Debug symbols | rvdbg load | GDB reads the ELF |
| PER register names | reg, watch | Use addresses or check files instead |
| PRACTICE | eval, cmd, do | Unsupported |
| Trace export | trace, fault --trace | Unsupported |
| Clock diagram | clock --html | Text/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:
--backend trace32or--backend openocdon the command line.[project] backend = "trace32"or"openocd".- 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
| Section | Fields | Purpose |
|---|---|---|
[project] | elf, extra_elf, program, backend | Images, TRACE32 symbol program and backend |
[trace32] | sys, config, host, rcl_port | Installation, startup configuration and Remote API |
[trace32.target] | cpu, cores, mem_access, jtag_clock, dual_port | Target and runtime access |
[trace32.flash] | chip, script, args | Flash script selection and arguments |
[trace32.rtos] | config, menu, show_tasks | Optional RTOS awareness |
[openocd] | executable, config, search, commands | OpenOCD and board initialization |
[openocd] | tcl_port, gdb_port, gdb_target, core | Control connection, GDB core and inspection core |
[openocd] | memory_ap, timeout, otp | Physical memory access, operation timeout, OTP ranges |
[rtt] | symbol, control_block_address, poll_interval | Control block and polling |
[fdx] | symbol | Link 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.
StellarLINK cores and memory ports
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.
| Variable | Effect and empty values |
|---|---|
ELF, PROJECT_ROOT | Primary image or image-resolution root; empty ignored; the latter does not select a config file |
EXTRA_ELF | Shell-style image list; empty explicitly clears it |
PROGRAM_NAME | TRACE32 symbol program; empty applies |
T32_SYS, then T32SYS | Installation directory; empty ignored |
T32_HOST, T32_EXE, T32_BIN, T32_CONFIG, T32_DEBUG_ADAPTER | Host platform directory and executable paths; empty ignored |
T32_CPU, T32_CORES, T32_MEMACCESS, T32_JTAG_CLOCK, T32_DUALPORT | Target settings; empty applies |
T32_FLASH_CHIP | Script matching chip; empty ignored |
T32_FLASH_SCRIPT, T32_FLASH_ARGS | Explicit script and shell-style arguments; empty clears |
T32_RCL_PORT, T32_DAP_PORT, T32_DAP_BACKEND_PORT | Remote API and frontend/backend DAP ports |
T32_DAP_BACKEND_TIMEOUT, T32_TIMEOUT | Adapter and TRACE32 operation timeouts |
RTT_SYMBOL | RTT 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
| Location | Contents |
|---|---|
<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.
| Command | When to use | Target effect |
|---|---|---|
rvdbg flash | Program contents must change | Write Flash, reset and normally run |
rvdbg load | Load current ELF symbols into TRACE32 | No code write or reset; resume if needed |
rvdbg verify | Compare target contents with local ELF | Read 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.
StellarLINK: write, compare and run
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
| Command | Behavior |
|---|---|
rvdbg status | Inspect state without automatically halting |
rvdbg attach | Connect without reset, preserving running/halted state |
rvdbg halt | Halt the selected core |
rvdbg go | Resume the selected core |
rvdbg reset | Reset the chip and halt at the reset vector |
rvdbg run-until <symbol-or-address> | Run a halted core to a temporary hardware breakpoint |
rvdbg down | TRACE32 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:
| Configuration | Connection | Preparation and effects |
|---|---|---|
TRACE32: Attach | Hidden task starts rvdbg’s DAP proxy | PowerView running, symbols loaded |
StellarLINK: Attach | Cortex-Debug connects to rvdbg debug | Flash 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.
Direct GDB (StellarLINK)
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?
| Command | Intended object | Units and restrictions |
|---|---|---|
mem <address-or-symbol> [count] | A few memory words, TRACE32 address classes, supported coprocessor addresses | Defaults to one 32-bit word |
ram <address-or-symbol> [count] | Known valid ordinary RAM | Bulk aligned 32-bit words; never MMIO/coprocessors |
ram <address-or-symbol> --write <values…> | Write ordinary RAM | Changes target memory; confirm ownership/address |
reg <names…> | TRACE32 PER registers/fields | Case-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 form | Backend |
|---|---|
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.
| Need | Use |
|---|---|
| Continuous character logs or terminal input | RTT channel 0 |
| Send a packet and wait for an agreed reply | FDX |
| Inspect ordinary RAM directly | mem / 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.
FDX: each link belongs to an image
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.
| Code | Meaning | Handling |
|---|---|---|
| 0 | Completed, conditions met | Parse the result as needed |
| 1 | Execution failure | Preserve errors; distinguish config, connection and read failures |
| 2 | Usage error | Fix arguments rather than retrying target operations |
| 3 | Executed but unexpected result | Preserve 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:
- Read ready and confirm version, configuration path and backend.
- Write one command and flush; collect output through its corresponding end.
- Inspect
ok,exit_codeanderrorbefore deciding the next operation. - Send
quitor 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 openbefore inspection. - If
config.t32definesRCL=, confirmNETTCPand aPORT=matchingtrace32.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
| Symptom | Next step |
|---|---|
| Programming is still progressing | Check trace32.operation_timeout / openocd.timeout; inspect TRACE32 AREA output |
verify returns 3 | Save the first differing address; check local images, load addresses and the complete image set |
| Another image disappeared | Check extra_elf, especially TRACE32 full-range erase behavior |
| OTP differs | Check 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.
Links and backlinks
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.