Skip to content

ESP32 and embedded runtime hardening#258

Merged
mariusandra merged 1 commit into
mainfrom
esp32-embedded-hardening
Jul 15, 2026
Merged

ESP32 and embedded runtime hardening#258
mariusandra merged 1 commit into
mainfrom
esp32-embedded-hardening

Conversation

@mariusandra

Copy link
Copy Markdown
Collaborator

Summary

Split out of #257 (FrameOS Cloud link). Device runtime, firmware pipeline, and embedded frontend workflows:

Device runtime (Nim + ESP-IDF glue)

  • Streaming decode of multi-MB PNGs and chunked HTTP bodies — downloads are no longer size-limited by socket fragmentation
  • Image download failures paint an error frame instead of "No image provided"; render errors paint into the live canvas
  • Frame-sized images are not pinned in the scene node cache; OOM-aborted renders that leak the heap beyond recovery trigger a restart
  • Serialized scenes.json writers; console polls sleep a full tick
  • Documented the no-image-proxies-for-frames rule (AGENTS.md, ESP32 README, code comments)

Firmware pipeline (backend)

  • Content-addressed firmware download URLs with no-store responses
  • Stale firmware cache invalidates on source changes
  • Reliable OTA acknowledgement; the state partition survives re-flashing

Frontend (USB / flasher)

  • USB serial render lifecycle events with Pi event parity; post-deploy USB preview retries until the first render exists
  • USB commands fall back to HTTP when the port is stale; boards that re-enumerate among identical devices require explicit reselection
  • Flasher keeps progress visible after the inline-controls move; reliable post-flash reboot and reconnect

Test plan

  • pytest app/api/tests/test_embedded_firmware.py app/api/tests/test_embedded_device.py — 61 passed
  • nim c -r src/frameos/tests/test_embedded_image_url.nim and test_interpreter_errors.nim — all green
  • pnpm --dir frontend run build — typecheck + build pass

🤖 Generated with Claude Code

Split out of #257. Device runtime, firmware pipeline, and embedded
frontend workflows:

- Streaming decode of multi-MB PNGs and chunked HTTP bodies, so
  downloads are no longer size-limited by fragmentation; images too
  large for the device paint a download-failure frame instead of
  'No image provided'
- Memory-aware scene node cache (frame-sized images are not pinned),
  OOM-aborted renders that leak the heap beyond recovery trigger a
  restart; render errors paint into the live canvas
- Serialized scenes.json writers, reliable OTA acknowledgement,
  post-flash reboot/reconnect, and the state partition survives
  re-flashing
- Content-addressed firmware download URLs with no-store responses;
  stale firmware cache invalidates on source changes
- USB serial render lifecycle events with Pi event parity; frontend
  USB commands fall back to HTTP when the port is stale; post-deploy
  USB preview retries until the first render exists; identical-board
  reconnects require explicit reselection
- Document the no-image-proxies-for-frames rule

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mariusandra
mariusandra merged commit 2424784 into main Jul 15, 2026
35 checks passed
@mariusandra
mariusandra deleted the esp32-embedded-hardening branch July 15, 2026 07:10
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.

1 participant