Hardware-in-the-loop testing
The HIL tools run checks on an ESP32-S31 board and, for wired or radio peer tests, a programmable test board. A host script controls the serial consoles and saves the results.
Test tools
Tool |
Runs on |
Purpose |
|---|---|---|
|
Host computer |
Select and coordinate test cases |
|
ESP32-S31 Linux |
Run board-side checks |
|
ESP32-P4 test board |
Provide GPIO, serial, bus, and other peer functions |
The P4 tester keeps fixture outputs disabled until a test arms them and returns them to the disarmed state afterwards. Use the fixture wiring and firmware instructions in its README.
1. Run host tests
From the parent checkout, run:
make check-host
This includes the feature-contract, selftest, overlay, and BTstack regressions.
The feature tests use a host C compiler to exercise I2C command generation,
SPI word ordering, and I2S configuration. Firmware/helper tests do not imply
that their operations are exposed by the current SoftMAC frontend. The BTstack
test uses pinned sources explicitly prepared with make btstack-source (also
included in make fetch). See
Development setup for prerequisites and the complete
check-fast workflow. Host-test success is separate from board-test evidence.
2. Prepare the boards
Build the full-board image and flash the S31:
make image
make PORT=/dev/ttyUSB0 BAUD=2000000 flash-existing-all
Replace PORT with the S31 serial device. make image builds and verifies the
host-side images; make flash-existing-all verifies and writes the published
dist/current set without rebuilding. This preserves persist only on the same
installed layout. For a first installation or layout change, follow the backup
and clean-install steps in Flash and first boot. Confirm the
first login and startup checks, then install
the P4 tester firmware for cases that need it. Connect the fixture according
to its pin map, with a common ground and compatible signal voltages. Close
serial monitors before starting the host runner.
Check the runner’s available cases and serial-port options:
python3 tools/hil/s31_hil.py --help
3. Run a test
For a wired I2C test with both boards:
mkdir -p logs
python3 tools/hil/s31_hil.py --board both --case i2c \
--output logs/hil-i2c.json
To repeat the test at 400 kHz:
python3 tools/hil/s31_hil.py --board both --case i2c \
--i2c-speed 400000 --repeat 12 --output logs/hil-i2c-repeat.json
Other wired cases include gpio, uart, spi, i2s, and pwm-pcnt.
spi-stress and i2s-stress use longer transfers for characterization.
For S31-only checks, select --board s31:
python3 tools/hil/s31_hil.py --board s31 --case lp-core \
--output logs/hil-lp-core.json
python3 tools/hil/s31_hil.py --board s31 --case smp-irq-dma \
--output logs/hil-smp-irq-dma.json
The host runner and target agent have different command-line options. Use the runner examples above when controlling tests from your computer.
Storage tests
Insert the appropriate storage device before running sdmmc or usb-drive:
python3 tools/hil/s31_hil.py --board s31 --case sdmmc
python3 tools/hil/s31_hil.py --board s31 --case usb-drive
The SD/MMC case temporarily applies sdmmc0 bus-width=1 for the 1-bit
CLK/CMD/DAT0 fixture if no sdmmc0 overlay is already active. An existing
overlay is left unchanged, so check that its width and routing match your
wiring. The case reads 1 MiB from the card.
The USB case is read-only by default. To allow its temporary 64 KiB write
test on a disposable test drive, add --allow-usb-write.
Radio tests
With the P4/C6 radio peer connected, run:
python3 tools/hil/s31_hil.py --board both --case c6-wifi \
--peer-connected --output logs/hil-wifi.json
python3 tools/hil/s31_hil.py --board both --case c6-ble \
--peer-connected --output logs/hil-ble.json
The Wi-Fi case sets up a fixture access point and temporary station profile, then checks association, address assignment, and packet exchange. It also temporarily changes radio services and restores them during cleanup.
For power-management tests, check the current suspend limitations first. GPIO wake requires wiring to LP GPIO0–7 rather than the normal higher-numbered fixture pins.
Flash safety
The current layout has no HIL scratch partition. Destructive flash testing must check the actual MTD ranges and must not use persist or any other live partition. Refuse the test if there is no explicitly safe range. Do not use stale offsets or hand-created MTD nodes to bypass those checks.
Read the results
Board results use HIL1 JSON records. Tests report PASS, FAIL, or SKIP, along
with the operation, evidence level, and a short explanation. A probe-level
PASS records registration or presence; a data-level PASS checks the operation
named in that result. Neither establishes untested modes or peripherals. Check any failed or skipped
prerequisites and review cleanup errors before starting another case.
Keep the output file with a brief description of the board, firmware build, wiring, and command used. For data-transfer tests, include the peer result; for power tests, include wake reason and any current measurements separately. Update the support matrix when a result changes the documented feature status.
Add a test case
Add the host sequence, S31 operation, and peer response needed for the test. Set timeouts for waits and include cleanup for success, error, and interruption. A useful case checks the returned data or resulting device behavior and gives a clear explanation when a required device or fixture is missing.