From 179d760fc784ce66330803d6e1235f9dc3f0df58 Mon Sep 17 00:00:00 2001 From: Ari Sulistiono Date: Tue, 3 Nov 2026 18:42:03 +0700 Subject: [PATCH] docs(firmware): define revision-aware ESP32-P4 zero-guess provisioning PRD and ARD Specify dual pre-v3/v3.x images, deterministic ROM/board/manifest selection, single-owner one-action Studio UX, bounded failure recovery, no surprise reset, post-boot identity proof and v1.3/v3.2 HIL gates. Bind AGENTS to architecture and release immutability. --- AGENTS.md | 20 +++ docs/ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md | 153 ++++++++++++++++++++ docs/PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md | 101 +++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 docs/ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md create mode 100644 docs/PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md diff --git a/AGENTS.md b/AGENTS.md index 8b6e1ecb7..55c0df12b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -312,6 +312,26 @@ Rules: If a patch cannot explain how it preserves this single-model contract, stop and redesign before coding. +## 21. Mandatory ESP32-P4 firmware provisioning contract (dual silicon families) + +Before changing `FirmwareManager`, `FirmwareWorker`, `SmartSessionController`, ESP32-P4 `sdkconfig`, manifest/package workflows, flasher version, ROM probe logic or setup UI, read: +- [`docs/PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md`](docs/PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md) — electrical engineer UX, release scope and acceptance; +- [`docs/ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md`](docs/ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md) — ownership, typed policy, revision evidence, safety state machine, CI/HIL gates; +- [`docs/SMV_STUDIO_DEVICE_SUPERVISOR_ARCHITECTURE.md`](docs/SMV_STUDIO_DEVICE_SUPERVISOR_ARCHITECTURE.md) — existing single-owner serial/session lifecycle. + +**Non-negotiable:** +1. **Two incompatible silicon families, two immutable image outputs**: pre-v3 and v3.x; separate generated sdkconfig/build dirs; inspect bootloader + app image revision headers and packaged manifest. Never turn pre-v3 build into a generic v3.x image by broadening a GUI boolean, and never modify an already published stable M3.H.3 tag/asset. +2. **The existing supervisor owns all firmware writes.** One `SmartSessionController` authority, `DeviceIoWorker` serial owner, `FirmwareManager` policy, `FirmwareWorker` process. No new flashing process owner, second QSerialPort, concurrent updater, hidden QML state machine or duplicated revision parser. +3. **ROM-revision proof + qualified board profile + one exact image + integrity and provenance + exclusive COM handoff + explicit operator intent must ALL precede writes.** No guessing from COM port, firmware log, marketing model, silent timeout, or partial probe. Never `--force`, `erase-all`, alter eFuse/security, auto-flash on connect or overwrite an autonomously running board. +4. **Running output is protected.** Before any reset/flash, require operator authorization for interruption and authoritative STOPPED proof of SV and PTP (and M4 group where applicable). Unknown board/operating state is not proof of safety; fail closed and guide recovery instead of auto-reset. Firmware installation never auto-STARTs SV/PTP or silently restores an editor draft. +5. **Bound the entire attempt, not just each QProcess.** Typed stages, monotonic hard deadlines, cancelled/stale session suppression, one terminal state and controlled retry; never an endless spinner. If a merged-image write is interrupted, mark outcome uncertain and offer manual/assisted ROM recovery; do not claim atomic rollback. +6. **Success requires the same board to BOOT the exact expected build**, with fresh semantic `IDENTIFY` / boot and capability proof; flasher exit 0 or 100% progress is insufficient. Unknown chip/board revision, incomplete package, mismatched ID or misleading UI state are errors, never READY. +7. **Electrical-engineer interface:** a compact status and one contextual action ('Set up board' / 'Update firmware'), no raw COM/bootloader/hash jargon unless in expandable Details. Do not add heavy/noisy cards or fake percentages. Same offline behavior on Windows and Linux. +8. **Evidence before stable:** CI covers v1/v3 catalog, wrong-revision rejection, concurrency, unplug/re-enumeration, boot mismatch and packaging. Physical v1.3+v3.2 HIL must verify boot/recovery/EMAC SV/PTP and preserved autonomy before v3.x stable claims. Check the bundled Rust `espflash` independently; the vendor `esptool` advisory does not automatically validate it. +9. **CI economy and change isolation:** reuse existing firmware/Studio workflows and native tests; request targeted revision lanes with separate caches, not an always-on duplicated matrix. Do not collide with in-flight M4 multi-SV or LAN autonomy work. + +**Execution sequencing:** design docs are a contract, **not evidence of implemented or tested compatibility**. Never report v3.2 as supported until an exact packaged image/Studio flow plus physical board passes the documented gates. + ## Final rule Think like the engineer responsible for a protocol stack and embedded device under sustained field load for years, not like a prototype generator trying to make one packet or screenshot pass. diff --git a/docs/ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md b/docs/ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md new file mode 100644 index 000000000..8e5f0b501 --- /dev/null +++ b/docs/ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md @@ -0,0 +1,153 @@ +# ARD — Fail-closed Revision-aware ESP32-P4 Firmware Provisioning + +**Status:** Architecture accepted for implementation; NOT implemented or hardware accepted. **Date:** 2026-11-03. **Scope:** Studio + ESP32-P4 firmware packaging, Windows/Linux. +**Product contract:** [PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md](PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md). **Agent invariants:** [AGENTS.md](../AGENTS.md). +**Release invariant:** immutable official stable `processbus-sim-m3h3-20261025` and existing M4 workstreams; no timing/PHY patch as an incidental part of provisioning. + +## A. Audited repository baseline (2026-11-03, main `071dae5`) + +| Existing owner | Verified code/contract | Extension strategy | +| --- | --- | --- | +| Firmware build | `embedded/esp32p4_smv_injector/sdkconfig.defaults` sets `CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y`; bench v1.3 | Keep known-good pre-v3 profile; add isolated v3.x profile, never mutate one shared generated sdkconfig | +| CI | `.github/workflows/esp32p4-smv-injector.yml`, `espressif/idf:v5.5.4`, checks pre-v3, merges raw image at flash offset 0 | Targeted two-profile variant within existing pipeline, immutable per-profile outputs and image/header checks | +| Manifest | `arstack.studio.firmware.v1`, single `chipRevisionPolicy=pre-v3`, source SHA/build ID, SHA-256 | Explicitly versioned v2 multi-image catalog; retain strict v1 read compatibility for old stable pre-v3 only | +| GUI supervisor | `SmartSessionController.cpp` owns firmware stage, one serial owner, release generation, reconnect, failure | Extend existing authority; no QML-owned alternative installer | +| Device session | `DeviceController`/`DeviceIoWorker` typed `DeviceIdentity` and boot identity, serial release | Preserve current semantic-first non-disruptive detection | +| Flasher | `FirmwareManager.cpp` uses asynchronous `FirmwareWorker` with external `espflash` `board-info` / `write-bin` / reset | Verify flasher revision v3.2 support *on hardware* before selecting/upgrading; exact pinned tool; same worker/CLI boundary | +| Revision guard | `supportsEsp32P4Revision(major,minor)` requires `major < 3` and manifest equals `pre-v3` | Replace *policy* with deterministic catalog/revision proof; never widen guard without a matching verified firmware | +| Bundled tools | `arstack-studio-release.yml`, Linux AppImage use `espflash v4.5.0` | Do not assume advisory for Espressif Python `esptool` guarantees behavior of Rust `espflash` | +| Physical acceptance | M3.H.3 has real v1.x SV/PTP evidence; v3.2 untested | Independent v3.2 hardware smoke and wire/PTP capture are mandatory for stable claim | + +The current `FirmwareManager` has per-operation limits (15 s launch, 30 s ROM probe, 180 s write, 20 s reset) and bounded reconnect attempts. Preserve these useful safeguards; add a transaction-level hard deadline and proof of catalog/device identity. Existing Studio currently auto-STOPs SV when the user begins an update: introduce explicit acknowledgment when an active SV *or PTP* experiment would be interrupted. Never reset a RUNNING autonomous publisher through passive discovery. + +### Hardware constraints backed by vendor evidence + +- ESP32-P4 pre-v3 and v3.x require separate binaries because of incompatible ROM/ABI assumptions. Do not force a v1.x bootloader on v3.x. `CONFIG_ESP32P4_SELECTS_REV_LESS_V3=n` is required for v3.x; set `CONFIG_ESP32P4_REV_MIN_300=y` with the IDF-supported profile and inspect computed min/max image headers. For pre-v3, retain the previously accepted selector and inspect actual built revision bounds. +- Espressif requires appropriate tool support for v3.2 flash power-on. `espflash v4.5.0` release notes include ECO6/ECO7 flash power-on changes, but compatibility with *the pinned bundled executable, board, OS and exact flash flow* is a test gate, not an assumption. +- Espressif v3.2 WDT advisory: evaluate ESP-IDF release/v5.5 v5.5.5+ (or suitable maintained patch level) in the new v3.x lane, particularly if external 32 kHz crystal is configured. Toolchain upgrades must be independently proven on legacy lane; do not casually rebuild or rewrite official M3.H.3. +- Silicon identity != PCB wiring identity. A true v3.2 chip does not prove Waveshare board pinout, PHY/reset circuitry, flash capacity or power suitability. Catalog must carry a qualified board profile; apply conservative supported-board evidence, not a generic "ESP32-P4" whitelist. +- `esptool` rejects invalid revision headers at bootloader offset unless forced. Studio's runtime checks are an additional protection; never use `--force` to bypass incompatible chip or security checks. + +## B. One authoritative flow / ownership + +`SmartSessionController` remains the **sole state and authorization owner** (operator intent, STOP authorization, session generation, USB candidate binding, deadlines, terminal result). `DeviceIoWorker` remains the **sole QSerialPort owner**; `FirmwareWorker` remains the **sole external flasher process owner** with exclusive port handoff. `FirmwareManager` owns package validation, ROM results, catalog selection and install proof. Introduce at most one small **pure, no-thread/no-I/O firmware catalog selector** shared between Studio tests and production; do not fork `FirmwareManager` or add redundant state/pollers. + +Proposed typed boundaries: + + FirmwareImage { + profileId; family; minRevision; maxQualifiedRevision; + supportedBoardProfile; image; flashOffset; length; sha256; + idfVersion; flasherContract; buildId; sourceCommit; capabilities; + bootloaderHeaderBounds; applicationHeaderBounds; + } + FirmwareCatalog { schema; releaseChannel; images[]; provenance; } + RomIdentity { chip; major; minor; romChipIdOrMac?; observedUsbFingerprint; } + QualifiedSelection { exactImage; romIdentity; supportProof; catalogHash; operationGeneration; } + FirmwareAttempt { attemptId; sessionGeneration; portLease; stage; deadline; selectedImage; terminalStatus; } + +The object names are design types, not demands for exact class names. There must be a single immutable `QualifiedSelection` captured at end of preflight. Every later step (write, reset, postflight) checks current attempt/generation/lease against it. Cache manifest hash and image digest per immutable packaged file; invalidate on package path/content/mtime/size change and verify at the write boundary to avoid TOCTOU. Do not trust a user-replaced writable catalog by its checksum alone. + +### Manifest v2, backward compatibility, and packaging + +Version `arstack.studio.firmware.v2` describes an array of *two disjoint profiles*, not one mutable 'current' .bin. Example conceptual inventory: + +| Profile | Qualified silicon | IDF profile | Binary | +| --- | --- | --- | --- | +| `esp32p4-pre-v3` | explicitly qualified existing v1.x (including v1.3) | `SELECTS_REV_LESS_V3=y` | `arstack-esp32p4-prev3.bin` | +| `esp32p4-v3x` | separately qualified v3.2; other minor v3.x only after validation | `SELECTS_REV_LESS_V3=n` + `REV_MIN_300=y` | `arstack-esp32p4-v3x.bin` | + +No overlap in **qualified selection**; max hardware revisions may be tighter than Espressif's theoretical `REV_MAX_FULL`. Reject missing/duplicate filenames, path traversal, malformed hashes, wrong target, unsupported/unknown schema, invalid lengths/offsets, duplicate overlapping selectors, release mix-ups, missing tool contract, or missing image-header evidence. A v1 manifest is recognized only with its legacy pre-v3 semantics; never "upgrade" its policy implicitly to support v3.x. + +Generate each firmware in **a separate SDKCONFIG + build/output directory**, with exact source SHA and locked toolchain. Do not let pre-existing `sdkconfig` silently override profile defaults; verify actual generated `sdkconfig` and both app+bootloader `esp_image_header_t` min/max revision fields, chip ID, partition/offset layout, merged binary SHA and per-image provenance before packaging. Include `firmware-manifest.json` and both binary hashes in Windows/Linux bundles; packaged self-check ensures exactly two valid images and correct versioned catalog. No runtime compilation, no network dependency. Explicit stable vs preview channel in catalog; do not silently select unaccepted v3.x stable. + +Trust policy: packaged, immutable release asset + SHA-256 currently validates local integrity, **not cryptographic origin by itself**. For remote catalogs/update services in the future, require an authenticated signed manifest and pinned verification key. No network auto-update in this milestone; fail closed on modified/unrecognized local bundle. + +## C. Exact device provisioning state machine + + PASSIVE_DISCOVERY -- app IDENTIFY verified --> READY / OFFER_UPDATE + | + +-- no response --> UNIDENTIFIED (never infer blank firmware) + | + +-- user SET UP / UPDATE authorization + | + v + PREFLIGHT / QUIESCE (explicit permission if SV/PTP running) + | + v + RELEASE_SERIAL -- portReleased(generation) --> ROM_PROBE + | + v + REVISION_AND_BOARD_PROOF --> SELECT_EXACT_IMAGE --> VALIDATE + | + v + WRITE_IN_PROGRESS --> WRITE_REPORTED_COMPLETE + | + v + RESET --> USB_REACQUIRE --> POSTBOOT_IDENTITY_PROOF --> READY + | + any failed gate --> TERMINAL_ERROR / GUIDED_RECOVERY + +**Entry rule:** Desktop startup and serial reconnect perform only bounded application `IDENTIFY`; never invoke `board-info` if that requires a reset as a side effect. Unknown application identity is not permission to take over a potentially autonomous RUNNING board. ROM probing requires a fresh operator action for the selected candidate. Do not automatically flash because USB is present. + +**QUIESCE rule:** If SV/PTP is RUNNING, stop only after explicit confirmation of test interruption, then obtain authoritative STOPPED evidence for **all relevant producers**. If current board state cannot be proven (unknown firmware / disconnected management), present a recovery notice requiring operator confirmation the board is disconnected from any live process bus; no blind assumption. Existing M4 `MULTISV` roster, SCD/board state, and STOP authority must not be overwritten through fallback V1 profile. + +**Port-binding rule:** Accept `portReleased(generation)` before ROM, bind attempt to selected device/USB fingerprint and session, and never use COM3/COM4 text alone as an identity. On re-enumeration use semantic eFuse-derived `device_id` where known, plus ROM identity, USB serial/location evidence as available. If ROM ID cannot be mapped directly to `device_id`, do not invent equality; compare only proven independent attributes and refuse ambiguous same-bus replacement. Multiple candidates => explicit selection. No second watcher or serial owner. + +**ROM rule:** Use tested pinned flasher to obtain structured chip+revision when available. If only textual `board-info` exists, isolate a strict, bounded parser for the known pinned-version output with positive/negative fixture tests; do not guess revision from a failed command, partial log, or misleading error text. Preflight board profile and security constraints independently. + +**Selection rule:** `matches` must return exactly one qualified image by verified revision, approved board profile, release channel, and protocol; if not, block. A CHIP family mismatch, unknown v4.x future revision, unknown minor outside qualification, or mismatched IDF image header must be rejected before first write. + +**Write rule:** One process, one port, one selected immutable image, no `--force`, `erase-all`, eFuse changes, loose fallback command, or background second attempt. Mark stage `WRITE_IN_PROGRESS` before launching process; treat interruption after first byte as **uncertain flash content**. Do not claim automatic rollback/atomicity for raw merged images. Cancellation before write is harmless; after write begins display guarded state and allow failure/recovery rather than claiming a safe instant cancel. Never automatically retry a possibly partially written image. + +**Proof rule:** Tool exit 0 != product success. Reset, wait for bounded USB events (COM number may change), run verified semantic `IDENTIFY` on the *same qualified target* and require chip/board binding evidence + exact expected `buildId`, `protocolVersion`, target and mandatory capabilities, fresh `bootId`. Do not report READY if firmware booted but wrong build, the USB device changed, or a stale identity was cached. No automatic START or implicit scenario deployment after update. + +**Stage failure rule:** First terminal failure wins, later stale callbacks ignored by generation. A single diagnostic record contains stage, machine error code, revision/profile, expected/observed identifiers and limited bounded logs (no secrets, no automatic upload). When failed, release the flasher/port, stop all associated timers, and offer Retry/Recover based on observed state; no infinite reconnect. Abort on power/USB loss, port ownership failure, unknown board profile, security/download-mode restrictions, or integrity mismatch. + +## D. Bounded timing and resource budget + +Existing timeouts are baselines, not license to make indefinite progress: flasher launch 15 s, ROM probe 30 s, write 180 s, reset 20 s. Proposed post-reset USB+identity deadline 45 s, serial handoff bounded by existing watchdog, **whole authorized transaction ≤300 s** from start to terminal outcome, measured with monotonic elapsed time. Stage deadlines and absolute deadline cannot be extended by progress output or repeated USB events. Retry is a new explicit attempt, not background looping. At most one controlled re-enumeration sequence with bounded attempts and a cap; operator retry never inherits an old successful probe. + +UI thread must stay responsive; reuse existing `FirmwareWorker` asynchronous QProcess and bounded log ring. Pure catalog selection occurs once per immutable package/device identity; no repeated JSON/hash parsing on every QML frame, no new polling at 4 kHz, no new real-time firmware task or EMAC/PTP dependency. A result is immutable per attempt. UI reports aggregate state, details panel lazy/optional. + +## E. Failure matrix (mandatory negative tests) + +- v1.3 selects v3.x / v3.2 selects legacy -> reject pre-write. +- ROM reply malformed/empty/partial; chip != ESP32-P4; unknown v4.x; unqualified minor; ambiguous supported-board identity -> reject. +- Corrupt image, manifest tampering, duplicate/overlapping selector, duplicate filename, path traversal, missing binary/flasher, image header vs manifest disagreement -> reject before release/write. +- A preinstalled v1 manifest and M3.H.3 asset remain readable for historical pre-v3 only, never advertised v3-capable. +- User tries update while SV or PTP RUNNING; STOP rejected, timeout, unknown running state -> do not enter flash. +- USB disappears during port release, ROM probe, before write, mid-write, reset or postboot; stale `sessionGeneration`, old-boot `IDENTIFY`, two boards swap COM numbers -> no cross-device flash and no false success. +- Two concurrent update clicks; late QProcess callback; busy COM/access denied; flasher missing/AV delayed; flasher output truncated; progress moves backwards; flasher hangs after reporting 100% -> one bounded terminal result. +- `write-bin` returns success but firmware crashes, bootloops, wrong build/capabilities/target, USB returns different physical board -> not Ready. +- Unknown secure-download/flash-encryption state -> fail closed with support diagnosis, never `--force` or unsafe workaround. +- Repeated optional update, failed attempt followed by explicit recovery, already-current firmware -> no stale state or accidental board reset. +- Legacy M3.H.3 running autonomy + M4 3-MU draft/roster/reconnect and priority STOP remain unaffected. + +Use existing `arstack_session_harness`, `--check-firmware-contract` / Qt packaging checks, firmware CI and Linux/Windows installer lifecycle tests. Add deterministic pure catalog/ROM-parser fixtures in the current test targets instead of separate standalone background services/jobs. + +## F. CI, hardware gates, release protocol + +**CI-efficient execution:** One scoped source commit/PR checkpoint; existing `esp32p4-smv-injector.yml` builds both profiles only when firmware/packaging gate is requested. Existing Windows Native Preview + Qt/packaging and Linux AppImage reuse resulting immutable per-profile artifact. Do not add a global every-push matrix or parallel redundant firmware rebuild. Keep exact-source check, checked-in policy, generated config, image header, merged image, catalog and SHA bound together. Cache only compiler objects separated by profile/toolchain, never reused sdkconfig or firmware image across revisions. + +**HIL-A v1.3:** pre-v3 first boot/update/recovery, USB mapping, SV+PTP, standalone autonomy, repeatable STOP and no regression to original measured M3.H.3 wire profile. **HIL-B v3.2:** Waveshare ESP32-P4-ETH-M physical ROM probe using shipped Windows/Linux tool, flash, fresh boot, Ethernet PHY, canonical 4I+4V 4000 SV fps, no missing/reordered/duplicate counters, PTP Layer-2 frames and truthful `smpSynch`, cold boot / reset / reconnect, interrupted-flash recovery. Record serial ROM identity, exact firmware+flasher+IDF version, sha, board model, capture and error traces. CI green is not HIL PASS. + +**Release gating:** v3.x engineering preview only after CI artifacts + at least boot/reconnect/flasher HIL-B; stable promotion only after both hardware acceptance lanes and honest packet timing evidence. Mark support by **qualified board model + silicon revision**. Never overwrite immutable M3.H.3 tag/assets. Other active M4 PRs and independent LAN autonomy PR must be audited for overlap, not rewritten in this milestone. + +## G. Implementation order (one coherent milestone, avoid patch stacking) + +1. Baseline current `main` / active M4 PRs / existing boot and installer fixtures; freeze v1 stable. +2. Implement pure v2 catalog/selection + revision/parser/image-header tests, with v1 strict compatibility. +3. Compile independent pre-v3 and v3.x firmware lanes in isolated generated-config/output locations; prove header/manifest and pinned flasher CLI + board support. +4. Extend existing `FirmwareManager` and `SmartSessionController` transaction for one-authority guarded selection, RUNNING/unknown-state safety, deadlines and reset/postboot proof. +5. Wire compact UX with no extra screens and one primary operator action; details remain optional. Add full negative session regressions and packaged-offline tests. +6. Physically test v1.3 and v3.2; release separate v3.x preview; promote only with evidence. + +### Primary vendor and security references + +- https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-reference/system/chip_revision.html +- https://documentation.espressif.com/en/PCN202600801_ESP32-P4_Chip_Revision_v3.2_Upgrade_Chip_Revision_v1.3_Demand_Collection_and_EOL_Plan_Description.html +- https://documentation.espressif.com/AR2026-004_Compatibility_Advisory_for_ESP32-P4_Chip_Revision_v3.2_EN.html +- https://github.com/waveshareteam/ESP32-P4-Platform/blob/main/docs/ESP32P4_REVISION_CONFIG.md +- https://github.com/esp-rs/espflash/releases/tag/v4.5.0 +- https://docs.espressif.com/projects/esptool/en/latest/esp32p4/esptool/basic-commands.html +- https://www.ncsc.gov.uk/collection/device-security-principles-for-manufacturers/provide-updates-securely diff --git a/docs/PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md b/docs/PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md new file mode 100644 index 000000000..b1ecf2c7d --- /dev/null +++ b/docs/PRD_REVISION_AWARE_ESP32P4_FIRMWARE.md @@ -0,0 +1,101 @@ +# PRD — Revision-aware ESP32-P4 Firmware Setup in ARStack Studio + +**Status:** Approved product direction; implementation NOT complete. **Date:** 2026-11-03. **Priority:** P1 public hardware compatibility blocker. **Owner:** ARStack Studio / ESP32-P4 Process Bus. +**Companion architecture:** [ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md](ARD_REVISION_AWARE_ESP32P4_FIRMWARE.md). **Rules:** [AGENTS.md](../AGENTS.md). + +## 1. Problem and outcome + +A public user reports that a newly purchased Waveshare ESP32-P4-ETH-M (silicon v3.2) cannot boot the firmware bundled with M3.H.3. The currently shipped firmware was compiled for pre-v3 silicon, while Studio also intentionally refuses chip revisions >= v3.0. An electrical engineer should not need ESP-IDF, Python, command lines, firmware file selection, revision knowledge, or bootloader expertise to operate ARStack. + +**Target experience:** Connect a supported board, open Studio, select a single contextual action (Set up board or Update firmware), and let Studio safely identify, select, install, restart, and verify the *correct* signed/trusted packaged firmware. Standard use is offline and self-contained. Never start flashing solely because a serial device appears. + +**Value promise:** No guessing and no wrong-revision flash. A success message means the intended firmware has actually booted and identified itself; not merely that bytes were sent. + +## 2. User experience contract + +**Primary persona:** protection / substation automation / commissioning engineer who is comfortable with USB and Ethernet, but not software development. + +| Observed condition | Main UI | Operator action | +| --- | --- | --- | +| No usable board | 'Connect your ESP32-P4 board' | Connect USB; automatic non-disruptive discovery | +| Verified ARStack board, exact supported build | 'Board ready' | None; continue engineering | +| Verified board, supported update available | 'Firmware update available' + **Update firmware** | One click; preflight below | +| Fresh/unsupported-app board on an explicitly chosen device | **Set up board** | One click; guided recovery/ROM probe | +| Device is publishing SV or emitting PTP | 'Board is in use' | Explicit operator confirmation of interruption and safe STOP proof before flashing | +| Multiple candidate boards/ambiguous USB identity | 'Choose the board to set up' | Choose one physical board; never guess by COM number | +| Unsupported silicon, unknown PCB, unreadable revision | 'This board is not supported yet' | No write; Show details for technical reason | +| Recovery/download mode required | 'Put the board in download mode' | Short illustration/text for BOOT/RESET and **Try again** | +| Setup complete | 'Board ready' | Return to the prior engineering screen; no automatic SV/PTP START | + +**Noise budget:** One compact status line, one primary action, optional expandable 'Details' / 'Copy diagnostics'. No prominent revision numbers, tool names, hashes, COM ports, PTP internals, raw errors, or many persistent steps during the normal path. In Details, provide board model evidence, silicon revision, selected firmware version/build, exact error code, stage, bounded timestamps, and support-ready report. Show percentage only when real flasher progress is available and monotonic. Otherwise use a neutral 'Installing firmware…' state, not an invented 0–100%. + +**Single-action does NOT mean silent destructive action.** The click explicitly authorizes flashing one identified board after preflight; running SV/PTP needs an additional clear confirmation that tests will stop. Startup, reconnect, and detection alone may never reset, erase, flash, stop, or reconfigure a running board. + +## 3. P0 must-have requirements + +- **R01 — Revision-aware offline bundle.** One Studio distribution includes independent *pre-v3* and *v3.x* ESP32-P4 firmware builds with separate exact-build manifests; no developer toolchain required on end-user PCs. Initial v3.2 release remains a labeled preview until physical acceptance. Preserve M3.H.3 official release/tag/assets unchanged. +- **R02 — Authoritative silicon probe.** Upon authorized setup, read ESP32-P4 chip revision from the ROM/flasher, not from COM number, GUI guess, board marketing name, or any application log. Recognize supported major/minor revisions and reject unknown/contradictory evidence. +- **R03 — Deterministic selection.** Exactly one firmware compatible with chip, qualified board/PHY profile, revision range, release channel, and protocol is selected. Zero or multiple matches => fail closed. Firmware pre-v3 can never be written to v3.x and vice versa. +- **R04 — Package integrity & provenance.** Verify manifest schema, expected target/revision/profile, bundle file inventory, image length, SHA-256, exact source/build identity and embedded bootloader/application image revision compatibility *before any write*. SHA-256 alone is not authenticity: distributions must be release-provenanced; future remote distribution requires signature verification with a pinned trust anchor. +- **R05 — One port owner.** Reuse SmartSessionController -> DeviceController/DeviceIoWorker serial release acknowledgement -> FirmwareManager/FirmwareWorker. Exactly one firmware tool/process and one active device operation; no parallel COM consumers or cloned updaters. +- **R06 — Non-disruptive startup.** Prefer a bounded ARStack application `IDENTIFY`. Silence/timeout means unidentified, NOT 'empty flash'. ROM probe/reset only on user intent; do not auto-stop autonomous SV/PTP, and do not let firmware recovery bypass M4 board/roster authority. +- **R07 — Bounded operation.** Every stage has a deadline and one terminal outcome; an absolute elapsed-time deadline prevents an endless spinner even if partial output/events keep arriving. No unbounded retries, polling, or callback accumulation. Terminal errors retain one relevant Retry action. +- **R08 — Truthful verification.** Flash tool exit 0 is only 'write reported complete'. After reset, re-enumerate safely, require semantic ARStack `IDENTIFY` with exact expected firmware build/protocol/capabilities and device binding before showing Ready. Mismatch or no boot => 'Setup not verified'. +- **R09 — Recovery.** USB unplug / timeout / crash during write enters explicit 'Needs recovery' outcome. No blind second flash, erase-all, `--force`, unsafe eFuse change, or claim of automatic rollback from a merged raw image. Operator-guided ROM recovery must remain possible. +- **R10 — Existing-product parity.** V1 4I+4V/4000 fps, PTP, autonomy, fail-closed STOP and M4 safety gates behave as before; a firmware refresh never implies START or silently deploys cached drafts. +- **R11 — Cross-platform identical policy.** Windows installer/portable and Linux AppImage carry the same revision selection/catalog semantics and truly compatible pinned flashing executables. No runtime network download or user-managed Python/ESP-IDF. +- **R12 — Honest compatibility.** Silicon revision compatibility does not prove board/PHY wiring compatibility. Only explicitly qualified board hardware profiles may be offered automatic setup; unknown boards require an explicit supported-model assessment, never an inferred 'all ESP32-P4 work' claim. + +## 4. Exceptional paths and example UI copy + +| Error class | Compact message | Primary next action | +| --- | --- | --- | +| USB absent / port busy | 'Board connection lost' | Reconnect / Try again | +| Cannot establish ROM identity | 'Could not identify this board' | Download-mode help + Try again | +| Unsupported silicon/PCB | 'This board is not supported yet' | View supported boards | +| Missing/ambiguous/corrupt package | 'Firmware package could not be verified' | Reinstall Studio / Details | +| Still transmitting | 'Stop the running test before updating' | Stop and continue (explicit) | +| Writing interrupted | 'Firmware setup was interrupted' | Recover board | +| Reconnect but unexpected build | 'Firmware setup could not be verified' | Try recovery | +| Correct verified build | 'Board ready' | Continue | + +Action wording is illustrative; compact 9–12px normal typography, no big banners or heavy cards. Errors are friendly at surface, deterministic typed codes in Details; never claim success on a stale session or earlier boot. + +## 5. Acceptance matrix (no shortcuts) + +| ID | Required evidence | Acceptance | +| --- | --- | --- | +| U01 | Connected v1.3 board with current firmware | Ready without reset/ROM probe/flash | +| U02 | Fresh supported v1.3 board | Legacy image selected and boots; no v3 image write | +| U03 | Fresh Waveshare v3.2 board | v3.x image selected, boots, exact-build postflight | +| U04 | Forced test with opposing images | Every wrong revision rejected before first write | +| U05 | Unknown revision or unsupported PCB | No flash and actionable support message | +| U06 | Corrupt image/manifest, missing binary, duplicate match | No flash; precise typed failure | +| U07 | Multiple USB devices and COM reassignment | No cross-device flash / wrong-device verification | +| U08 | Running autonomous SV or active PTP | No silent STOP, reset, or firmware operation | +| U09 | Unplug during each stage; failure while writing | Bounded error; safe guided recovery, no false Ready | +| U10 | Flasher exits 0, firmware does not boot or has wrong build | Not successful; evidence retained | +| U11 | Windows and Linux packaged offline install | Same exact firmware catalog, verified flasher, no SDK dependency | +| U12 | Reinstall/upgrade legacy Studio | Old M3.H.3 unchanged; no legacy package contract regression | +| U13 | One-hour idle / 100 repeated connect-disconnect simulations | Bounded memory/handles; no duplicate workers, phantom dialogs or permanent busy | +| U14 | Physical SV/PTP acceptance on v3.2 | 4I+4V canonical 4kfps, counters/quality, Ethernet/PTP frames and timing independently captured; failures reported honestly | + +CI can verify U01–U13 in host simulations and build contracts as applicable, but U02/U03/U08/U09/U14 require actual representative boards. v3.2 **preview** may ship with an explicit unverified hardware gate; **stable** cannot be claimed until HIL evidence is captured. Do not imply PTP UTC/GNSS traceability. + +## 6. Release phases and priorities + +- **P1A (highest impact):** ARD/PRD/AGENTS and compatibility disclosure; baseline exact stable untouched. +- **P1B:** independent binary build profiles with fail-closed manifest and revision/header CI; pinned flasher v3.2 suitability proven. +- **P1C:** single-owner Studio catalog selection, guided one-action installer, bounded recovery and strict postflight proof. +- **P1D:** physical v1.3 + v3.2 lab acceptance, public v3.x engineering preview, promotion only after evidence. + +**Out of scope:** universal third-party ESP32-P4 boards, cloud OTA, unattended update, automatic cross-machine device migration, promises of power-fail atomicity for raw merged flashing, or bypass of secure-download/security restrictions. + +## 7. Canonical external evidence + +- Espressif chip revision compatibility: https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-reference/system/chip_revision.html +- Espressif PCN v3.2 (separate binary / `ESP32P4_SELECTS_REV_LESS_V3=n`): https://documentation.espressif.com/en/PCN202600801_ESP32-P4_Chip_Revision_v3.2_Upgrade_Chip_Revision_v1.3_Demand_Collection_and_EOL_Plan_Description.html +- Espressif AR2026-004 flasher + v3.2 watchdog advisory: https://documentation.espressif.com/AR2026-004_Compatibility_Advisory_for_ESP32-P4_Chip_Revision_v3.2_EN.html +- Waveshare qualified build profiles: https://github.com/waveshareteam/ESP32-P4-Platform/blob/main/docs/ESP32P4_REVISION_CONFIG.md +- Espressif esptool incompatible-image rejection: https://docs.espressif.com/projects/esptool/en/latest/esp32p4/esptool/basic-commands.html +- NCSC firmware update authenticity guidance: https://www.ncsc.gov.uk/collection/device-security-principles-for-manufacturers/provide-updates-securely