Version: 1.0 (Phase 6 baseline). Owner: root3315. Status: draft β bench BOM listed, firmware hooks pending.
HIL testing closes the gap between the host ctest green pipeline
(which proves the code is correct) and the TRL-5 claim (which
requires proof the code runs on target hardware in a relevant
environment). This plan specifies the minimal bench that turns
βthe firmware compiles for STM32F446REβ into βthe firmware
executes, reads real sensors, transmits real beacons, and keeps
going across a 48 h run.β
Cost target: β€ $150. Everything on the BOM is off-the-shelf and shipped to a student team within one week.
| Item | Vendor / P/N | Qty | Unit $ | Purpose |
|---|---|---|---|---|
| Nucleo-F446RE dev board | STMicro / NUCLEO-F446RE | 1 | 14 | Target MCU with integrated ST-Link |
| BME280 breakout | Adafruit 2652 | 1 | 15 | IΒ²C sensor under test |
| MPU-9250 breakout | generic eBay | 1 | 8 | SPI sensor under test |
| TMP117 breakout | SparkFun SEN-16416 | 1 | 15 | Precision temp sensor (Tboard) |
| u-blox NEO-M8N breakout | generic | 1 | 25 | GNSS receiver (IΒ²C/DDC path) |
| Logic analyser | Saleae Logic 8 / Kingst LA1010 | 1 | 25 | Bus tracing, WCET probe |
| USB inline ammeter | USB charger-doctor | 1 | 8 | Power profile measurements |
| RTL-SDR dongle | generic RTL2832U | 1 | 25 | RF decode for AX.25 beacon over air |
| HopeRF RFM98W breakout | generic | 1 | 10 | 437 MHz TX for RF loop |
| Breadboard + jumpers | any | 1 | 10 | Wiring |
| Total | Β | Β | 155 | Β |
ββββββββββββββββββββ
β Host PC (Linux) β
β - pytest β
β - openocd β
β - gqrx β
ββββ¬βββββββ¬βββββββββ
βUSB-A βUSB-A
ββββ ST-Link βββββββ ββββββββ RTL-SDR βββ antenna ββ
β β
β ββββ IΒ²C (PB6/PB7) ββ BME280 / TMP117 / u-blox β
β β β
βΌ βΌ βββ SPI (PA5/6/7) ββ MPU-9250 β
βββββββββββββββββ β
β Nucleo ββ€ βββ USART1 TX (PA9) ββ RFM98W β antenna ββ
β F446RE ββ β
β βββββ
β βββββ USART2 (PA2/3) ββ FTDI USB-UART ββ host VCP
ββββββββββββββββ
The HIL test targets in the repo are defined as pytest tests that talk to the bench over two channels:
The tests live under tests/hil/ (directory created by this
plan; files added in the Phase 6 follow-up). Each test ID maps
1:1 to an SRS REQ:
| Test ID | SRS ref | Scenario | Pass criterion | Β | Β |
|---|---|---|---|---|---|
| HIL-01 | REQ-BLD-001 | make flash + reset |
OBC emits βUniSat v1.2 boot OKβ on UART VCP within 3 s | Β | Β |
| HIL-02 | REQ-TLM-001 | Collect 5 beacons | 4 consecutive intervals within 30 s Β± 500 ms | Β | Β |
| HIL-03 | REQ-TLM-003 | Tboard value vs TMP117 direct read | Β | ΞT | < 0.2 Β°C between beacon byte 14-15 and reference |
| HIL-04 | REQ-CMD-001 | Transmit authenticated cmd via RFM98W | OBC increments accepted stat; handler executes |
Β | Β |
| HIL-05 | REQ-CMD-002 | Transmit tampered cmd | OBC increments rejected_bad_tag; no handler fire |
Β | Β |
| HIL-06 | REQ-CMD-003 | Replay previous valid cmd | OBC increments rejected_replay |
Β | Β |
| HIL-07 | REQ-FDIR-001 | Unplug BME280 mid-run | FDIR IΒ²C bus counter β₯ 5 within 60 s, beacon shows FAULT stats | Β | Β |
| HIL-08 | REQ-EPS-003 | Drop bus voltage via bench PSU to 3.0 V | OBC enters safe mode within 30 s | Β | Β |
| HIL-09 | REQ-SAFE-002 | While in safe mode, attempt an imaging command | Handler refuses + FDIR logs | Β | Β |
| HIL-10 | REQ-BLD-002 | After 48 h soak | arm-none-eabi-size firmware.elf section totals unchanged; HWM stable |
Β | Β |
# 0. Flash the image you want to soak.
make flash
# 1. Start ground-station collector.
python3 ground-station/cli/ax25_listen.py --serial /dev/ttyACM0 \
--out soak_log.jsonl &
# 2. Start telemetry consistency checker (counts beacons, asserts
# monotonic uptime, logs missed intervals).
python3 tests/hil/soak_sentinel.py \
--duration 172800 \
--log soak_log.jsonl \
--report soak_report.md
# 3. Let it run. 48 h.
# 4. After completion, `soak_report.md` contains pass/fail.
The sentinel script is the same shape as
flight-software/tests/test_long_soak.py except the clock is real
wall time and the state machine under test is the actual OBC, not
the simulated Python flight-controller.
After a clean soak, the operator files a TRL-5 characterisation packet containing:
docs/characterization/*.md populated (not TBD).soak_report.md showing β₯ 48 h continuous operation.cppcheck clean, coverage β₯ 80 %, sanitizers clean
(already true at Phase 5 baseline for host tests; HIL adds
the ARM-target flash/RAM numbers).That packet is the software deliverable of TRL 5. The hardware
deliverable (vibration, TVAC, radiation) remains out of scope
per docs/project/GAPS_AND_ROADMAP.md.
| Test | Status |
|---|---|
| Bench BOM defined | β (this document) |
| Wiring diagram | β (this document) |
| Test matrix | β (this document) |
| Firmware HIL hooks (mode command, wcet probe) | β³ Phase 6 follow-up |
tests/hil/ pytest runner |
β³ Phase 6 follow-up |
scripts/parse_wcet_tlm.py |
β³ Phase 6 follow-up |
| Soak sentinel script | β³ Phase 6 follow-up |
| First HIL pass on hardware | β³ depends on bench BOM purchase |