mirror of
https://github.com/ruvnet/RuView
synced 2026-08-10 20:31:42 +00:00
feat(firmware): mirror weight-blob parser into ruv_temporal (#513)
Closes the format contract on the firmware side. Source-only — Phase 5
toolchain blocker still prevents actually compiling, but when it
unblocks this is one less thing to write under time pressure.
- src/weights.rs — no_std mirror of v2/.../weights.rs. Same magic
('RVNE'), same version 1, same CRC32-IEEE polynomial (matches the C
side in temporal_task.c). Bit-for-bit lockstep with the host: a
blob produced by host WeightBlob::serialize() parses here as a
WeightBlobView byte-for-byte.
Borrowed-slice parse design: the firmware loader receives weights
via mmap'd EMBED_FILES or NVS read into a heap buffer. The parser
takes &[u8] with no copy — view fields point into the caller's
buffer. Caller is responsible for keeping the buffer alive for the
view's lifetime.
Loader errors map to esp_err_t-style codes via
weight_load_err_to_esp() so the C ABI can surface specific failure
modes (ESP_ERR_INVALID_ARG for magic/version/size, ESP_ERR_INVALID_CRC
for corruption, ESP_ERR_INVALID_SIZE for shape validation failures).
- src/lib.rs — ruv_temporal_init now optionally validates a non-NULL
weights blob. NULL pointer is still allowed during the Phase 4/5
bring-up window (kernel forward isn't actually consuming weights
yet), but when caller passes a real blob we parse + sanity-check
declared dims against runtime arguments. Catches deploy bugs at
init() rather than at first classify() — the firmware Tmr Svc work
in v0.6.4 taught us that classify-time crashes are the worst kind.
- README.md — Phase 6 marked done (verified by 8MB firmware build with
feature off in commit 7994af822). Added module map table covering
lib.rs / window.rs / weights.rs / ruv_temporal.h / shim.c.
What's deliberately NOT in this commit:
- Cross-compile validation. Same toolchain blocker as before.
- Kernel-side wiring of weights into the forward pass. That's
Phase 6+ of the firmware roadmap — once the kernel is wired,
weights become a required arg, not an optional one.
- Tests on the firmware side. They'd need build-std working to run;
16/16 host tests cover the format end-to-end via the lockstep
polynomial.
Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -9,10 +9,20 @@ C ABI declared in `include/ruv_temporal.h`.
|
||||
|
||||
| Phase | Scope | State |
|
||||
|-------|-------|-------|
|
||||
| 4 — Scaffold | Cargo.toml, src/{lib.rs,window.rs}, include/ruv_temporal.h, CMakeLists.txt, .cargo/config.toml | **Done.** Source compiles host-side syntax check; not yet cross-compiled to xtensa. |
|
||||
| 4 — Scaffold | Cargo.toml, src/{lib.rs,window.rs,weights.rs}, include/ruv_temporal.h, CMakeLists.txt, .cargo/config.toml | **Done.** |
|
||||
| 5 — Cross-compile | `cargo +esp build --release --target xtensa-esp32s3-none-elf` produces `libruv_temporal.a`. | **Blocked** — see below. |
|
||||
| 6 — Wire from edge_processing.c | FreeRTOS task on Core 1, queue from adaptive_controller fast loop, push() in fast tick, classify() at 1 Hz, emit `0xC5110007` packet. | Not started. |
|
||||
| 7 — COM8 validation | Flash 8MB build with `CONFIG_CSI_TEMPORAL_HEAD_ENABLED=y`, soak ≥5 min, check no Tmr Svc / task_wdt overflow. | Not started. |
|
||||
| 6 — Wire from edge_processing.c | FreeRTOS task on Core 1, queue from adaptive_controller fast loop, push() in fast tick, classify() at 1 Hz, emit `0xC5110007` packet. | **Done** in `main/temporal_task.c` (no-op shim path verified by 8MB firmware build with feature off). |
|
||||
| 7 — COM8 validation | Flash 8MB build with `CONFIG_CSI_TEMPORAL_HEAD_ENABLED=y`, soak ≥5 min, check no Tmr Svc / task_wdt overflow. | Pending board reattach. |
|
||||
|
||||
## Module map
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/lib.rs` | C ABI: `ruv_temporal_init / push / classify / destroy / kernel_self_test` |
|
||||
| `src/window.rs` | `FrameRing` rolling buffer used by `ruv_temporal_push` |
|
||||
| `src/weights.rs` | Loader-side mirror of host `wifi_densepose_temporal::weights`. Parses the `.rvne` blob format (magic `RVNE`, version 1, FP32/FP16, CRC32-IEEE). Bit-exact with the host crate; a blob produced by the host's `WeightBlob::serialize()` parses here byte-for-byte. |
|
||||
| `include/ruv_temporal.h` | Public C header consumed by `main/temporal_task.c` |
|
||||
| `shim.c` | Empty C shim for `idf_component_register` |
|
||||
|
||||
## Phase 5 blocker — esp toolchain rust-src bug
|
||||
|
||||
|
||||
Reference in New Issue
Block a user