diff options
| author | Ha Thach <[email protected]> | 2026-07-21 18:06:01 +0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-07-21 18:06:01 +0700 |
| commit | 1b5c26b76e7194d05b82b0cccf76684716d3374d (patch) | |
| tree | 6f7e853077150f61fd98ccd399c4ffc8639fb90c | |
| parent | c6a1c66f8a64446ad1160b8e5b2da88ad1f3eac5 (diff) | |
* docs: add read-doc skill for on-demand datasheet lookup
Search and read MCU datasheets, reference manuals, errata, and the USB
spec from a local Calibre library ($HOME/Documents/calibre-library)
instead of answering register/bitfield/pinout questions from model
memory. Gated on the library's existence, so it no-ops for contributors
who don't have it.
* docs: reference read-doc skill and tighten CLAUDE.md
Point the datasheet/reference entry at the new read-doc skill, and trim
sections that only duplicate a skill already owning the detail:
PVS-Studio and Code Size collapse to pointers; GDB/Build/Flash command
blocks condensed to essentials. 213 -> 129 lines; behavioral guidelines
and the validation checklist unchanged.
* docs: tighten skill redundancy; rename AGENTS.md refs to CLAUDE.md
code-size: fold the step list into a sentence and drop invocation
examples the argument tables already cover. hil: merge the duplicated
self-lock bullets and compress the hifiphile note. usbmon: compress the
group-membership setup paragraph. All commands, flags, lock rules, and
report paths preserved. usb-target-debug and the pvs script only get
stale AGENTS.md references renamed to CLAUDE.md (now the real file);
run_pvs.sh no longer cites a --dump-files mention that CLAUDE.md dropped.
* docs: fix review findings — restore Espressif cd step, ELF placeholder, code-size comment
Codex/Copilot/Claude review of #3778: the condensed Espressif bullet
lost its cd (idf.py resolves the project from CWD, so the command failed
from repo root); the GDB example now uses the build/your_app.elf
placeholder that docs/troubleshooting.rst established; the code-size
invocation comment no longer references --combined, which the shown
command doesn't use.
| -rw-r--r-- | .claude/skills/code-size/SKILL.md | 24 | ||||
| -rw-r--r-- | .claude/skills/hil/SKILL.md | 13 | ||||
| -rwxr-xr-x | .claude/skills/pvs/run_pvs.sh | 8 | ||||
| -rw-r--r-- | .claude/skills/read-doc/SKILL.md | 61 | ||||
| -rw-r--r-- | .claude/skills/usb-target-debug/SKILL.md | 6 | ||||
| -rw-r--r-- | .claude/skills/usbmon/SKILL.md | 4 | ||||
| -rw-r--r-- | CLAUDE.md | 138 |
7 files changed, 104 insertions, 150 deletions
diff --git a/.claude/skills/code-size/SKILL.md b/.claude/skills/code-size/SKILL.md index f3c51ccfa..0a5305221 100644 --- a/.claude/skills/code-size/SKILL.md +++ b/.claude/skills/code-size/SKILL.md @@ -13,14 +13,7 @@ Compare TinyUSB code size between a base ref (default `master`) and the current | **all examples, one board** | Per-board regression sweep | `-b BOARD` | | **all examples, all CI families (combined)** | Pre-merge full check | `--ci` | -The script handles the full base-vs-branch dance: -1. Creates a temporary git worktree of the base ref under `cmake-metrics/_worktree/`. -2. Builds the base in `cmake-metrics/<board>/base/`. -3. Builds the current tree in `cmake-metrics/<board>/build/`. -4. Runs `tools/metrics.py compare` and writes `cmake-metrics/<board>/metrics_compare.md`. -5. Removes the worktree on exit. - -`--combined` (auto-set by `--ci`) also produces `cmake-metrics/_combined/metrics_compare.md` aggregating across all boards. +The script does the whole base-vs-branch dance itself: a temporary git worktree of the base ref under `cmake-metrics/_worktree/` (removed on exit), base + branch builds under `cmake-metrics/<board>/{base,build}/`, then `tools/metrics.py compare` (report paths under Outputs). ## Choosing arguments @@ -35,29 +28,20 @@ Infer from the user's request: ## Common invocations ```bash -# Single example, one board (linkermap, fastest): +# Single example, one board (linkermap, fastest; add --bloaty for section/symbol breakdown): python3 tools/metrics_compare_base.py -b raspberry_pi_pico -e device/cdc_msc -# Same with bloaty for section/symbol breakdown: -python3 tools/metrics_compare_base.py -b raspberry_pi_pico -e device/cdc_msc --bloaty - -# All examples for one board: +# All examples for one board (repeat -b for several boards): python3 tools/metrics_compare_base.py -b raspberry_pi_pico -# Multiple boards, one combined report: -python3 tools/metrics_compare_base.py -b raspberry_pi_pico -b raspberry_pi_pico2 --combined - # Full CI sweep (first board per arm-gcc family, combined): python3 tools/metrics_compare_base.py --ci - -# Compare against a tag/commit instead of master: -python3 tools/metrics_compare_base.py -b raspberry_pi_pico --base-branch v0.18.0 ``` ## Outputs - **Per-board:** `cmake-metrics/<board>/metrics_compare.md` (and `_<example>.md` when `-e` is set) -- **Combined (with `--combined`/`--ci`):** `cmake-metrics/_combined/metrics_compare.md` +- **Combined (`--combined`, auto-set by `--ci`):** `cmake-metrics/_combined/metrics_compare.md`, aggregating all boards - **Bloaty:** printed to stdout as section + symbol diffs ## Timing diff --git a/.claude/skills/hil/SKILL.md b/.claude/skills/hil/SKILL.md index 0d3abf1ac..7b76bf1b8 100644 --- a/.claude/skills/hil/SKILL.md +++ b/.claude/skills/hil/SKILL.md @@ -15,17 +15,14 @@ Run TinyUSB HIL tests on real boards. **Run `hostname` first** — it tells you Default to **local**. Use **remote** only when on `htpc` and the user says `remote`/`ci.lan`. Never attempt remote on `ci`. -The `hifiphile` rig is externally hosted by TinyUSB maintainer hifiphile; its board pool is -`test/hil/hfp.json` and its HIL runs are triggered by GitHub CI (the `hil-tinyusb (hfp.json)` -matrix job). **Never run HIL against this rig during development unless the user explicitly -asks for it.** +`hifiphile` is an external rig (hosted by maintainer hifiphile), exercised by the GitHub CI +`hil-tinyusb (hfp.json)` matrix job — **never run HIL against it unless the user explicitly asks.** ## Board locks — the CI runner keeps running The `ci` rig also hosts a GitHub Actions runner that flashes boards and runs HIL as part of CI. Hardware access is arbitrated **per board** with kernel flocks in `/tmp/tinyusb-hil-locks/` — do NOT stop the runner service. -- `hil_test.py` self-locks each board for the duration of its flash+test (holder reason `hil_test.py`). A locked board fails immediately (`<board> Failed: board locked: {holder info}`) without flashing — in CI, re-run the failed job once the lock is released. -- If your `hold` fails and the holder's reason is `hil_test.py`, a CI job is mid-test on that board — wait a few minutes and retry rather than forcing. +- `hil_test.py` self-locks each board for its flash+test (holder reason `hil_test.py`). A locked board fails immediately (`<board> Failed: board locked: {holder info}`) without flashing — in CI, re-run the failed job later; if your `hold` is refused with reason `hil_test.py`, a CI job is mid-test — wait a few minutes and retry rather than forcing. - For hardware work outside `hil_test.py` (JLink/GDB, manual flashing, `usbtest.py`, serial poking), hold the lock first: ```bash @@ -41,7 +38,7 @@ python3 test/hil/board_lock.py release BOARD [BOARD...] ## Prerequisites -Examples must be built for the target board(s) — see AGENTS.md "Build" → "All examples for a board" (produces `examples/cmake-build-<board>/`). `-B examples` points `hil_test.py` at that parent folder. +Examples must be built for the target board(s) — see CLAUDE.md "Build" → "All examples for a board" (produces `examples/cmake-build-<board>/`). `-B examples` points `hil_test.py` at that parent folder. ## Arguments @@ -64,8 +61,6 @@ python3 test/hil/hil_test.py -B examples "$CONFIG" python3 test/hil/hil_test.py -b stm32f723disco -B examples "$CONFIG" ``` -Append pass-through flags (`-v`, `-r 1`, …) to either command as needed. - ## Remote execution (htpc → ci.lan only) `test/hil/hil_ci.sh` handles dir setup, scp of test scripts, rsync of firmware (`.elf`/`.bin`/`.hex`), and runs `hil_test.py` on `ci.lan` with `tinyusb.json`: diff --git a/.claude/skills/pvs/run_pvs.sh b/.claude/skills/pvs/run_pvs.sh index 7406a3b4f..ce2cfd7e7 100755 --- a/.claude/skills/pvs/run_pvs.sh +++ b/.claude/skills/pvs/run_pvs.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Run PVS-Studio static analysis on TinyUSB for a given BOARD. # -# Mirrors the "Static Analysis (PVS-Studio)" section in AGENTS.md / CLAUDE.md: +# Implements the build + analyze flow behind CLAUDE.md "Static Analysis (PVS-Studio)": # - build all examples for BOARD with compile_commands.json exported # - run pvs-studio-analyzer against that compile DB using .PVS-Studio/.pvsconfig # - convert the log to human-readable (errorfile) and SARIF output @@ -64,9 +64,9 @@ fi # --- Analyze --------------------------------------------------------------- echo ">>> Running PVS-Studio analyzer (-j${JOBS})" -# Note: AGENTS.md shows --dump-files, but that scatters .PVS-Studio.i/.cfg dump -# files across the source tree (only useful for debugging false positives). It is -# omitted here to keep the working tree clean; add it back via "$@" if needed. +# Note: --dump-files scatters .PVS-Studio.i/.cfg dump files across the source +# tree (only useful for debugging false positives). It is omitted here to keep +# the working tree clean; add it back via "$@" if needed. pvs-studio-analyzer analyze \ -f "${COMPILE_DB}" \ -R .PVS-Studio/.pvsconfig \ diff --git a/.claude/skills/read-doc/SKILL.md b/.claude/skills/read-doc/SKILL.md new file mode 100644 index 000000000..df845e7b5 --- /dev/null +++ b/.claude/skills/read-doc/SKILL.md @@ -0,0 +1,61 @@ +--- +name: read-doc +description: Use when you need authoritative hardware/protocol facts from a primary source rather than model memory — an MCU/peripheral datasheet, reference manual (RM/TRM), errata, pinout, register/bitfield layout, memory map, schematic, or the USB spec — before answering register/electrical/timing/protocol questions from training knowledge or the web; or when the user asks to read/open/look up a manual, datasheet, book, or PDF/EPUB from their Calibre library. Requires a local Calibre library at ~/Documents/calibre-library; no-ops if absent. +--- + +# Read Doc + +## Overview + +Some maintainers keep datasheets, manuals, and books in a Calibre library at +`$HOME/Documents/calibre-library/`, laid out as +`AUTHOR/TITLE (id)/TITLE - AUTHOR.pdf|.epub`. For hardware/protocol facts — +registers, bitfields, memory maps, pinouts, electrical/timing specs, errata, USB +spec — read the doc instead of answering from training knowledge or the web. + +## Gate first + +The library is per-user. Check it exists before anything else: + +```bash +[ -d "$HOME/Documents/calibre-library" ] && echo present || echo absent +``` + +Absent → the skill does not apply; fall back to normal sources silently (don't +mention the library unless the user named it). + +## When to use + +- About to state a register/bitfield/reset-value/memory-map/pinout/timing spec + for a specific MCU or peripheral. +- User says "read the RP2040 datasheet", "open the CH569 manual", "what does the + STM32H7 RM say about…". + +Not for general concepts, repo/code questions, or when no such doc is likely. + +## Find + +Keywords from `/read-doc <keywords>`, else derived from the question (part number, +peripheral, spec name). AND them with chained case-insensitive grep: + +```bash +find "$HOME/Documents/calibre-library/" -maxdepth 3 \( -iname '*.pdf' -o -iname '*.epub' \) | grep -i "kw1" | grep -i "kw2" +``` + +One match → read it. Several → list and ask via AskUserQuestion. None → drop the +weakest keyword and broaden (filenames hold title+author, not tags); still none → +list the closest author/title matches. + +## Read + +- **PDF:** Read with `pages`; for >10 pages start `pages: "1-20"` (TOC/overview), + report the page count, then read sections on demand. +- **EPUB:** Read the path directly. +- Summarize in one line (title, pages, coverage) and keep as reference context. + +## Common mistakes + +- Skipping the gate on a machine with no library. +- Answering a register/spec question from memory when the datasheet is on disk. +- Loading a 1000-page PDF up front instead of TOC-first. +- Requiring all keywords to match — broaden on zero hits. diff --git a/.claude/skills/usb-target-debug/SKILL.md b/.claude/skills/usb-target-debug/SKILL.md index c664bf8fc..71fac98f2 100644 --- a/.claude/skills/usb-target-debug/SKILL.md +++ b/.claude/skills/usb-target-debug/SKILL.md @@ -58,7 +58,7 @@ Build with `LOG=2` (`LOG=3` adds per-transfer noise and much more timing skew). `LOGGER=rtt` routes it over the debug probe (J-Link only) — no UART wiring: ```bash -# RTT: JLinkGDBServer from AGENTS.md "GDB Debugging" + -RTTTelnetPort, then: +# RTT: JLinkGDBServer from CLAUDE.md "GDB Debugging" + -RTTTelnetPort, then: timeout 20s JLinkRTTClient > /tmp/rtt.log # non-interactive capture # UART (board's debug serial, if wired): stty -F /dev/ttyACM<N> 115200 raw && timeout 20s cat /dev/ttyACM<N> | tee /tmp/uart.log @@ -80,10 +80,10 @@ reads don't halt the target. ## GDB — state autopsy and watchpoints Connect/load recipes per probe family (J-Link, OpenOCD for ST-Link / -CMSIS-DAP / WCH-Link) are in AGENTS.md "GDB Debugging". Release builds keep +CMSIS-DAP / WCH-Link) are in CLAUDE.md "GDB Debugging". Release builds keep DWARF (`MinSizeRel`), so `p`/struct access works on HIL firmware. -**Autopsy of a wedged board: attach and halt ONLY** — skip AGENTS.md's +**Autopsy of a wedged board: attach and halt ONLY** — skip CLAUDE.md's `monitor reset halt` + `load` (those are for fresh starts; a reset destroys the evidence). Symbolize with the ELF that is actually flashed — `<build root>/cmake-build-<board>/<example>/<example>.elf` from the run that diff --git a/.claude/skills/usbmon/SKILL.md b/.claude/skills/usbmon/SKILL.md index 4164dcf2e..85ec33248 100644 --- a/.claude/skills/usbmon/SKILL.md +++ b/.claude/skills/usbmon/SKILL.md @@ -7,9 +7,7 @@ description: Use when capturing, analyzing, or debugging USB bus traffic for Tin `usbmon` records host-side **URBs** — control / bulk / interrupt / isochronous transfers, descriptors, class requests, STALLs, short packets — i.e. exactly what the host exchanged with a device. Use it to debug a TinyUSB device on real hardware. (It's host/URB-level, not wire-level; for SOF/ACK/electrical use a hardware analyzer.) -**Setup (assumed in place):** `usbmon` loaded and a udev rule `SUBSYSTEM=="usbmon", GROUP="wireshark", MODE="0640"` with your user in the `wireshark` group — so `tshark` captures with no `sudo`. - -If you were just added to `wireshark` (e.g. `usermod -aG`), the running shell/agent still has the old group set (group adds only apply to a fresh login). Don't restart — wrap each capture in `sg wireshark -c '…'`, which re-reads `/etc/group` immediately: `sg wireshark -c 'tshark -i usbmon3 -s 128 -a duration:30 -w /tmp/cap.pcapng'`. (Reading a finished `.pcapng` with `tshark -r` needs no special group.) For long/high-throughput captures add `-s 128` (snaplen) to keep only URB headers/status, not payloads. +**Setup (assumed in place):** `usbmon` loaded and a udev rule `SUBSYSTEM=="usbmon", GROUP="wireshark", MODE="0640"` with your user in the `wireshark` group — so `tshark` captures with no `sudo`. Freshly added to the group? The running shell doesn't have it yet (group adds need a new login) — wrap captures in `sg wireshark -c 'tshark -i usbmon3 -s 128 -a duration:30 -w /tmp/cap.pcapng'`; reading a finished `.pcapng` (`tshark -r`) needs no group. `-s 128` (snaplen) keeps only URB headers/status, not payloads — use it for long/high-throughput captures. ## Capture @@ -19,8 +19,8 @@ Bias toward caution over speed. For trivial tasks, use judgment. - **Language/style:** C99, 2-space indent (no tabs), snake_case helpers, `UPPER_CASE` macros. Public APIs use `tud_`/`tuh_`; macros use `TU_`. Headers self-contained with `#if CFG_TUSB_MCU` guards. - **Safety:** no dynamic allocation; defer ISR work to task context; use `TU_ASSERT()` for error checks; always check return values; include order: C stdlib → tusb common → drivers → classes. - **Layout:** `src/` core, `hw/{mcu,bsp}/` MCU+BSP, `examples/{device,host,dual}/`, `test/{unit-test,fuzz,hil}/`, `docs/`, `tools/`. -- **Commits/PRs:** imperative mood, scoped changes, link issues, include test/build evidence. After opening a PR, monitor it and drive it to green: address automated review comments (Copilot/Codex/Claude) and fix any failing CI builds, pushing follow-up commits until checks pass and review threads are resolved. Useful: `gh pr checks <num> --watch`, `gh pr view <num> --comments`. -- **Formatting/lint:** `clang-format` (`.clang-format`), `codespell` (`.codespellrc`), run `pre-commit run --all-files` before submitting. +- **Commits/PRs:** imperative mood, scoped changes, link issues, include test/build evidence. After opening a PR, drive it to green: address automated review comments (Copilot/Codex/Claude) and fix failing CI, pushing follow-ups until checks pass and threads resolve. Useful: `gh pr checks <num> --watch`, `gh pr view <num> --comments`. +- **Formatting/lint:** `clang-format` (`.clang-format`), `codespell` (`.codespellrc`); run `pre-commit run --all-files` before submitting. ## Bootstrap @@ -35,86 +35,45 @@ python3 tools/get_deps.py [FAMILY|-b BOARD] # fetch deps into lib/, hw/mc Single example (CMake+Ninja, recommended, 1-3 s): ```bash cd examples/device/cdc_msc && mkdir -p build && cd build -cmake -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .. -cmake --build . +cmake -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel .. && cmake --build . ``` -All examples for a board (15-20 s; some objcopy failures are non-critical). Use `cmake-build-<board>` as the build dir — HIL tests expect that exact name: +All examples for a board (15-20 s; some objcopy failures are non-critical). The build dir **must** be `cmake-build-<board>` — HIL tests expect that exact name: ```bash cd examples -cmake -B cmake-build-raspberry_pi_pico -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel . -cmake --build cmake-build-raspberry_pi_pico +cmake -B cmake-build-raspberry_pi_pico -DBOARD=raspberry_pi_pico -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel . && cmake --build cmake-build-raspberry_pi_pico ``` -Single example with Make: -```bash -cd examples/device/cdc_msc && make BOARD=raspberry_pi_pico all -``` - -Espressif (only ESP-IDF examples like `cdc_msc_freertos`): -```bash -. $HOME/code/esp-idf/export.sh -cd examples/device/cdc_msc_freertos -idf.py -DBOARD=espressif_s3_devkitc build -``` - -**Build options** (CMake `-D…` / Make `…=…`): -- Debug: `CMAKE_BUILD_TYPE=Debug` / `DEBUG=1` -- Logging: `LOG=2` (add `LOGGER=rtt` for RTT) -- Root hub port: `RHPORT_DEVICE=1` -- Speed: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` +- **Make:** `cd examples/device/cdc_msc && make BOARD=raspberry_pi_pico all` +- **Espressif** (ESP-IDF examples only, e.g. `cdc_msc_freertos`): after `export.sh`, `cd examples/device/cdc_msc_freertos && idf.py -DBOARD=espressif_s3_devkitc build` +- **Options** (CMake `-D…` / Make `…=…`): `CMAKE_BUILD_TYPE=Debug`/`DEBUG=1`; `LOG=2` (`LOGGER=rtt` for RTT); `RHPORT_DEVICE=1`; `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` ## Flash ```bash -# JLink -ninja cdc_msc-jlink # CMake -make BOARD=<board> flash-jlink # Make - -# OpenOCD -ninja cdc_msc-openocd # CMake -make BOARD=<board> flash-openocd # Make - -# UF2 -ninja cdc_msc-uf2 # CMake -make BOARD=<board> all uf2 # Make - -ninja -t targets # list CMake targets - -# Espressif (after . $HOME/code/esp-idf/export.sh) -idf.py -DBOARD=<board> flash -idf.py -DBOARD=<board> monitor +ninja cdc_msc-jlink # CMake; Make: make BOARD=<board> flash-jlink +ninja cdc_msc-openocd # CMake; Make: make BOARD=<board> flash-openocd +ninja cdc_msc-uf2 # CMake; Make: make BOARD=<board> all uf2 +ninja -t targets # list CMake targets ``` +Espressif (after `export.sh`): `idf.py -DBOARD=<board> flash` / `… monitor`. ## GDB Debugging -Look up `JLINK_DEVICE` / `OPENOCD_OPTION` in `hw/bsp/*/boards/*/board.cmake` (CMake builds) or `board.mk` (Make builds). +Look up `JLINK_DEVICE` / `OPENOCD_OPTION` in `hw/bsp/*/boards/*/board.cmake` (CMake) or `board.mk` (Make). -**JLink — Terminal 1:** +Terminal 1 — start a gdbserver: ```bash -JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -swoport 2332 -telnetport 2333 -nogui +JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -nogui # JLink → :2331 +openocd -f interface/stlink.cfg -f target/stm32h7x.cfg # OpenOCD → :3333 +openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" # rp2040/rp2350 ``` - -**OpenOCD — Terminal 1:** -```bash -openocd -f interface/stlink.cfg -f target/stm32h7x.cfg -# or with a J-Link interface: -openocd -f interface/jlink.cfg -f target/stm32h7x.cfg -# rp2040/rp2350 via CMSIS-DAP: -openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -``` - -**Terminal 2 — connect GDB** (replace `<port>` with `2331` for JLinkGDBServer or `3333` for OpenOCD): +Terminal 2 — connect (`<port>`: 2331 JLink, 3333 OpenOCD): ```bash -arm-none-eabi-gdb /tmp/build/firmware.elf -(gdb) target remote :<port> -(gdb) monitor reset halt -(gdb) load -(gdb) break main # optional, to stop at entry -(gdb) continue +arm-none-eabi-gdb build/your_app.elf +(gdb) target remote :<port> # then: monitor reset halt → load → continue ``` - -**RTT logging:** build with `LOG=2 LOGGER=rtt`, flash, then run JLinkGDBServer with `-RTTTelnetPort 19021`, and in another terminal `JLinkRTTClient` (pipe to `tee rtt.log` or use `timeout 20s JLinkRTTClient > rtt.log` for non-interactive capture). +**RTT:** build `LOG=2 LOGGER=rtt`, run JLinkGDBServer with `-RTTTelnetPort 19021`, then `JLinkRTTClient` (`timeout 20s JLinkRTTClient > rtt.log` for non-interactive capture). ## Testing @@ -124,62 +83,19 @@ sudo gem install ceedling cd test/unit-test && ceedling test:all # or ceedling test:test_fifo ``` -**HIL (2-5 min):** invoke the `hil` skill (`.claude/skills/hil/SKILL.md`) for the full procedure (local vs remote mode, config selection, SSH copy steps, debugging tips). Requires pre-built examples — see Build → "All examples for a board". +**HIL (2-5 min):** invoke the `hil` skill (`.claude/skills/hil/SKILL.md`) — local vs remote mode, config selection, SSH copy steps, debugging. Requires pre-built examples (Build → "All examples for a board"). ## Documentation -Sphinx docs in `docs/` (reStructuredText `.rst` or Markdown `.md` via MyST). Use the `build-doc` skill (`.claude/skills/build-doc/SKILL.md`) to build/preview locally (`sphinx-build`) and to regenerate auto-generated files (`tools/gen_doc.py` + `tools/gen_presets.py`) after adding a board or dependency. +Sphinx docs in `docs/` (`.rst`, or `.md` via MyST). Use the `build-doc` skill (`.claude/skills/build-doc/SKILL.md`) to build/preview locally and regenerate auto-generated files (`tools/gen_doc.py` + `tools/gen_presets.py`) after adding a board or dependency. ## Code Size Metrics -Verify size impact before committing. Invoke the `code-size` skill (`.claude/skills/code-size/SKILL.md`) — it wraps `tools/metrics_compare_base.py` to handle the base-vs-branch worktree + build + compare flow. - -Quick reference: -```bash -# Single example, one board: -python3 tools/metrics_compare_base.py -b raspberry_pi_pico -e device/cdc_msc -# Add --bloaty for section/symbol breakdown. - -# All examples, one board: -python3 tools/metrics_compare_base.py -b raspberry_pi_pico - -# All arm-gcc CI families combined (pre-merge sweep, 4-8 min): -python3 tools/metrics_compare_base.py --ci -``` - -Reports land in `cmake-metrics/<board>/metrics_compare.md` (per-board) and `cmake-metrics/_combined/metrics_compare.md` (with `--combined`/`--ci`). +Verify size impact before committing with the `code-size` skill (`.claude/skills/code-size/SKILL.md`) — it wraps `tools/metrics_compare_base.py` for the base-vs-branch worktree + build + compare. Scopes: single example (`-e device/cdc_msc -b <board>`, add `--bloaty`), all examples on a board (`-b <board>`), or all arm-gcc CI families (`--ci`). Reports land in `cmake-metrics/<board>/metrics_compare.md` (and `_combined/` for `--ci`). ## Static Analysis (PVS-Studio) -Requires `compile_commands.json`, which the examples build exports by default -(`hw/bsp/family_support.cmake` sets `CMAKE_EXPORT_COMPILE_COMMANDS ON`). The -`pvs` skill (`.claude/skills/pvs/SKILL.md`) wraps the build + analyze flow for a -board; the commands below are the underlying steps. - -```bash -# Whole project: -pvs-studio-analyzer analyze \ - -f examples/cmake-build-raspberry_pi_pico/compile_commands.json \ - -R .PVS-Studio/.pvsconfig \ - -o pvs-report.log -j12 \ - --security-related-issues \ - --misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser - -# Specific files: -S takes a plaintext list (one path per line), not paths directly: -printf 'src/foo.c\nsrc/bar.c\n' > files.txt -pvs-studio-analyzer analyze \ - -f examples/cmake-build-raspberry_pi_pico/compile_commands.json \ - -R .PVS-Studio/.pvsconfig \ - -S files.txt \ - -o pvs-report.log -j12 \ - --security-related-issues \ - --misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser - -plog-converter -a GA:1,2 -t errorfile pvs-report.log # view results -``` - -Takes ~10-30 s. (`--dump-files` adds preprocessed `.PVS-Studio.i/.cfg` dumps next -to every source for false-positive debugging — omit it for normal runs.) +Use the `pvs` skill (`.claude/skills/pvs/SKILL.md`) — it builds the examples with an exported `compile_commands.json` and runs SAST + MISRA C:2023/C++:2008 for a board, emitting readable + SARIF output (~10-30 s). The examples build exports `compile_commands.json` by default. ## Validation After Changes @@ -200,7 +116,7 @@ Cutting a release — version bump, regenerated files, the per-release changelog ## References -- MCU reference manuals, datasheets, schematics: `$HOME/Documents/calibre-library`. +- MCU reference manuals, datasheets, schematics: before answering register/bitfield/pinout/errata/timing questions from memory or the web, use the `read-doc` skill (`.claude/skills/read-doc/SKILL.md`) to search and read them from `$HOME/Documents/calibre-library` (skill no-ops if the library is absent). - Supported MCUs/boards: `hw/bsp/` and `docs/reference/boards.rst`. - USB classes: `src/class/{cdc,hid,msc,audio,…}/` — each has `*_device.c` and `*_host.c`. - Key files: `src/tusb.h`, `src/tusb_config.h`, `tools/get_deps.py`, `tools/build.py`, `test/unit-test/project.yml`. |
