
Probe Rs
Flash, debug, and inspect embedded targets with probe-rs using the same JSON workflow shape as J-Link and OpenOCD in embeddedskills.
Overview
Probe-rs is an agent skill for the Build phase that orchestrates probe-rs CLI flash, memory, GDB, and RTT operations with embeddedskills JSON workflows.
Install
npx skills add https://github.com/zhinkgit/embeddedskills --skill probe-rsWhat is this skill?
- Probe discovery, target info, flash, erase, and reset via list/info/flash/erase/reset
- Memory read/write helpers for scripted bring-up checks
- One-shot GDB debugging through probe_rs_gdb.py with shared JSON result shape
- RTT observation via probe_rs_rtt.py for log streaming without extra UART wiring
- Project-level .embeddedskills/config.json for chip, SWD/JTAG, probe, and speed
- Third debug backend alongside jlink and openocd
- Default DAP port 50000 and GDB port 3333 in bundled runtime example
Adoption & trust: 1 installs on skills.sh; 340 GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
What problem does it solve?
You have firmware artifacts and a debug probe but no consistent agent-driven path to flash, reset, and inspect the target like your other debugger backends.
Who is it for?
Solo embedded builders standardizing on embeddedskills who want probe-rs as a peer backend with scripted flash-and-debug steps.
Skip if: Pure host-only web or mobile projects with no on-chip debugging, or teams that require interactive DAP sessions this skill deliberately does not expose.
When should I use this skill?
You need to list probes, flash or erase firmware, reset the target, run one-shot GDB, or stream RTT via probe-rs inside embeddedskills workflows.
What do I get? / Deliverables
Your agent runs probe-rs commands through shared wrappers and returns structured JSON for flash, debug, and RTT steps inside the same workflow as J-Link and OpenOCD.
- JSON command results with timing for flash, debug, and RTT operations
- Repeatable workflow steps matching jlink/openocd orchestration
Recommended Skills
Journey fit
Firmware bring-up and on-target debugging sit on the build phase when hardware and toolchain integration are the bottleneck. probe-rs is a third-party CLI backend wired into project config and workflows—classic integrations subphase tooling.
How it compares
Skill-packaged workflow wrapper around the probe-rs CLI—not a replacement for SEGGER J-Link GUI workflows or a cloud flash service.
Common Questions / FAQ
Who is probe-rs for?
Indie firmware developers using embeddedskills who need probe-rs for SWD flashing, GDB one-shots, and RTT logs with JSON-friendly automation.
When should I use probe-rs?
During Build integrations work when bringing up a board, automating flash-after-build, or validating memory and reset behavior before ship-stage hardware QA.
Is probe-rs safe to install?
Check the Security Audits panel on this page; flashing and memory writes can brick or corrupt devices, so review scripts and probe driver changes (including WinUSB) before running on production hardware.
SKILL.md
READMESKILL.md - Probe Rs
{ "exe": "probe-rs", "gdb_exe": "C:\\Program Files\\Arm\\GNU Toolchain mingw-w64-x86_64-arm-none-eabi\\bin\\arm-none-eabi-gdb.exe", "gdb_port": 3333, "dap_port": 50000, "operation_mode": 1 } # probe-rs `probe-rs` skill 为本仓库新增的第三调试后端,目标是和现有 `jlink`、`openocd` 保持同一套 JSON 输出和 `workflow` 编排方式。 ## 能力范围 - 探针发现:`list` - 目标信息:`info` - 烧录/擦除/复位:`flash` `erase` `reset` - 内存访问:`read-mem` `write-mem` - one-shot 调试:`probe_rs_gdb.py` - RTT 观测:`probe_rs_rtt.py` ## 配置示例 环境级 `config.json` 可参考 config.example.json。 工程级 `.embeddedskills/config.json`: ```json { "probe-rs": { "chip": "STM32F407VGTx", "protocol": "swd", "probe": "", "speed": 4000, "connect_under_reset": false } } ``` ## 重要说明 - `probe-rs` 默认依赖外部官方 CLI,不在本仓库内代管安装器 - `workflow` 中的 `probe-rs` 只接入 one-shot 调试,不直接暴露交互式 DAP 会话 - Windows 下如需让 `probe-rs` 访问 `J-Link`,通常需要将驱动切换到 `WinUSB`;这可能导致 SEGGER 官方工具不可用 """probe-rs 基础操作与包装命令。""" from __future__ import annotations import argparse import os import re import subprocess import sys import time from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent if str(SCRIPT_DIR) not in sys.path: sys.path.insert(0, str(SCRIPT_DIR)) from probe_rs_runtime import ( build_artifacts, default_config_path, get_state_entry, hidden_subprocess_kwargs, is_missing, load_json_file, load_project_config, load_workspace_state, make_result, make_timing, normalize_path, now_iso, output_json, parameter_context, save_project_config, update_state_entry, workspace_root, ) ALL_ACTIONS = ["list", "info", "flash", "erase", "reset", "read-mem", "write-mem", "attach", "run"] ERROR_PATTERNS = [ (r"no probes were found", "no_probe_found", "未检测到调试探针,请检查 USB 连接和驱动"), (r"multiple probes were found", "multiple_probes", "检测到多个探针,请通过 --probe 显式指定"), (r"chip.*not found", "chip_not_found", "未找到目标芯片描述,请确认 --chip 配置"), (r"failed to open probe", "probe_open_failed", "打开调试探针失败,请检查探针占用、驱动和 USB 连接"), (r"failed to open the debug probe", "probe_open_failed", "打开调试探针失败,请检查探针占用、驱动和 USB 连接"), (r"error while probing target", "probe_open_failed", "打开调试探针失败,请检查探针占用、驱动和 USB 连接"), (r"unexpected answer to command", "probe_protocol_error", "探针返回异常响应,请检查固件、驱动和链路稳定性"), (r"failed to attach", "attach_failed", "连接目标失败,请检查供电、连线和芯片型号"), (r"permission denied", "permission_denied", "访问调试探针被拒绝,请检查驱动和权限"), (r"address.*out of bounds", "address_out_of_range", "访问地址超出范围,请确认地址和数据宽度"), (r"timed out", "timeout", "操作超时,请检查连接和速度配置"), ] def infer_binary_format(file_path: str) -> str: suffix = Path(file_path).suffix.lower() if suffix == ".bin": return "bin" if suffix in {".hex", ".ihex"}: return "hex" if suffix == ".uf2": return "uf2" return "elf" def parse_output(text: str, action: str) -> dict: parsed = {"raw": text} for pattern, code, message in ERROR_PATTERNS: if re.search(pattern, text, re.IGNORECASE): return {"error_code": code, "error_message": message, "raw": text} if action == "list": probes = [] for line in text.splitlines(): item = line.strip() if not item or item.lower().startswith("the following debug probes were found"): continue probes.append(item) if probes: parsed["probes"] = probes elif action == "read-mem": words = re.findall(r"\b[0-9a-fA-F]{2,16}\b", text) if words: parsed["words"] = words elif action == "info": chip_match = re.search(r"chip[:=]\s*([^\r\n]+)", text, re.IGNORECASE) probe_match = re.search(r"probe[:=]\s*([^\r\n]+)", text, re.IGNORECASE) if chip_match: parsed["chip"] = chip_match.group(1).strip() if probe_match: parsed["probe"] = probe_match.group(1).strip() return parsed def _summary(action: str, parsed: dict, fallback: str) -> str: if action == "lis