Skip to content

Latest commit

 

History

History
217 lines (162 loc) · 8.89 KB

File metadata and controls

217 lines (162 loc) · 8.89 KB

TinyUSB Agent Instructions

TinyUSB is a cross-platform USB Host/Device stack for embedded systems: memory-safe (no dynamic allocation) and thread-safe (ISR events deferred to task context).

Reference these instructions first; fall back to search/bash only when reality diverges.

Behavioral Guidelines

Bias toward caution over speed. For trivial tasks, use judgment.

  • Think first — state assumptions; ask if unclear; present alternatives instead of picking silently.
  • Simplicity — no features, abstractions, flexibility, or error handling beyond what was asked. If 200 lines could be 50, rewrite.
  • Surgical changes — touch only what the task requires; match existing style; don't refactor working code; mention unrelated dead code rather than deleting it. Remove only orphans your changes created.
  • Goal-driven — turn tasks into verifiable goals ("write failing test, make it pass"). For multi-step work, state a brief step → verify plan.

Ground Rules

  • 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.
  • Formatting/lint: clang-format (.clang-format), codespell (.codespellrc), run pre-commit run --all-files before submitting.

Bootstrap

sudo apt-get install -y gcc-arm-none-eabi          # ARM toolchain (2-5 min, one-time)
python3 tools/get_deps.py [FAMILY|-b BOARD]        # fetch deps into lib/, hw/mcu/ (<1 s)
. $HOME/code/esp-idf/export.sh                     # Espressif only: before any build/flash/monitor

Build

Single example (CMake+Ninja, recommended, 1-3 s):

cd examples/device/cdc_msc && mkdir -p build && cd 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:

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

Single example with Make:

cd examples/device/cdc_msc && make BOARD=raspberry_pi_pico all

Espressif (only ESP-IDF examples like cdc_msc_freertos):

. $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

Flash

# 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

GDB Debugging

Look up JLINK_DEVICE / OPENOCD_OPTION in hw/bsp/*/boards/*/board.cmake (CMake builds) or board.mk (Make builds).

JLink — Terminal 1:

JLinkGDBServer -device stm32h743xi -if SWD -speed 4000 -port 2331 -swoport 2332 -telnetport 2333 -nogui

OpenOCD — Terminal 1:

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):

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

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).

Testing

Unit (Ceedling, Unity+CMock, ~4 s):

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".

Documentation

pip install -r docs/requirements.txt
cd docs && sphinx-build -b html . _build        # ~2.5 s

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:

# 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).

Static Analysis (PVS-Studio)

Requires compile_commands.json (CMake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON).

# 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 --dump-files \
  --misra-c-version 2023 --misra-cpp-version 2008 --use-old-parser

# Specific files (add one or more `-S <file>`):
pvs-studio-analyzer analyze \
  -f examples/cmake-build-raspberry_pi_pico/compile_commands.json \
  -R .PVS-Studio/.pvsconfig \
  -S src/foo.c -S src/bar.c \
  -o pvs-report.log -j12 --dump-files \
  --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.

Validation After Changes

  1. pre-commit run --all-files — format, spell, unit tests (10-15 s).
  2. Build at least one board's full example set (Build → "All examples for a board") for modules you touched.
  3. Run relevant unit tests; add fuzz/HIL coverage for parsers or protocol state machines.

Boards good for local testing:

  • stm32f407disco — no external SDK
  • raspberry_pi_pico — Pico SDK required
  • Others: see hw/bsp/FAMILY/boards/

Device examples need real hardware to validate runtime behavior; must at least build.

Release

Do not commit automatically — leave changes for maintainer review.

  1. Bump version at top of tools/make_release.py.
  2. Run python3 tools/make_release.py to refresh: src/tusb_option.h, repository.yml, library.json, sonar-project.properties, docs/reference/boards.rst, hw/bsp/BoardPresets.json.
  3. Changelog docs/info/changelog.rst:
    • git log <last-tag>..HEAD --oneline for commit list.
    • Read merged PRs for context (gh pr view, or github MCP tools).
    • Follow existing format: version + ====== underline, italic date, sections (General, API Changes, DCD & HCD, Device Stack, Host Stack, Testing), RST inline code for symbols.
  4. Validate: ceedling test:all, build cdc_msc for stm32f407disco, review git diff --stat.
  5. Leave unstaged. Maintainer commits Bump version to X.Y.Z, then: git tag -a vX.Y.Z -m "Release X.Y.Z" && git push origin <branch> vX.Y.Z. Create GitHub release from tag.

References

  • MCU reference manuals, datasheets, schematics: $HOME/Documents/Calibre Library.
  • 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.

Common Build Issues

  • Missing compiler → install gcc-arm-none-eabi.
  • Missing deps → python3 tools/get_deps.py FAMILY.
  • Unknown board → check hw/bsp/FAMILY/boards/.
  • objcopy errors in full builds are often non-critical; retry the single example.