Skip to content

HIL: replace build.flags_on with named build variants#3687

Merged
hathach merged 12 commits into
masterfrom
claude/hil-variants
Jun 11, 2026
Merged

HIL: replace build.flags_on with named build variants#3687
hathach merged 12 commits into
masterfrom
claude/hil-variants

Conversation

@hathach

@hathach hathach commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Summary

Replaces the HIL config's build.flags_on with an explicit, named variant schema. Each variant declares its own name (used as the build dir cmake-build-<name> and the HIL report row) and raw flags (CFLAGS, e.g. -DCFG_TUD_DWC2_DMA_ENABLE=1). A board with no variant builds a single target named after the board.

"variant": [
  { "name": "stm32f723disco",     "flags": "" },
  { "name": "stm32f723disco-DMA", "flags": "-DCFG_TUH_DWC2_DMA_ENABLE=1" }
]

This makes variant build dirs and report rows explicit instead of the derived -f1_<flags> suffix.

Changes

  • build.py--build-name <name> (build dir) + --cflag=<token> (raw CFLAGS into CFLAGS_CLI, repeatable; the =-form keeps -D…=1 tokens space-free so they survive the CI matrix's shell word-splitting). Dropped -f1.
  • hil_ci_set_matrix.py — emit one build arg per variant.
  • hil_test.py — iterate variants; report row + firmware dir = variant name.
  • hil_ci.sh-b runs copy the board's dir plus any cmake-build-<board>-* variant dirs (and still fail fast when none exist).
  • get_deps.py — accept/ignore --build-name/--cflag (matrix args are passed through it).
  • tinyusb.json — migrate all 6 flags_on boards to variant.

Test evidence

  • Matrix emits correct per-variant args; tokens survive shell-splitting.
  • build.py builds both stm32f723disco variants; DMA gets CFLAGS_CLI=-DCFG_TUH_DWC2_DMA_ENABLE=1, base none.
  • Hardware (ci.lan rig): both stm32f723disco variants flashed and tested; report shows separate stm32f723disco / stm32f723disco-DMA rows, 0 failed.

Stacked on #3686 (the variant report-row change depends on that PR's HIL report feature). Base will retarget to master once #3686 merges.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 8, 2026 16:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the HIL configuration and tooling to replace the implicit build.flags_on mechanism with explicit, named variant build entries, making build directories and report rows deterministic and human-readable.

Changes:

  • Introduces a variant schema in HIL config (name + raw flags) and migrates existing flags_on boards to the new format.
  • Updates HIL tooling to build and test per-variant (matrix generation, build invocation, firmware discovery/report row labeling).
  • Extends tools/build.py (and get_deps.py passthrough) with --build-name and repeatable --cflag support.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/get_deps.py Accepts/ignores new build CLI args so CI arg passthrough doesn’t fail.
tools/build.py Adds --build-name + --cflag to support named build output dirs and raw CFLAGS injection.
test/hil/tinyusb.json Migrates HIL config from build.flags_on to explicit variant entries.
test/hil/hil_test.py Iterates build variants for build/test execution and report row naming.
test/hil/hil_ci.sh Copies per-board build outputs, attempting to include variant build dirs as well.
test/hil/hil_ci_set_matrix.py Emits one CI build arg set per variant (named dir + cflags tokens).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/build.py
Comment on lines 314 to +315
# build all boards
result = build_boards_list(all_boards, build_defines, build_system, build_flags_on, build_targets)
result = build_boards_list(all_boards, build_defines, build_system, build_name, build_cflags, build_targets)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d2f037b: build.py now errors out when --build-name is combined with families or more than one -b board, since the renamed build dir is global to the invocation.

Comment thread test/hil/hil_ci.sh Outdated
Comment on lines +69 to +77
# Copy the board's build dir plus any variant dirs (cmake-build-<BOARD>-<variant>).
# Collect only dirs that actually exist (the bare cmake-build-<BOARD> is a literal,
# not a glob, so it would otherwise stay in the list even when missing).
shopt -s nullglob
BUILD_DIRS=()
for d in "$ROOT_DIR"/examples/cmake-build-"$BOARD" "$ROOT_DIR"/examples/cmake-build-"$BOARD"-*; do
[ -d "$d" ] && BUILD_DIRS+=("$d")
done
shopt -u nullglob

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in d2f037b: hil_ci.sh -b now reads the variant names from $CONFIG and copies cmake-build-<variant.name> for each (deduplicated), keeping the cmake-build--* glob as a fallback for ad-hoc local builds.

@claude

claude Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

No changes
file .text .rodata .data .bss size % diff
audio_device.c 2896 0 1259 1625 4515 +0.0%
cdc_device.c 1239 16 1092 735 1972 +0.0%
cdc_host.c 6413 487 15 994 7619 +0.0%
dcd_ch32_usbfs.c 1582 0 0 2444 4026 +0.0%
dcd_ch32_usbhs.c 1892 0 0 481 2373 +0.0%
dcd_ci_fs.c 1924 0 0 1290 3214 +0.0%
dcd_ci_hs.c 1756 0 0 1344 2534 +0.0%
dcd_da146xx.c 3067 0 0 144 3211 +0.0%
dcd_dwc2.c 4223 19 0 265 4506 +0.0%
dcd_eptri.c 2273 0 0 259 2532 +0.0%
dcd_ft9xx.c 3284 0 0 172 3456 +0.0%
dcd_khci.c 1952 0 0 1290 3242 +0.0%
dcd_lpc17_40.c 1481 0 0 648 1805 +0.0%
dcd_lpc_ip3511.c 1463 0 0 264 1683 +0.0%
dcd_mm32f327x_otg.c 1477 0 0 1290 2767 +0.0%
dcd_msp430x5xx.c 1801 0 0 176 1977 +0.0%
dcd_musb.c 2225 0 0 171 2396 +0.0%
dcd_nrf5x.c 2939 0 0 292 3231 +0.0%
dcd_nuc120.c 1096 0 0 78 1174 +0.0%
dcd_nuc121.c 1170 0 0 101 1270 +0.0%
dcd_nuc505.c 0 0 1533 157 1690 +0.0%
dcd_rp2040.c 840 0 764 653 2257 +0.0%
dcd_rusb2.c 2918 0 0 156 3074 +0.0%
dcd_samd.c 1036 0 0 266 1302 +0.0%
dcd_samg.c 1322 0 0 72 1394 +0.0%
dcd_stm32_fsdev.c 2558 0 0 291 2849 +0.0%
dfu_device.c 777 28 712 138 914 +0.0%
dfu_rt_device.c 157 0 134 0 157 +0.0%
dwc2_common.c 603 22 0 0 615 +0.0%
ecm_rndis_device.c 1059 0 1 2759 3818 +0.0%
ehci.c 2763 0 0 6274 7783 +0.0%
fsdev_common.c 180 0 0 0 180 +0.0%
hcd_ch32_usbfs.c 2491 0 0 502 2993 +0.0%
hcd_ci_hs.c 181 0 0 0 181 +0.0%
hcd_dwc2.c 5015 25 1 513 5554 +0.0%
hcd_khci.c 2443 0 0 454 2897 +0.0%
hcd_musb.c 3071 0 0 157 3228 +0.0%
hcd_pio_usb.c 262 0 240 0 502 +0.0%
hcd_rp2040.c 1996 17 4 321 2338 +0.0%
hcd_rusb2.c 2923 0 0 245 3168 +0.0%
hcd_samd.c 2220 0 0 324 2544 +0.0%
hcd_stm32_fsdev.c 3257 0 1 420 3678 +0.0%
hid_device.c 1125 44 997 119 1244 +0.0%
hid_host.c 1241 0 0 1251 2492 +0.0%
hub.c 1384 8 8 30 1418 +0.0%
midi2_device.c 2634 52 1175 566 3222 +0.0%
midi2_host.c 1802 0 0 5921 7723 +0.0%
midi_device.c 1151 0 1007 624 1773 +0.0%
midi_host.c 1341 7 7 3635 4979 +0.0%
msc_device.c 2517 108 2281 806 3323 +0.0%
msc_host.c 1636 0 0 394 2030 +0.0%
mtp_device.c 1717 22 743 588 2312 +0.0%
ncm_device.c 1757 28 815 4354 6124 +0.0%
ohci.c 1925 0 0 2503 4428 +0.0%
printer_device.c 830 0 706 566 1394 +0.0%
rp2040_usb.c 386 35 619 11 1051 +0.0%
rusb2_common.c 160 0 16 0 176 +0.0%
tusb.c 455 0 387 3 457 +0.0%
tusb_fifo.c 853 0 486 0 848 +0.0%
typec_stm32.c 820 8 2 12 842 +0.0%
usbc.c 420 2 20 166 608 +0.0%
usbd.c 3519 58 91 355 3936 +0.0%
usbh.c 4967 57 82 1161 6233 +0.0%
usbtmc_device.c 2196 24 68 316 2544 +0.0%
vendor_device.c 641 0 534 565 1204 +0.0%
video_device.c 4443 5 1235 479 4914 +0.0%
TOTAL 124145 1072 17035 52190 177894 +0.0%

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Hardware-in-the-loop (HIL) Test Report

hfp-iar

Board cdc_dual_ports dfu cdc_msc cdc_msc_throughput audio_test_freertos dfu_runtime cdc_msc_freertos hid_boot_interface msc_dual_lun hid_generic_inout printer_to_cdc midi_test mtp
stm32l412nucleo ✅ CDC 636k/401k MSC 818k/725k
stm32f746disco ✅ CDC 10.9M/8.6M MSC 17.8M/18.7M
stm32f746disco-DMA ✅ CDC 12.6M/10.6M MSC 15.8M/31M
lpcxpresso43s67 ✅ CDC 10.4M/9.4M MSC 20.4M/19.9M

Legend: ✅ pass · ❌ fail · ⚪ skipped · blank not run

hfp.json

Board cdc_dual_ports dfu cdc_msc cdc_msc_throughput audio_test_freertos dfu_runtime cdc_msc_freertos hid_boot_interface msc_dual_lun hid_generic_inout printer_to_cdc midi_test mtp
stm32l412nucleo ✅ CDC 628k/402k MSC 795k/770k
stm32f746disco ✅ CDC 12.2M/8.5M MSC 13.6M/29.7M
stm32f746disco-DMA ✅ CDC 13.5M/9.7M MSC 19.1M/30.3M
lpcxpresso43s67 ✅ CDC 12.3M/12.3M MSC 24.1M/24.8M

Legend: ✅ pass · ❌ fail · ⚪ skipped · blank not run

tinyusb.json

Board cdc_dual_ports dfu cdc_msc cdc_msc_throughput audio_test_freertos dfu_runtime cdc_msc_freertos hid_boot_interface msc_dual_lun hid_generic_inout printer_to_cdc midi_test mtp host_info_to_device_cdc cdc_msc_hid msc_file_explorer msc_file_explorer_freertos device_info hid_composite_freertos
ek_tm4c123gxl ✅ CDC 770k/732k MSC 642k/951k
espressif_p4_function_ev rd 409KB/s
espressif_p4_function_ev-DMA rd 409KB/s
espressif_s3_devkitm rd 409KB/s
espressif_s3_devkitm-DMA
feather_nrf52840_express ✅ CDC 357k/403k MSC 564k/497k
max32666fthr ✅ CDC 7.1M/14.3M MSC 7.5M/21M
metro_m4_express ✅ CDC 372k/366k MSC 555k/506k
mimxrt1015_evk ✅ CDC 14.6M/7.2M MSC 24.3M/19.3M
mimxrt1064_evk ✅ CDC 14.6M/9.2M MSC 24.7M/18.4M rd 1368KB/s rd 1365KB/s
lpcxpresso11u37 ✅ CDC 334k/316k MSC 550k/508k
ra4m1_ek ✅ CDC 515k/465k MSC 571k/527k
raspberry_pi_pico ✅ CDC 766k/575k MSC 998k/1M
raspberry_pi_pico_w rd 1106KB/s rd 1022KB/s
raspberry_pi_pico2 rd 1110KB/s rd 1022KB/s
adafruit_fruit_jam ✅ CDC 499k/438k MSC 977k/990k rd 62KB/s rd 62KB/s
stm32f072disco ✅ CDC 461k/304k MSC 506k/500k
stm32f407disco ✅ CDC 893k/600k MSC 881k/1000k
stm32f723disco ✅ CDC 714k/723k MSC 1M/983k rd 18078KB/s rd 4096KB/s
stm32f723disco-DMA ✅ CDC 995k/681k MSC 1.1M/1M rd 20164KB/s rd 4096KB/s
stm32h743nucleo ✅ CDC 508k/511k MSC 511k/511k
stm32h743nucleo-DMA ✅ CDC 622k/532k MSC 572k/549k
stm32g0b1nucleo ✅ CDC 451k/356k MSC 473k/511k
stm32l476disco ✅ CDC 544k/520k MSC 570k/555k
stm32u083nucleo ✅ CDC 653k/505k MSC 753k/526k

Legend: ✅ pass · ❌ fail · ⚪ skipped · blank not run

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

Top 10 targets by memory change (%) (out of 2345 targets) View Project Dashboard →

target .text .rodata .data .bss total % diff
frdm_kl25z/board_test 308 → 304 (-4) 308 → 304 (-4) -1.3%
stm32l412nucleo/board_test 240 → 232 (-8) 648 → 640 (-8) -1.2%
metro_m0_express/board_test 376 → 372 (-4) 376 → 372 (-4) -1.1%
stm32g0b1nucleo/board_test 216 → 212 (-4) 408 → 404 (-4) -1.0%
cynthion_d11/board_test 412 → 408 (-4) 412 → 408 (-4) -1.0%
stm32l052dap52/board_test 216 → 212 (-4) 412 → 408 (-4) -1.0%
stm32c071nucleo/board_test 232 → 228 (-4) 428 → 424 (-4) -0.9%
b_u585i_iot2a/board_test 288 → 280 (-8) 864 → 856 (-8) -0.9%
stm32u083cdk/board_test 244 → 240 (-4) 436 → 432 (-4) -0.9%
lpcxpresso51u68/board_test 440 → 436 (-4) 440 → 436 (-4) -0.9%

Base automatically changed from update-hil-pool to master June 9, 2026 06:40
@hathach hathach force-pushed the claude/hil-variants branch 2 times, most recently from 3dc8416 to 85775f3 Compare June 9, 2026 07:24
@hathach

hathach commented Jun 9, 2026

Copy link
Copy Markdown
Owner Author

@HiFiPhile I think I mess up your vm, at first I notice the stm32f7 jlink become stlink. So I guess the fw got reverted somehow or it go into bootloader mode. I try to reboot your VM, and now the jlink for lpcxpresso43 is also missing. I guess I have to ping you for the roll back or something.

@HiFiPhile

Copy link
Copy Markdown
Collaborator

@HiFiPhile I think I mess up your vm, at first I notice the stm32f7 jlink become stlink. So I guess the fw got reverted somehow or it go into bootloader mode. I try to reboot your VM, and now the jlink for lpcxpresso43 is also missing. I guess I have to ping you for the roll back or something.

I'll try to put debuggers in a separate hub in a few days.

@hathach

hathach commented Jun 9, 2026

Copy link
Copy Markdown
Owner Author

I think that is Ok. I have them all on the same hub aswell. I guess it is some weird things that got stlink reverted back to its stock firmware. Why reboot make it worse is out of my understanding.

@HiFiPhile

Copy link
Copy Markdown
Collaborator

I just unplug and replugged. For audio test it seems a delay is needed before launching arecord.

hathach and others added 4 commits June 10, 2026 18:15
Boards declare build variants as `variant: [{name, flags}]` instead of
`build.flags_on`. The variant `name` is the build dir (cmake-build-<name>) and
the HIL report row; `flags` is the raw CFLAGS string (-D...=1) injected via
CFLAGS_CLI. No `variant` => a single build named after the board.

- build.py: --build-name <name> (dir) + --cflag=<token> (raw CFLAGS, repeatable,
  =form survives the matrix's shell word-splitting); drop -f1/CFLAGS wrapping.
- hil_ci_set_matrix.py: emit one build arg per variant.
- hil_test.py: iterate variants; report row + build dir = variant name.
- hil_ci.sh: copy all cmake-build-<board>* dirs for -b runs.
- get_deps.py: accept (ignore) --build-name/--cflag from matrix args.
- tinyusb.json: migrate all 6 flags_on boards to variant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The variant-aware -b path put the bare cmake-build-<BOARD> literal into the
array unconditionally (nullglob only drops globs, not literals), so the
empty-check never fired and a missing build silently produced an all-"no
binary" run instead of erroring. Collect only dirs that actually exist, then
error out if none.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Every DWC2 DMA variant now enables both -DCFG_TUD_DWC2_DMA_ENABLE=1 and
-DCFG_TUH_DWC2_DMA_ENABLE=1 (stm32f723disco-DMA, stm32h743nucleo-DMA,
stm32f769disco-DMA previously had only one of the two). Also add a
stm32f746disco-DMA variant to hfp.json with both flags. stm32l412nucleo is
left untouched (STM32L4 USB FS, not DWC2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Each variant carries its own --build-name/--cflag, which are global to a single
build.py invocation — joining all hfp.json matrix entries leaked a variant's DMA
flags onto every board (e.g. stm32l412nucleo, which isn't DWC2) and collided
their build dirs. Iterate the matrix entries and build each separately, matching
the per-entry gcc/esp-idf matrix builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hathach hathach force-pushed the claude/hil-variants branch from d723e2d to 3445924 Compare June 10, 2026 11:16
hathach and others added 8 commits June 10, 2026 18:19
- tools/build.py: reject --build-name with families or more than one
  board; all boards would otherwise clobber the same renamed build dir
- hil_ci.sh -b: read variant names from $CONFIG when collecting build
  dirs to copy, since variant names are not required to be prefixed
  with the board name; keep the glob as fallback and deduplicate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CFG_TUD_DWC2_SLAVE_ENABLE defaults to !CFG_TUD_DWC2_DMA_ENABLE, so
building the variant with TUD DMA compiled slave mode out — but the
f723disco device port (port0) is the slave-only FS core, leaving the
device with no working transfer mode: every device test failed with
no enumeration and the retries blew the 3000s HIL pool timeout.

The DMA variant on this board is meant to exercise the HS host port
(port1), so only enable CFG_TUH_DWC2_DMA_ENABLE.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
hil-hfp-iar hung for 26+ minutes (until the 30-min job timeout) in
printer_to_cdc on stm32l412nucleo: ser.write() blocks forever when the
device stops draining CDC OUT, since serial.Serial was opened with a
read timeout only. With write_timeout the wedge becomes a normal test
failure that goes through retry instead of stalling the whole pool.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The wfe park from #3690 bricked SWD on mimxrt1064_evk and max32666fthr:
sleeping gates the debug clocks on these MCUs, and since the parked
image is the boot image the board comes back unflashable — attach and
connect-under-reset both fail and the state survives power cycles.
Verified on the ci.lan rig: J-Link reads garbage (CPUID 0xA05F0001) on
the 1064, openocd gets "stalled AP operation" on the max32666, after a
full rig reboot. Both boards need one-time manual recovery.

A busy spin keeps the debug port clocked on every MCU; the park goal
(no USB activity) is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Report cell now reads "✅ CDC 25.2M/20.4M MSC 35.7M/32.9M" instead of
the terser "C 25.2M/20.4M M 35.7M/32.9M", so pass/fail and which
numbers belong to which class are clear at a glance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Restructure: the CI park build gets a dedicated minimal main() at the
top of the file instead of ifdef blocks woven through the normal
blink/echo implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
IAR builds with --warnings_are_errors and flags the return after the
infinite park loop: Error[Pe111] statement is unreachable (broke
stm32f3/stm32wba IAR CI builds).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hathach hathach merged commit 6f35e76 into master Jun 11, 2026
403 of 430 checks passed
@hathach hathach deleted the claude/hil-variants branch June 11, 2026 01:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants