|
| 1 | +# Proves Core Reference Project - Copilot Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | +This is a reference software implementation for the [Proves Kit](https://docs.proveskit.space/en/latest/), combining F Prime (NASA's flight software framework) with Zephyr RTOS to create firmware for embedded flight control boards. The project targets ARM Cortex-M microcontrollers, specifically RP2350 (Raspberry Pi Pico 2) and STM32 boards. |
| 5 | + |
| 6 | +**Repository Size**: ~450MB (primarily from Zephyr workspace and F Prime submodules) |
| 7 | +**Languages**: C++ (F Prime components), C (Zephyr integration), Python (testing), FPP (F Prime modeling language), CMake |
| 8 | +**Frameworks**: F Prime v4.0.0a1, Zephyr RTOS v4.2.0 |
| 9 | +**Target Runtime**: Bare metal embedded systems (ARM Cortex-M33/M7) |
| 10 | + |
| 11 | +## Critical Build Prerequisites |
| 12 | + |
| 13 | +### System Dependencies |
| 14 | +Before any build steps, ensure you have: |
| 15 | +- Python 3.13+ (specified in `.python-version`) |
| 16 | +- F Prime system requirements: https://fprime.jpl.nasa.gov/latest/docs/getting-started/installing-fprime/#system-requirements |
| 17 | +- Zephyr dependencies: https://docs.zephyrproject.org/latest/develop/getting_started/index.html#install-dependencies |
| 18 | + - **NOTE**: Only install dependencies; do NOT run Zephyr's full setup (handled by Makefile) |
| 19 | + |
| 20 | +### Build Tool: UV Package Manager |
| 21 | +This project uses **UV** (v0.8.13) for Python environment management. It is automatically downloaded by the Makefile. |
| 22 | +- Do NOT use `pip` or `python -m venv` directly |
| 23 | +- Always use `make` targets which invoke UV internally |
| 24 | + |
| 25 | +## Build & Test Workflow |
| 26 | + |
| 27 | +### First-Time Setup (Complete Sequence) |
| 28 | +Run these commands **in order** from the repository root. The entire setup takes ~5-10 minutes: |
| 29 | + |
| 30 | +```bash |
| 31 | +# Step 1: Initialize git submodules (~1 minute) |
| 32 | +make submodules |
| 33 | + |
| 34 | +# Step 2: Create Python virtual environment and install dependencies (~2 minutes) |
| 35 | +make fprime-venv |
| 36 | + |
| 37 | +# Step 3: Set up Zephyr workspace and SDK (~3-5 minutes) |
| 38 | +make zephyr-setup |
| 39 | + |
| 40 | +# Step 4: Generate F Prime build cache (~1 minute) |
| 41 | +make generate |
| 42 | + |
| 43 | +# Step 5: Build the firmware (~2-3 minutes) |
| 44 | +make build |
| 45 | +``` |
| 46 | + |
| 47 | +**IMPORTANT**: The `make` command (default target) runs all of the above automatically. |
| 48 | + |
| 49 | +### Development Workflow |
| 50 | + |
| 51 | +**After making code changes**: |
| 52 | +```bash |
| 53 | +# Always run build (it calls generate-if-needed automatically) |
| 54 | +make build |
| 55 | +``` |
| 56 | + |
| 57 | +**When to run generate explicitly**: |
| 58 | +- After modifying `.fpp` files (F Prime component definitions) |
| 59 | +- After changing CMakeLists.txt files |
| 60 | +- After modifying core F Prime package files |
| 61 | +- Command: `make generate` |
| 62 | + |
| 63 | +### Linting & Formatting |
| 64 | +```bash |
| 65 | +# Run all pre-commit checks (REQUIRED before committing) |
| 66 | +make fmt |
| 67 | +``` |
| 68 | + |
| 69 | +This runs: |
| 70 | +- `clang-format` (C/C++ formatting) |
| 71 | +- `cpplint` (C++ style checking using `cpplint.cfg`) |
| 72 | +- `ruff` (Python linting and formatting) |
| 73 | +- `codespell` (spell checking) |
| 74 | +- Standard pre-commit hooks (trailing whitespace, JSON/YAML validation, etc.) |
| 75 | + |
| 76 | +**Configuration**: `.pre-commit-config.yaml`, `cpplint.cfg`, `.clang-format` |
| 77 | + |
| 78 | +### Testing |
| 79 | + |
| 80 | +**Integration Tests**: |
| 81 | +Integration tests require the GDS (Ground Data System) to be running: |
| 82 | + |
| 83 | +```bash |
| 84 | +# Terminal 1: Start GDS |
| 85 | +make gds |
| 86 | + |
| 87 | +# Terminal 2: Run integration tests |
| 88 | +make test-integration |
| 89 | +``` |
| 90 | + |
| 91 | +**Test Location**: `FprimeZephyrReference/test/int/` |
| 92 | +**Test Framework**: pytest with fprime-gds testing API |
| 93 | + |
| 94 | +## Project Structure |
| 95 | + |
| 96 | +### Repository Root Files |
| 97 | +``` |
| 98 | +CMakeLists.txt # Top-level CMake configuration |
| 99 | +CMakePresets.json # CMake presets for Zephyr build |
| 100 | +Makefile # Primary build interface |
| 101 | +settings.ini # F Prime project settings (default board, toolchain) |
| 102 | +west.yml # Zephyr workspace manifest |
| 103 | +Kconfig # Zephyr configuration options |
| 104 | +prj.conf # Zephyr project configuration (USB, I2C, SPI, etc.) |
| 105 | +fprime-gds.yaml # GDS command-line defaults |
| 106 | +requirements.txt # Python dependencies |
| 107 | +.python-version # Python version requirement (3.13) |
| 108 | +``` |
| 109 | + |
| 110 | +### Directory Structure |
| 111 | +``` |
| 112 | +FprimeZephyrReference/ |
| 113 | +├── Components/ # Custom F Prime components |
| 114 | +│ ├── BootloaderTrigger/ |
| 115 | +│ ├── Drv/ # Driver components (IMU, RTC, sensor managers) |
| 116 | +│ ├── FatalHandler/ |
| 117 | +│ ├── ImuManager/ |
| 118 | +│ └── Watchdog/ |
| 119 | +├── ReferenceDeployment/ |
| 120 | +│ ├── Main.cpp # Application entry point |
| 121 | +│ └── Top/ # Topology definition |
| 122 | +│ ├── instances.fpp # Component instances |
| 123 | +│ └── topology.fpp # Component connections |
| 124 | +├── project/ |
| 125 | +│ └── config/ # Project-wide FPP configuration |
| 126 | +└── test/ |
| 127 | + └── int/ # Integration tests (pytest) |
| 128 | +
|
| 129 | +lib/ |
| 130 | +├── fprime/ # F Prime framework (39MB, git submodule) |
| 131 | +├── fprime-zephyr/ # F Prime-Zephyr integration (368KB, git submodule) |
| 132 | +└── zephyr-workspace/ # Zephyr RTOS (404MB, git submodule) |
| 133 | +
|
| 134 | +boards/ # Custom board definitions |
| 135 | +└── bronco_space/ |
| 136 | + └── proves_flight_control_board_v5*/ |
| 137 | +
|
| 138 | +docs/ |
| 139 | +├── main-content/ # Setup and build documentation |
| 140 | +└── additional-resources/ # Board-specific guides, troubleshooting |
| 141 | +``` |
| 142 | + |
| 143 | +### Key Architecture Points |
| 144 | + |
| 145 | +**F Prime + Zephyr Integration**: |
| 146 | +- F Prime components defined in `.fpp` files (autocoded to C++) |
| 147 | +- Zephyr handles RTOS, drivers, and hardware abstraction |
| 148 | +- Main entry point: `FprimeZephyrReference/ReferenceDeployment/Main.cpp` |
| 149 | + - **Critical**: 3-second sleep before starting to allow USB CDC ACM initialization |
| 150 | +- Build system: CMake with F Prime and Zephyr toolchains |
| 151 | +- Default board: `proves_flight_control_board_v5c/rp2350a/m33` (configurable in `settings.ini`) |
| 152 | + |
| 153 | +**Component Types**: |
| 154 | +- `.fpp` files: F Prime component definitions (autocoded) |
| 155 | +- `.cpp/.hpp` files: Implementation code |
| 156 | +- `CMakeLists.txt` in each component: Build registration |
| 157 | + |
| 158 | +## Build System Details |
| 159 | + |
| 160 | +### Generated Artifacts Location |
| 161 | +``` |
| 162 | +build-fprime-automatic-zephyr/ # F Prime + Zephyr build cache |
| 163 | +build-artifacts/ |
| 164 | +├── zephyr.uf2 # Firmware binary for flashing |
| 165 | +└── zephyr/fprime-zephyr-deployment/ |
| 166 | + └── dict/ReferenceDeploymentTopologyDictionary.json # For GDS |
| 167 | +``` |
| 168 | + |
| 169 | +### CMake Configuration |
| 170 | +- **Toolchain**: `lib/fprime-zephyr/cmake/toolchain/zephyr.cmake` |
| 171 | +- **Build Type**: Release |
| 172 | +- **Board Root**: Repository root (custom board definitions in `boards/`) |
| 173 | +- **Important Options**: |
| 174 | + - `FPRIME_ENABLE_FRAMEWORK_UTS=OFF` (no framework unit tests) |
| 175 | + - `FPRIME_ENABLE_AUTOCODER_UTS=OFF` (no autocoder unit tests) |
| 176 | + |
| 177 | +### Makefile Targets Reference |
| 178 | +```bash |
| 179 | +make help # Show all available targets |
| 180 | +make submodules # Initialize git submodules |
| 181 | +make fprime-venv # Create Python virtual environment |
| 182 | +make zephyr-setup # Set up Zephyr workspace and ARM toolchain |
| 183 | +make generate # Generate F Prime build cache (force) |
| 184 | +make build # Build firmware (runs generate-if-needed) |
| 185 | +make fmt # Run linters and formatters |
| 186 | +make gds # Start F Prime Ground Data System |
| 187 | +make test-integration # Run integration tests |
| 188 | +make clean # Remove all gitignored files |
| 189 | +make clean-zephyr # Remove Zephyr build files only |
| 190 | +make clean-zephyr-sdk # Remove Zephyr SDK (requires re-running zephyr-setup) |
| 191 | +``` |
| 192 | + |
| 193 | +### CI/CD Pipeline (`.github/workflows/ci.yaml`) |
| 194 | + |
| 195 | +**Jobs**: |
| 196 | +1. **Lint**: Runs `make fmt` (pre-commit checks) |
| 197 | +2. **Build**: Full build with caching |
| 198 | + - Caches: bin tools, submodules, Python venv, Zephyr workspace |
| 199 | + - Runs: `make submodules`, `make fprime-venv`, `make zephyr-setup`, `make generate-ci build-ci` |
| 200 | + - Uploads: `build-artifacts/zephyr.uf2` and dictionary JSON |
| 201 | + |
| 202 | +**Critical for CI Success**: |
| 203 | +- Always run `make fmt` before pushing |
| 204 | +- Ensure code builds with `make build` locally |
| 205 | +- Integration tests are NOT run in CI (require hardware) |
| 206 | + |
| 207 | +## Common Issues & Workarounds |
| 208 | + |
| 209 | +### Issue: Build Fails with "west not found" |
| 210 | +**Solution**: Run `make zephyr-setup` to install west and Zephyr SDK. |
| 211 | + |
| 212 | +### Issue: "No such file or directory: fprime-util" |
| 213 | +**Solution**: Run `make fprime-venv` to create virtual environment with dependencies. |
| 214 | + |
| 215 | +### Issue: CMake cache errors after changing board configuration |
| 216 | +**Solution**: Run `make clean` followed by `make generate build`. |
| 217 | + |
| 218 | +### Issue: USB device not detected on board |
| 219 | +**Workaround**: The board may need to be put into bootloader mode. See board-specific guides in `docs/additional-resources/board-list.md`. |
| 220 | + |
| 221 | +### Issue: Integration tests fail to connect |
| 222 | +**Solution**: Ensure GDS is running (`make gds`) and board is connected. Check serial port in GDS output. |
| 223 | + |
| 224 | +### Issue: Build times out (>2 minutes) |
| 225 | +**Solution**: First build takes 3-5 minutes. Subsequent builds are faster (~30 seconds). Use `timeout: 300` for initial builds. |
| 226 | + |
| 227 | +### Issue: Flashing firmware to board |
| 228 | +**Different boards require different methods**: |
| 229 | +- **RP2040/RP2350**: Copy `.uf2` file to board's USB mass storage |
| 230 | + ```bash |
| 231 | + cp build-artifacts/zephyr.uf2 /Volumes/RPI-RP2 # macOS |
| 232 | + ``` |
| 233 | +- **STM32**: Use STM32CubeProgrammer via SWD |
| 234 | + ```bash |
| 235 | + sh ~/Library/Arduino15/packages/STMicroelectronics/tools/STM32Tools/2.3.0/stm32CubeProg.sh \ |
| 236 | + -i swd -f build-artifacts/zephyr/zephyr.hex -c /dev/cu.usbmodem142203 |
| 237 | + ``` |
| 238 | +- See `docs/additional-resources/board-list.md` for tested boards |
| 239 | + |
| 240 | +## File Modification Guidelines |
| 241 | + |
| 242 | +### When modifying F Prime components: |
| 243 | +1. Edit `.fpp` files for interface changes (ports, commands, telemetry, events) |
| 244 | +2. Edit `.cpp/.hpp` files for implementation |
| 245 | +3. Run `make generate` to regenerate autocoded files |
| 246 | +4. Run `make build` to compile |
| 247 | +5. Run `make fmt` to lint |
| 248 | + |
| 249 | +### When modifying topology: |
| 250 | +1. Edit `FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp` for new component instances |
| 251 | +2. Edit `FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp` for connections |
| 252 | +3. Run `make generate build` |
| 253 | + |
| 254 | +### When adding new components: |
| 255 | +1. Create component directory under `FprimeZephyrReference/Components/` |
| 256 | +2. Add `CMakeLists.txt` with `register_fprime_library()` or `register_fprime_module()` |
| 257 | +3. Add component to parent `CMakeLists.txt` with `add_fprime_subdirectory()` |
| 258 | +4. Follow existing component structure (see `Components/Watchdog/` as example) |
| 259 | + |
| 260 | +### When modifying board configuration: |
| 261 | +1. Edit `settings.ini` to change default board |
| 262 | +2. Or use CMake option: `cmake -DBOARD=<board_name>` |
| 263 | +3. Board definitions are in `boards/bronco_space/` |
| 264 | +4. Run `make clean` then `make generate build` |
| 265 | + |
| 266 | +## Trust These Instructions |
| 267 | + |
| 268 | +These instructions are comprehensive and validated. **Only search for additional information if**: |
| 269 | +- Instructions are incomplete for your specific task |
| 270 | +- You encounter errors not covered in "Common Issues" |
| 271 | +- You need board-specific flashing instructions (see docs/) |
| 272 | + |
| 273 | +For standard build/test/lint workflows, **trust and follow these instructions exactly** to minimize exploration time and command failures. |
0 commit comments