|
21 | 21 | 3. Run unit tests relevant to touched modules; add fuzz/HIL coverage when modifying parsers or protocol state machines. |
22 | 22 |
|
23 | 23 | ## Copilot Agent Notes (`.github/copilot-instructions.md`) |
24 | | -- Treat this handbook as authoritative before searching or executing speculative shell commands; unexpected conflicts justify additional probing. |
25 | | -- Respect build timing guidance: allow ≥5 minutes for single example builds and ≥30 minutes for bulk runs; never cancel dependency fetches or builds mid-flight. |
26 | | -- Support optional switches: `-DRHPORT_DEVICE[_SPEED]`, logging toggles (`LOG=2`, `LOGGER=rtt`), and board selection helpers from `tools/get_deps.py`. |
27 | | -- Flashing shortcuts: `ninja <target>-jlink|openocd|uf2` or `make BOARD=<board> flash-{jlink,openocd}`; list Ninja targets with `ninja -t targets`. |
28 | | -- Keep Ceedling installed (`sudo gem install ceedling`) and available for per-test or full suite runs triggered from `test/unit-test`. |
| 24 | +# TinyUSB |
| 25 | +TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events deferred to non-ISR task functions. |
| 26 | + |
| 27 | +Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here. |
| 28 | + |
| 29 | +### Working Effectively |
| 30 | + |
| 31 | +#### Bootstrap and Build Setup |
| 32 | +- Install ARM GCC toolchain: `sudo apt-get update && sudo apt-get install -y gcc-arm-none-eabi` |
| 33 | +- Fetch core dependencies: `python3 tools/get_deps.py` -- takes <1 second. NEVER CANCEL. |
| 34 | +- For specific board families: `python3 tools/get_deps.py FAMILY_NAME` (e.g., rp2040, stm32f4) |
| 35 | +- Dependencies are cached in `lib/` and `hw/mcu/` directories |
| 36 | + |
| 37 | +#### Build Examples |
| 38 | +Choose ONE of these approaches: |
| 39 | + |
| 40 | +**Option 1: Individual Example with CMake (RECOMMENDED)** |
| 41 | +```bash |
| 42 | +cd examples/device/cdc_msc |
| 43 | +mkdir -p build && cd build |
| 44 | +cmake -DBOARD=raspberry_pi_pico -DCMAKE_BUILD_TYPE=MinSizeRel .. |
| 45 | +cmake --build . -j4 |
| 46 | +``` |
| 47 | +-- takes 1-2 seconds. NEVER CANCEL. Set timeout to 5+ minutes. |
| 48 | + |
| 49 | +**CMake with Ninja (Alternative)** |
| 50 | +```bash |
| 51 | +cd examples/device/cdc_msc |
| 52 | +mkdir build && cd build |
| 53 | +cmake -G Ninja -DBOARD=raspberry_pi_pico .. |
| 54 | +ninja |
| 55 | +``` |
| 56 | + |
| 57 | +**Option 2: Individual Example with Make** |
| 58 | +```bash |
| 59 | +cd examples/device/cdc_msc |
| 60 | +make BOARD=raspberry_pi_pico all |
| 61 | +``` |
| 62 | +-- takes 2-3 seconds. NEVER CANCEL. Set timeout to 5+ minutes. |
| 63 | + |
| 64 | +**Option 3: All Examples for a Board** |
| 65 | +```bash |
| 66 | +python3 tools/build.py -b BOARD_NAME |
| 67 | +``` |
| 68 | +-- takes 15-20 seconds, may have some objcopy failures that are non-critical. NEVER CANCEL. Set timeout to 30+ minutes. |
| 69 | + |
| 70 | +#### Build Options |
| 71 | +- **Debug build**: |
| 72 | + - CMake: `-DCMAKE_BUILD_TYPE=Debug` |
| 73 | + - Make: `DEBUG=1` |
| 74 | +- **With logging**: |
| 75 | + - CMake: `-DLOG=2` |
| 76 | + - Make: `LOG=2` |
| 77 | +- **With RTT logger**: |
| 78 | + - CMake: `-DLOG=2 -DLOGGER=rtt` |
| 79 | + - Make: `LOG=2 LOGGER=rtt` |
| 80 | +- **RootHub port selection**: |
| 81 | + - CMake: `-DRHPORT_DEVICE=1` |
| 82 | + - Make: `RHPORT_DEVICE=1` |
| 83 | +- **Port speed**: |
| 84 | + - CMake: `-DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` |
| 85 | + - Make: `RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED` |
| 86 | + |
| 87 | +#### Flashing and Deployment |
| 88 | +- **Flash with JLink**: |
| 89 | + - CMake: `ninja cdc_msc-jlink` |
| 90 | + - Make: `make BOARD=raspberry_pi_pico flash-jlink` |
| 91 | +- **Flash with OpenOCD**: |
| 92 | + - CMake: `ninja cdc_msc-openocd` |
| 93 | + - Make: `make BOARD=raspberry_pi_pico flash-openocd` |
| 94 | +- **Generate UF2**: |
| 95 | + - CMake: `ninja cdc_msc-uf2` |
| 96 | + - Make: `make BOARD=raspberry_pi_pico all uf2` |
| 97 | +- **List all targets** (CMake/Ninja): `ninja -t targets` |
| 98 | + |
| 99 | +#### Unit Testing |
| 100 | +- Install Ceedling: `sudo gem install ceedling` |
| 101 | +- Run all unit tests: `cd test/unit-test && ceedling` or `cd test/unit-test && ceedling test:all` -- takes 4 seconds. NEVER CANCEL. Set timeout to 10+ minutes. |
| 102 | +- Run specific test: `cd test/unit-test && ceedling test:test_fifo` |
| 103 | +- Tests use Unity framework with CMock for mocking |
| 104 | + |
| 105 | +#### Documentation |
| 106 | +- Install requirements: `pip install -r docs/requirements.txt` |
| 107 | +- Build docs: `cd docs && sphinx-build -b html . _build` -- takes 2-3 seconds. NEVER CANCEL. Set timeout to 10+ minutes. |
| 108 | + |
| 109 | +#### Code Quality and Validation |
| 110 | +- Format code: `clang-format -i path/to/file.c` (uses `.clang-format` config) |
| 111 | +- Check spelling: `pip install codespell && codespell` (uses `.codespellrc` config) |
| 112 | +- Pre-commit hooks validate unit tests and code quality automatically |
| 113 | + |
| 114 | +#### Static Analysis with PVS-Studio |
| 115 | +- **Analyze whole project**: |
| 116 | + ```bash |
| 117 | + 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-cpp-version 2008 --misra-c-version 2023 --use-old-parser |
| 118 | + ``` |
| 119 | +- **Analyze specific source files**: |
| 120 | + ```bash |
| 121 | + pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -S path/to/file.c -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser |
| 122 | + ``` |
| 123 | +- **Multiple specific files**: |
| 124 | + ```bash |
| 125 | + pvs-studio-analyzer analyze -f examples/cmake-build-raspberry_pi_pico/compile_commands.json -R .PVS-Studio/.pvsconfig -S src/file1.c -S src/file2.c -o pvs-report.log -j12 --dump-files --misra-cpp-version 2008 --misra-c-version 2023 --use-old-parser |
| 126 | + ``` |
| 127 | +- Requires `compile_commands.json` in the build directory (generated by CMake with `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON`) |
| 128 | +- Use `-f` option to specify path to `compile_commands.json` |
| 129 | +- Use `-R .PVS-Studio/.pvsconfig` to specify rule configuration file |
| 130 | +- Use `-j12` for parallel analysis with 12 threads |
| 131 | +- `--dump-files` saves preprocessed files for debugging |
| 132 | +- `--misra-c-version 2023` enables MISRA C:2023 checks |
| 133 | +- `--misra-cpp-version 2008` enables MISRA C++:2008 checks |
| 134 | +- `--use-old-parser` uses legacy parser for compatibility |
| 135 | +- Analysis takes ~10-30 seconds depending on project size. Set timeout to 5+ minutes. |
| 136 | +- View results: `plog-converter -a GA:1,2 -t errorfile pvs-report.log` or open in PVS-Studio GUI |
| 137 | + |
| 138 | +### Validation |
| 139 | + |
| 140 | +#### ALWAYS Run These After Making Changes |
| 141 | +1. **Pre-commit validation** (RECOMMENDED): `pre-commit run --all-files` |
| 142 | + - Install pre-commit: `pip install pre-commit && pre-commit install` |
| 143 | + - Runs all quality checks, unit tests, spell checking, and formatting |
| 144 | + - Takes 10-15 seconds. NEVER CANCEL. Set timeout to 15+ minutes. |
| 145 | +2. **Build validation**: Build at least one example that exercises your changes |
| 146 | + ```bash |
| 147 | + cd examples/device/cdc_msc |
| 148 | + make BOARD=raspberry_pi_pico all |
| 149 | + ``` |
| 150 | + |
| 151 | +#### Manual Testing Scenarios |
| 152 | +- **Device examples**: Cannot be fully tested without real hardware, but must build successfully |
| 153 | +- **Unit tests**: Exercise core stack functionality - ALL tests must pass |
| 154 | +- **Build system**: Must be able to build examples for multiple board families |
| 155 | + |
| 156 | +#### Board Selection for Testing |
| 157 | +- **STM32F4**: `stm32f407disco` - no external SDK required, good for testing |
| 158 | +- **RP2040**: `raspberry_pi_pico` - requires Pico SDK, commonly used |
| 159 | +- **Other families**: Check `hw/bsp/FAMILY/boards/` for available boards |
| 160 | + |
| 161 | +### Common Tasks and Time Expectations |
| 162 | + |
| 163 | +#### Repository Structure Quick Reference |
| 164 | +``` |
| 165 | +├── src/ # Core TinyUSB stack |
| 166 | +│ ├── class/ # USB device classes (CDC, HID, MSC, Audio, etc.) |
| 167 | +│ ├── portable/ # MCU-specific drivers (organized by vendor) |
| 168 | +│ ├── device/ # USB device stack core |
| 169 | +│ ├── host/ # USB host stack core |
| 170 | +│ └── common/ # Shared utilities (FIFO, etc.) |
| 171 | +├── examples/ # Example applications |
| 172 | +│ ├── device/ # Device examples (cdc_msc, hid_generic, etc.) |
| 173 | +│ ├── host/ # Host examples |
| 174 | +│ └── dual/ # Dual-role examples |
| 175 | +├── hw/bsp/ # Board Support Packages |
| 176 | +│ └── FAMILY/boards/ # Board-specific configurations |
| 177 | +├── test/unit-test/ # Unit tests using Ceedling |
| 178 | +├── tools/ # Build and utility scripts |
| 179 | +└── docs/ # Sphinx documentation |
| 180 | +``` |
| 181 | + |
| 182 | +#### Build Time Reference |
| 183 | +- **Dependency fetch**: <1 second |
| 184 | +- **Single example build**: 1-3 seconds |
| 185 | +- **Unit tests**: ~4 seconds |
| 186 | +- **Documentation build**: ~2.5 seconds |
| 187 | +- **Full board examples**: 15-20 seconds |
| 188 | +- **Toolchain installation**: 2-5 minutes (one-time) |
| 189 | + |
| 190 | +#### Key Files to Know |
| 191 | +- `tools/get_deps.py`: Manages dependencies for MCU families |
| 192 | +- `tools/build.py`: Builds multiple examples, supports make/cmake |
| 193 | +- `src/tusb.h`: Main TinyUSB header file |
| 194 | +- `src/tusb_config.h`: Configuration template |
| 195 | +- `examples/device/cdc_msc/`: Most commonly used example for testing |
| 196 | +- `test/unit-test/project.yml`: Ceedling test configuration |
| 197 | + |
| 198 | +#### Debugging Build Issues |
| 199 | +- **Missing compiler**: Install `gcc-arm-none-eabi` package |
| 200 | +- **Missing dependencies**: Run `python3 tools/get_deps.py FAMILY` |
| 201 | +- **Board not found**: Check `hw/bsp/FAMILY/boards/` for valid board names |
| 202 | +- **objcopy errors**: Often non-critical in full builds, try individual example builds |
| 203 | + |
| 204 | +#### Working with USB Device Classes |
| 205 | +- **CDC (Serial)**: `src/class/cdc/` - Virtual serial port |
| 206 | +- **HID**: `src/class/hid/` - Human Interface Device (keyboard, mouse, etc.) |
| 207 | +- **MSC**: `src/class/msc/` - Mass Storage Class (USB drive) |
| 208 | +- **Audio**: `src/class/audio/` - USB Audio Class |
| 209 | +- Each class has device (`*_device.c`) and host (`*_host.c`) implementations |
| 210 | + |
| 211 | +#### MCU Family Support |
| 212 | +- **STM32**: Largest support (F0, F1, F2, F3, F4, F7, G0, G4, H7, L4, U5, etc.) |
| 213 | +- **Raspberry Pi**: RP2040, RP2350 with PIO-USB host support |
| 214 | +- **NXP**: iMXRT, Kinetis, LPC families |
| 215 | +- **Microchip**: SAM D/E/G/L families |
| 216 | +- Check `hw/bsp/` for complete list and `docs/reference/boards.rst` for details |
| 217 | + |
| 218 | +### Code Style Guidelines |
| 219 | + |
| 220 | +#### General Coding Standards |
| 221 | +- Use C99 standard |
| 222 | +- Memory-safe: no dynamic allocation |
| 223 | +- Thread-safe: defer all interrupt events to non-ISR task functions |
| 224 | +- 2-space indentation, no tabs |
| 225 | +- Use snake_case for variables/functions |
| 226 | +- Use UPPER_CASE for macros and constants |
| 227 | +- Follow existing variable naming patterns in files you're modifying |
| 228 | +- Include proper header comments with MIT license |
| 229 | +- Add descriptive comments for non-obvious functions |
| 230 | + |
| 231 | +#### Best Practices |
| 232 | +- When including headers, group in order: C stdlib, tusb common, drivers, classes |
| 233 | +- Always check return values from functions that can fail |
| 234 | +- Use TU_ASSERT() for error checking with return statements |
| 235 | +- Follow the existing code patterns in the files you're modifying |
| 236 | + |
| 237 | +Remember: TinyUSB is designed for embedded systems - builds are fast, tests are focused, and the codebase is optimized for resource-constrained environments. |
29 | 238 |
|
30 | 239 | ## Claude Agent Notes (`CLAUDE.md`) |
31 | 240 | - Default to CMake+Ninja for builds, but align with Make workflows when users rely on legacy scripts; provide DEBUG/LOG/LOGGER knobs consistently. |
|
0 commit comments