Skip to content

sprint_event: avoid %hu format (unsupported by MicroPython internal printf) - #888

Merged
dpwe merged 2 commits into
mainfrom
fix-sprint-event-hu-printf
Jul 27, 2026
Merged

sprint_event: avoid %hu format (unsupported by MicroPython internal printf)#888
dpwe merged 2 commits into
mainfrom
fix-sprint-event-hu-printf

Conversation

@bwhitman

Copy link
Copy Markdown
Collaborator

Problem

sprint_event in src/patches.c printed the osc field with PRIu16, which expands to %hu. MicroPython's internal printf (mp_vprintf) has no h length-modifier support, so in any MicroPython port where MICROPY_USE_INTERNAL_PRINTF=1 overrides snprintf (the default; micropython/shared/libc/printf.c routes it into mp_vprintf), formatting reaches assert(*fmt == '%' || !"unsupported fmt char") in py/mpprint.c and aborts on debug builds — triggered by anything that serializes events: tulip.amy_dump_state(), amyboard.update_sketch_knobs(), etc.

Affected in practice: Tulip Linux desktop builds and the AMYboard VCV Rack plugin build. Tulip macOS desktop happens to be immune: Darwin's fortify headers rewrite snprintf calls to ___snprintf_chk (system libc) regardless of -U _FORTIFY_SOURCE, bypassing the MicroPython override — verified live at the desktop REPL.

Fix

Print the osc field with %u and an (unsigned) cast (varargs promote uint16_t to int anyway, so this is value-identical). These were the only two %hu sites reachable through snprintf in AMY; all other formats used (%d/%u via 32-bit PRI macros, %.3f, %s) are supported by mp_vprintf.

Testing

make test: 109 tests pass.

🤖 Generated with Claude Code

PRIu16 expands to "%hu", which MicroPython's internal printf
(mp_vprintf, used when MICROPY_USE_INTERNAL_PRINTF=1 overrides
snprintf) does not support: it hits
assert(*fmt == '%' || !"unsupported fmt char") in py/mpprint.c and
aborts on debug builds. This fires in any MicroPython port that links
AMY and binds snprintf to the internal implementation (e.g. Tulip
Linux desktop, or the AMYboard VCV Rack plugin build) whenever
sprint_event runs — amy_dump_state(), update_sketch_knobs(), etc.
Print the osc field with %u and an unsigned cast instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🎛️ AMY HW CI (AMYboard bench)

Flashed this PR's AMY (LoadTestChord: 6-voice Juno patch=1, one held note every 2 s) onto the physical AMYboard and measured the smoothed render load as the chord grows — back-to-back with the same sketch built at the PR's merge base, so Δ is this PR's own cost.

PASS — the bench ran the test to completion.

notes held main @ 2e954a1 this PR Δ
1 1386 1385 -1
2 1586 1586 +0
3 2170 2169 -1
4 2353 2353 +0
5 3005 3004 -1
6 3187 3188 +1

Full chord settled render μs: 3189 (was 3192, Δ -0.1%) (peak 3197, 39 samples)

⬇️ Artifacts: serial log · load trace · report

Self-hosted bench (amyboardci). FAIL means only that the test could not run — the load values are informational, with no threshold and no audio compare. See tools/arduino_loadsweep/.

@dpwe
dpwe merged commit 63cfb3d into main Jul 27, 2026
12 checks passed
@bwhitman

Copy link
Copy Markdown
Collaborator Author

⛓️ tulipcc integration PR opened

This merge was pinned into tulipcc for full-system CI: shorepine/tulipcc#1245

Test it there and merge that PR to move tulipcc onto this AMY.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants