firmware: zero-copy StoredMap/CountingPattern envelopes + RAM tooling (lifted from #45) - #223
Merged
Merged
Conversation
… (lifted from #45) Lifts the still-useful, not-yet-on-main pieces of PR #45 (FUG-71 device heap pressure) onto current main, reconciled with the code as it has since moved. Zero-copy protocol envelopes (shrinks the by-value micropb frames that ride the heap-allocated loop/httpd task stacks in lm_player_handle): - handle_get_stored_map: encode the StoredMapChunk reply ZERO-COPY straight into the output buffer instead of materializing a by-value pb::StoredMapChunk (a 1 KiB inline Vec). Request is hand-decoded too. Firmware profile stubs StoredMapChunk.data to 8 B (gen_main.rs); host keeps 1 KiB for the encoder. - handle_set_counting_pattern: walk the repeated ColorBlock array (32 x f64-rgb, the fat arm of ClientMessage) ZERO-COPY into pre-reduced 8-bit blocks and install via the shared Player::set_counting_blocks path; also parse the optional color_order string so behavior matches the by-value path exactly. Firmware profile stubs SetCountingPattern.blocks to 1; host keeps 32. - envelope_size_test guards the shrunk structs directly. RAM tooling: - tools/ram_chart.bzl: a `.ram_chart` bazel-run sibling for firmware_binary that charts static SRAM per symbol/component (backed by fw_memaudit.py; wired onto esp32c6_netstack). - fw_memaudit.py --compare: diff a --json snapshot to track a reclaim per-symbol. - docs/design/ram-budget.md: the RAM budget + tooling writeup. The BLE-release / Bluedroid-lifecycle half of #45 is deliberately NOT lifted: main has since replaced Bluedroid with the heapless BLE host (//firmware/blehost:ble_ffi), so those changes are obsolete. Reconciliation notes vs #45's original assumptions: - The ServerMessage oneof is now dominated by the newer HardwareConfigState arm (~4 KiB board-capabilities catalog, full-size in both profiles), NOT by StoredMapChunk. So the size guard asserts on the StoredMapChunk / SetCountingPattern structs directly rather than on the whole envelope. - set_counting_pattern gained a color_order field on main; the zero-copy walker parses and forwards it so counting_preempt_test still passes. Verified: envelope_size_test, ffi_test, counting_preempt_test, and the firmware/player session/arena/phone-frame tests all pass; the ram_chart target and player_app build graph query clean. The firmware-profile link is left to CI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lifts the still-useful, not-yet-on-
mainpieces of #45 (FUG-71 device heap pressure) into a clean PR off currentmain, reconciled with the code as it has since moved. #45 is being closed as partially superseded.Lifted from #45
Zero-copy protocol envelopes
The by-value micropb decode + reply build in
lm_player_handleputs these structs on the heap-allocated loop/httpd task stacks, so shrinking them is heap FUG-71 wants back.handle_get_stored_map— encodes theStoredMapChunkreply zero-copy straight into the output buffer instead of materializing a by-valuepb::StoredMapChunk(a 1 KiB inlineVec); the request is hand-decoded too. The firmware profile stubsStoredMapChunk.datato 8 B (gen_main.rs); host keeps the full 1 KiB for the generated encoder / conformance.handle_set_counting_pattern— walks the repeatedColorBlockarray (32 × f64-rgb — the fat arm ofClientMessage) zero-copy into pre-reduced 8-bit blocks and installs them via a new sharedPlayer::set_counting_blockspath. The firmware profile stubsSetCountingPattern.blocksto 1; host keeps 32. Reconciliation:maingrew acolor_orderfield on this message since FUG-71: solve device heap pressure (release BLE + zero-copy envelopes + RAM tooling) #45, so the walker also parses/forwards it and the by-value host path was refactored (not just replaced) to keep behavior identical.envelope_size_test— a size-regression guard on the shrunk structs.RAM tooling
tools/ram_chart.bzl— a.ram_chartbazel runsibling forfirmware_binarythat charts static SRAM per symbol/component (backed byfw_memaudit.py, wired ontoesp32c6_netstack).fw_memaudit.py --compare— diff a--jsonsnapshot to track a reclaim per-symbol (the fw_memaudit core,--json, and addr2line were already onmain; only--compareis new here).docs/design/ram-budget.md— the RAM-budget + tooling writeup.Deliberately NOT lifted (superseded)
The BLE-release / Bluedroid-lifecycle half of #45 (
improv_ble.cpp/.h,main.cpp) is obsolete:mainhas since replaced Bluedroid entirely with the heapless BLE host (//firmware/blehost:ble_ffi), which removes that permanent BLE heap draw structurally rather than tearing a stack down at runtime.Reconciliation notes vs #45's original assumptions
maintheServerMessageoneof is dominated by the newerHardwareConfigStatearm (~4 KiB board-capabilities catalog — 31 GPIO pins × 64-B note strings + LED modes, full-size in both profiles), not byStoredMapChunk. So the size guard asserts on theStoredMapChunk/SetCountingPatternstructs directly rather than on the whole envelope (which a StoredMapChunk regression could no longer move).httpd_ssltask-stack-size retune that FUG-71: solve device heap pressure (release BLE + zero-copy envelopes + RAM tooling) #45 did inmain.cppis not included here —main.cppis on the abandoned (heapless-host) path; the stack retune is a clean follow-up once these frames are small.Verification
envelope_size_test,ffi_test,counting_preempt_test, andfirmware/playersession_test/arena_upload_test/phone_client_frames_testall pass.fw_memaudit.py --compareexercised on synthetic snapshots;black/buildifierclean.bazel queryresolves the newram_charttarget and its ELF filegroup.esp32c6_netstack) is left to CI, per repo convention. The zero-copy code hand-walks bytes so it is profile-agnostic; the hostffi_testcompiles the sameffi.rs.🤖 Generated with Claude Code