firmware-debug
Skill2 starsChanged 2 months agoMITView on GitHub
Diagnose firmware failures using bounded target state, serial/RTT/BLE evidence and offline PC/LR-to-source lookup. Trigger for crashes, hangs, resets, missing output, bad peripheral behavior, register or stack inspection, breakpoint diagnosis and comparisons between target state and external observations.
In this repository4 other files it gives its agents.
- AGENTS.mdAGENTS.md
- embedded-bringupSkill
- hardware-testSkill
- incident-captureSkill
The file
We split this skill into the rules it gives an agent
12 rules. About 0 are common, 8 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
Prefer $embedded-debugger for target control, $baud for serial evidence, and $ble for BLE evidence when those Skills or MCP tools are …
- Very specific: line 69
If the project supplies .embedded/toolchain-lock.json, validate it with the installed toolkit's component_lock.py inspect, pass it to …
- Very specific: line 74
When a different lock is proposed, run component_lock.py compare first and surface every changed path, version, and hash before selecting …
- Very specific: line 76
Do not install or upgrade components during an active diagnosis unless the user explicitly changes the task to host setup.
- Distinctive: line 115
Keep clock domains and capture failures explicit.
- Distinctive: line 120
When evidence spans multiple transports, operations, or observation windows, read references/identity-ledger.md and preserve a …
- Distinctive: line 130
Keep USB-interface association, physical-board identity, target/core identity, firmware artifact identity, and current runtime identity as …
- Distinctive: line 132
Treat runtime attestation and target state as point-in-time evidence.
- Distinctive: line 152
Start with bounded, zero-transmit serial observation and read-only BLE evidence when those interfaces remain alive.
- Distinctive: line 158
Use the component debug Skill to establish an exact session and current core state.
- Distinctive: line 164
If symbols are used, bind the exact ELF hash and distinguish offline annotation from proof that the target runs that ELF.
- Distinctive: line 173
Delete only resources created by this workflow, close the exact sessions, and verify cleanup.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Firmware Debug
Prefer $embedded-debugger for target control, $baud for serial evidence, and
$ble for BLE evidence when those Skills or MCP tools are installed. Otherwise
use the corresponding component CLI with structured output. Preserve each
component's capability and safety limits instead of translating a successful
process exit into a hardware claim.
For already saved digital, voltage, load or thermal assertion evidence, read offline instrument workflows. Use native assertions and the matching Trace evidence view; sample-relative data has no verified UTC alignment with serial/RTT logs. Preserve the full verdict when filtering results. For saved load records, use load evidence to retain the original error, partial readings and unknown OFF state; historical cleanup and plausible values alone cannot establish the current physical fault. For saved thermal records, use thermal evidence to retain ROI/raw spans, FFC/mask trend limits and invalid pixels. Apparent surface temperature and moving maxima establish neither junction temperature nor causality.
For a failure reproduced in a supported Renode/QEMU model, read
optional simulation. Use the explicitly selected
sim-runner/HIL native CLI, preserve failed or partial UART and process cleanup,
and use its matching Trace version for offline simulated evidence. Retain model diagnostics and
passed_with_model_limits instead of flattening a qualified pass. A simulation-only diagnosis
needs no hardware discovery or attach. Do not infer a physical fault, radio or
electrical behavior from a simulated pass, or silently switch to a real board.
GPIO RunFor boundaries and guest timer captures remain separate from UART/host
event times; use the saved model observation spans when reviewing the raw source.
S3 uses the separate Xtensa backend with an unmeasured device clock; keep its
runtime/core declarations and native limitations when comparing it with C3/Renode.
For a saved or requested GPIO/TIMER0 fault experiment, read
model fault evidence. Keep injection requests,
observed/unknown effects and native regression failures distinct; raw counter/IRQ
spans describe the model, not a physical fault or confirmed root cause. Use the
published default for released components; select local candidate payloads only
when that recorded build is explicitly requested.
For signed-temperature, stale-read or fixed TMP103 model faults, read sensor simulation. Compare native guest samples and raw model observations; retain failed/null evidence and avoid inferring an electrical fault, sensor accuracy or physical root cause. For LM74 signed Q4, two-byte framing or SPI model faults, read SPI simulation. Keep raw words, paused model observations, frame-slip byte spans and failed/unknown nominal outcomes distinct; the monitor-byte fault does not establish an electrical or physical root cause. For watchdog reload failures or modeled reboots, read watchdog simulation. Keep native model, reset/callback and guest spans together; a failed regression with an observed effect establishes neither physical reset nor low-power behavior. For RTC0 compare stalls or masked interrupts, read RTC simulation. Distinguish frozen counters from pending events using saved model/guest spans; neither establishes a physical clock fault, wakeup failure or root cause. For EGU masked interrupts or task misrouting in the model, read EGU simulation. Compare event latches, enable masks and raw guest/model spans; a fault marker alone does not establish its effect. For GPIOTE edge/polarity or pending-event failures, read GPIOTE simulation. Compare CONFIG/current-state, input, event and ISR spans; modeled effects do not establish an electrical cause. For PPI channel-disable or fork-misroute failures, read PPI simulation. Compare route, output and guest spans; retain failed/unknown outcomes and the deferred model-task limitation.
If the project supplies .embedded/toolchain-lock.json, validate it with the
installed toolkit's component_lock.py inspect, pass it to doctor, and use only
its hash-bound component paths. Do not let environment overrides mask that lock.
Otherwise use a selected workstation lock when available and verify the doctor
reports its lock source before correlating evidence across component tools.
When a different lock is proposed, run component_lock.py compare first and
surface every changed path, version, and hash before selecting it.
Do not install or upgrade components during an active diagnosis unless the user
explicitly changes the task to host setup. For setup, review the offline
component_install.py plan; proceed only when its authenticated bundled catalog
is complete, then compare the generated candidate lock before selecting it.
Frame the question
Define the symptom, observation window, exact firmware artifact and hash, exact target/core, and the smallest state needed to decide between hypotheses. Record whether firmware identity is verified on the running target, was verified only in an earlier observation window, or is merely selected from a local build.
Inspect local builds when relevant
For artifact identity, linker layout, or footprint regressions, use optional
firmware-inspect if available through the selected component lock; read
offline firmware inspection. This file-only
analysis needs no target attach or hardware confirmation. Do not block an
unrelated debug workflow or install a missing component during diagnosis.
Its file hashes, Build IDs, section sums and load ranges are not proof of the
running firmware, board memory capacity, or permission to flash.
For an exact variable, function or _SEGGER_RTT request, use the guide's
symbols workflow with a selected firmware-inspect 0.2.0+ executable. Check each
query's resolution status and original definition metadata; the largest-symbol
list is incomplete for exact lookup. Preserve raw ELF values, including ABI
bits, and distinguish TLS offsets and unresolved entries from target addresses.
For PC/LR or code addresses already present in logs or a snapshot, use the guide's
addresses workflow with selected firmware-inspect 0.3.0+. Bind the exact ELF
hash and preserve input/lookup addresses, then read function and line statuses
independently. Choose arm-thumb explicitly for ARM32 Thumb pointer inputs;
do not silently adjust LR or relocation. Retain ambiguous results and unverified
DWARF paths. A metadata line match does not establish a function's source, call
stack, fault cause or running identity. No new target reads are needed for this
offline annotation, and file-only requests can end with the native report.
For a question spanning saved serial/RTT logs, read Embedded Trace timelines. Its hash-bound line spans and host-recorded envelopes can link observations without new target reads. Keep clock domains and capture failures explicit; a matching log line does not establish causality or firmware identity.
Build an identity ledger
When evidence spans multiple transports, operations, or observation windows, read references/identity-ledger.md and preserve a machine-readable ledger beside the human report.
- Classify each claim as observed, documented, inferred, rejected, or unknown, and attach exact source paths, hashes, and validity times.
- For multi-interface or multi-board ambiguity, adapt the saved discovery JSON
through optional
board-registry; read offline board identity resolution. Preserve the native files and do not treat resolution as runtime continuity. - Keep USB-interface association, physical-board identity, target/core identity, firmware artifact identity, and current runtime identity as separate claims.
- Treat runtime attestation and target state as point-in-time evidence. Do not carry them into a later serial or BLE window without fresh proof.
- For counters or other expected-monotonic state, bind the initialization, update, width, and cadence semantics before interpreting a rollback. A rollback can reject uninterrupted continuity, but does not alone distinguish reset, power loss, reflash, alternate firmware, or a different device.
Gather evidence conservatively
For firmware exposing RTT, read bounded RTT workflows. Debugger 0.2.4 provides native CLI capture for probe-rs/nRF52840, not a persistent-session or MCP RTT request. Bind the initialized address to the exact ELF and record read-cursor consumption plus attachment effects. Keep raw JSONL, summary and serial evidence separately hashed; clocks do not establish shared identity or continuity. Do not install another RTT consumer during diagnosis. For saved captures, use the offline reader in the RTT guide to verify integrity, preview bounded lines with chunk/byte references, or extract binary bytes before project-specific decoding. Truncated previews and incomplete tails cannot stand in for complete runtime assertions.
- Start with bounded, zero-transmit serial observation and read-only BLE evidence when those interfaces remain alive. When firmware exposes a build-bound identifier, read references/serial-firmware-identity.md and bind the exact physical serial identity and expected artifact hash in the same receive-only workflow.
- Use the component debug Skill to establish an exact session and current core state. Halting, stepping, continuing, resetting, installing breakpoints or watchpoints, and recovery are state changes; apply its current confirmation policy and never reuse a prior digest.
- Request only the registers, frame count, and declared memory range needed by the hypothesis. Never infer RAM/NVM/MMIO semantics from an address alone.
- If symbols are used, bind the exact ELF hash and distinguish offline annotation from proof that the target runs that ELF.
- Correlate events by recorded timestamps and operation boundaries. Host clocks and transport buffering may differ, so describe ordering uncertainty. Do not merge individually valid point-in-time claims into an unproven continuity claim.
Close deliberately
Delete only resources created by this workflow, close the exact sessions, and
verify cleanup. Do not resume an incident target merely to return to a familiar
state; restoration needs an explicit policy and evidence. Report observations,
inferences, rejected hypotheses, remaining unknowns, exact artifact paths, and
the least invasive next experiment. When the toolkit checkout is available, run
python scripts/validate_identity_ledger.py <ledger.json> --json before treating
the ledger as complete.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

