Async buffered serial console for both targets — byte-level ring buffer
with overwrite-on-full semantics. The producer (log!() / send_line)
is O(1) and NEVER blocks the caller: never spins, never awaits, never
creates back-pressure. On full, the oldest bytes are overwritten so the
lines fired just before a failure survive (those are the informative ones).
What input model a board exposes, so a consumer can install the matching
LVGL indev (keypad vs pointer) instead of assuming three buttons (#32 I2).
This is a capability descriptor only — it carries no app vocabulary
(no nav/semantic meaning); see buttons::ButtonEvent for the I1 event
contract and input_caps to query the running board.
The running board’s input capability (#32 I2). Fire27 reports a 3-button
keypad; CoreS3 reports its touch-panel size. Lets a view install the right
indev without hardcoding the board.