Skip to main content
Drive a debug probe from a cargo test: connect, flash firmware, reset the target and read its memory. Debug nets are the one net type that does not talk to the box’s API on port 9000. They reach the box’s debug service on port 8765 instead.

Handle

The net’s saved record is fetched once on first use and cached on the handle. The cache is dropped whenever an operation fails, so a re-saved net is picked up on the next attempt rather than needing a new handle.

Methods

RTT streaming lives on the same handle and is covered in RTT.

Types

ConnectOptions

Default sets gdb: true and everything else off, so connect() starts a GDB server. This is the one field where the default is not false.

FirmwareKind

Method Reference

connect() -> Result<DebugConnection>

Connect using ConnectOptions::default().
Returns: DebugConnection, carrying the device, probe, serial, backend, and a GdbServer with the ports that were opened. On a J-Link these come back as gdb 2331, SWO 2332, telnet 2333 and RTT telnet 9090; tcl_port is OpenOCD-only and is None on a J-Link, just as swo_port is J-Link-only.

connect_with(opts: &ConnectOptions) -> Result<DebugConnection>

Connect with explicit options.

disconnect(keep_running: bool) -> Result<()>

Disconnect. Pass true to leave the gdbserver up for an external GDB client to attach to; pass false to tear it down.

reset(halt: bool) -> Result<()>

Reset the target. halt: true leaves it stopped at the reset vector.

erase() -> Result<()>

Mass-erase the target’s flash.
erase() drops the debugger connection. The next read_memory() fails with Error::Box and No debugger connection found. flash re-establishes on its own, so an erase-then-flash sequence works, but an erase-then-read does not — call connect() again first.

flash(firmware_path) -> Result<()>

Flash a file, inferring the type from its extension: .hex, .elf or .bin. An unrecognised extension is Error::Config.
A .bin is flashed at 0x08000000, the STM32 application base. On any other family that address is wrong, and the call still returns Ok(()) — verified on an nRF5340, where flash() of a .bin succeeded while flash at 0x0 stayed erased. This is a silent wrong result, not an error. Off STM32, use flash_bin() with the correct base address.

flash_bin(firmware_path, address: u32) -> Result<()>

Flash a raw binary at an explicit base address. This is the correct call for any target whose application does not start at 0x08000000.

flash_bytes(contents: &[u8], kind: FirmwareKind, address: Option<u32>) -> Result<()>

Flash bytes you already hold, without writing them to a file first. address is used only for FirmwareKind::Bin and defaults to 0x08000000.

read_memory(address: u64, length: usize) -> Result<Vec<u8>>

Read length bytes from the target starting at address.
Requires a live connection: without one it fails with Error::Box and No debugger connection found.

info() -> Result<DebugInfo> and status() -> Result<DebugStatus>

info() reports the device, architecture, probe, serial and backend, plus whether a connection is live. status() reports just the gdbserver: whether one is running, its pid, and the probe serial. Both work without connecting first.

Examples

Flash and verify

Leave a gdbserver up for an interactive session

Supported Hardware

Notes

  • Timeout budgets are per operation and match the CLI: connect 30 s, flash 180 s, erase 120 s, memory read 30 s, and 10 s for info, status and disconnect.
  • Net resolution requires the debug role. A net that exists but is something else gives net 'adc1' exists but is not a debug net; a name that does not exist gives debug net 'nosuch' not found on this box.
  • The debug service does not use the same success envelope as the port-9000 API. A 200 is success; anything else is Error::Box carrying the service’s message.
  • Async note: AsyncDebugNet provides everything here, but no RTT.
  • A net configured with allow_destructive: false refuses erase() and flash() with Error::Box and HTTP 403. See Client and Box.