summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2026-07-21 18:06:01 +0700
committerGitHub <[email protected]>2026-07-21 18:06:01 +0700
commit1b5c26b76e7194d05b82b0cccf76684716d3374d (patch)
tree6f7e853077150f61fd98ccd399c4ffc8639fb90c
parentc6a1c66f8a64446ad1160b8e5b2da88ad1f3eac5 (diff)
docs: add read-doc skill, tighten CLAUDE.md and skill docs (#3778)HEADmaster
* 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.md24
-rw-r--r--.claude/skills/hil/SKILL.md13
-rwxr-xr-x.claude/skills/pvs/run_pvs.sh8
-rw-r--r--.claude/skills/read-doc/SKILL.md61
-rw-r--r--.claude/skills/usb-target-debug/SKILL.md6
-rw-r--r--.claude/skills/usbmon/SKILL.md4
-rw-r--r--CLAUDE.md138
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
diff --git a/CLAUDE.md b/CLAUDE.md
index c902e2b62..2acdc3a63 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -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`.