Import
Methods
The Net-based API provides methods for embedded debugging operations.Method Reference
Net.get(name, type=NetType.Debug)
Get a debug net by name.
Returns: Debug Net instance
Note: The debug net must be configured with the target device name stored in the
channel field (e.g., ‘NRF52840_XXAA’, ‘R7FA0E107’).
connect(speed=None, transport=None, *, script=None, force=False, ignore_if_connected=False)
Connect to the target device (start the gdbserver for this probe). The backend
(J-Link or OpenOCD) is chosen automatically from the probe.
Returns:
dict - Status dictionary with connection information
A
script override is only adopted by a relaunch of the gdbserver. If a server
is already running, pass force=True to restart it with the new script;
ignore_if_connected=True returns early without relaunching (though the script
file is still repointed for subsequent Commander operations). Invalid input — a
missing path that isn’t valid base64, or an empty string — is silently ignored and
the net’s previously materialised script stays in effect. Concurrency caveat:
two debug nets connecting with different scripts share one temp path and can clobber
each other.disconnect()
Disconnect from the target device.
dict - Status dictionary
reset(halt=False)
Reset the device.
Returns:
str - Combined output from reset operation
Self-heal (both backends): Right after a flash() there is a short window where the debug server isn’t reachable yet — for J-Link the restarted GDB server’s PID isn’t observable, for OpenOCD a transient daemon/RPC fault — and a bare call would raise. reset() now retries with bounded backoff on both the J-Link and OpenOCD backends, and only (re)starts a server when one is genuinely down. It never tears down a server that is already running, so an attached RTT session is left intact, and callers no longer need their own retry wrappers.
DA1469x exception: On DA1469x, flash() deliberately leaves the server down (it ends in a software reset rather than a server restart) and the documented flow is an explicit, halt-aware reconnect. So on DA1469x the self-heal retries but never auto-starts a server — a genuinely-down server still surfaces the original error, exactly as before, instead of silently coming up unhalted (which can yield garbage QSPI-XIP reads).
flash(firmware_path)
Flash firmware to the device.
Returns:
str - Combined output from flash operation
Note: For .bin files, flash address defaults to 0x00000000.
erase()
Perform full chip erase. This erases ALL flash memory including protection settings.
str - Combined output from erase operation
read_memory(address, length)
Read memory from the target device.
Returns:
bytes - Memory data
Self-heal: like reset(), read_memory() retries with bounded backoff across the brief post-flash() settling window on both backends and only reconnects when no server is running, never disturbing a live session. erase() behaves the same way. The same DA1469x exception applies — no server is auto-started, so a post-flash DA1469x read raises clearly rather than returning unhalted-XIP garbage.
status()
Get the current connection status.
dict - Status dictionary with connection information
session(speed=None, transport=None, connect=True, ignore_if_connected=True, disconnect_on_exit=True)
Scoped debug session. Connects on entry and guarantees teardown on exit, so the safe flash → attach-RTT → reset ordering is encoded once instead of being rediscovered in every script. The with target is the net itself, so the full surface (flash, rtt_defmt, reset, read_memory, …) is available inside the block.
Returns: a context manager yielding the debug net.
Why it pairs with RTT: the in-process RTT reader is reconnect-aware (see below), so a
flash() or reset() inside the session that bounces the GDB server doesn’t kill a log stream opened in the same block.
rtt(channel=0, search_addr=None, search_size=None, chunk_size=None)
Create an RTT (Real-Time Transfer) session for bidirectional communication with the target device.
Returns: RTT context manager with methods:
read_some(timeout)- Read available data with timeout (returns bytes or None)write(data)- Write data to target (accepts bytes or str)
connect() first.
Reconnect-aware (both backends): a J-Link flash() (and reset() via its Commander grab) briefly frees the probe’s USB and restarts the GDB server on the same ports, dropping the RTT socket. The reader transparently re-attaches to the same RTT telnet port instead of going silent, so a long-lived read_some() / rtt_defmt() loop keeps producing across a flash. The OpenOCD reader is reconnect-aware too — OpenOCD keeps its daemon up across an ordinary flash so the socket rarely drops, but if it does (daemon force-restart or rtt-server bounce) the reader re-runs the rtt setup / rtt server start and re-attaches. In both cases reconnection is bounded (default 30 s) and only re-attaches once the server/daemon is actually back up — it never starts one — so a flash that deliberately leaves the server down (e.g. DA1469x) won’t spin forever, and the reader can’t disturb a DA1469x left intentionally down. Pass reconnect=False for the legacy one-shot behavior.
Examples
Flash Firmware and Reset
Chip Erase Before Programming
Read Memory
CLI Commands (Recommended)
For most use cases, the CLI provides a simpler interface:RTT Streaming
SEGGER Real-Time Transfer (RTT) enables high-speed bidirectional communication with embedded devices during debugging (faster than UART, no timing impact).Decoding defmt logs with rtt_defmt()
rtt_defmt(elf, channel=0) opens an RTT session and pipes it through defmt-print (preinstalled on the Lager Box), yielding decoded log lines instead of raw bytes. The elf must be the exact firmware flashed on the target — defmt needs its symbol metadata to decode.
rtt_defmt() returns a context manager exposing:
Like the CLI pipe, the RTT stream never ends on its own — bound your read loop with a time budget or line count, then exit the
with block.
Parameters:
CLI Alternative: For interactive tailing, pipe the CLI directly:
lager debug <net> gdbserver --box <box> --rtt 2>/dev/null | defmt-print -e build/app.elf. See the CLI Debug Reference. Use rtt_defmt() when you need to assert on log content inside a test script; use the pipe when you just want to watch logs.
Supported Devices
J-Link supports a wide range of ARM Cortex-M and other microcontrollers. Common device names:
For a complete list, see SEGGER’s supported devices.
Supported Hardware
Notes
- Debug nets must be configured with the target device name in the
channelfield - The CLI (
lager debug) is recommended for most use cases - Python Net API is intended for advanced automation scripts running on the Lager Box
- Always call
disconnect()when finished to release the debug probe - Use
erase()to perform a full chip erase and clear protection settings - RTT requires an active debug connection (see RTT Streaming section above)

