docs: reposition as the 86 Panel development environment

The repo's documentation framed it as a support repo for one product
(WardenOS). Since going public the real audience is anyone with a Luckfox
Pico 86 Panel: a maintained 6.18 kernel, an off-device development loop,
and a device simulator that exist nowhere else for this board. Reframe the
README and top-level docs board-first, with WardenOS documented as the
downstream consumer it is (ADR-0008).

Also an editorial pass over the whole doc set:
- every H1/H2 is now a short title, not a sentence (ADRs, qemu/, patches/,
  drivers/, architecture, NPU feasibility, config-lint, payload); workflow
  flowchart titles fixed at the source in tools/flowgen.py and regenerated
  with fresh bench numbers
- README Quick Start commands verified against the scripts; requirements
  corrected (curl, bare python, gcc >= 14) and the MC/DC gate added as a
  step (run green locally on gcc 14.2)
- dropped the 'needs python (not python3)' vendor dig: build-kernel.sh
  inherited the same requirement (filed #10 to remove it)
- glossed MC/DC and HPMCU on first use; marked the tests/uboot-ab
  reference as flare-edge; deduplicated the three-simulator list into the
  root README table
This commit is contained in:
BFE Engineering
2026-08-30 22:19:12 -06:00
parent 084df85450
commit c756622c96
27 changed files with 221 additions and 194 deletions
+15 -13
View File
@@ -1,10 +1,12 @@
# warden-sdk architecture
# Architecture
How the SDK makes WardenOS buildable, testable, and hardenable without a panel in
the loop. Grounded in a full survey of the current flare-edge firmware (the seam
inventory below is from that survey, not aspiration).
How the SDK makes the 86 Panel buildable, testable, and hardenable without a
board in the loop. The seam inventory below comes from a full survey of the
downstream WardenOS firmware — the SDK's first consumer — not aspiration; the
file paths in it point into that (private) codebase and serve as engineering
context.
## 1. The problem the seams solve
## 1. The Problem
The firmware touches RV1106 hardware through a *grab-bag* of mechanisms, each
tested (or not) differently. Today:
@@ -26,7 +28,7 @@ socket, misc dev, cmdline, hpmcu fw), and **fails-soft-because-the-path-is-absen
"relay 1 is ON" or "NPU at 80%", only "absent". The SDK's job is to turn all of
these into **one deliberate seam per block** with a real backend and a sim backend.
## 2. The seam taxonomy
## 2. Seam Taxonomy
Two seam kinds cover everything above:
@@ -47,7 +49,7 @@ backend is "a fake `improcess` that records the blits it was asked to do", swapp
behind the same `#if`, so the offload *dispatch* logic gets tested even though the
blit itself is modelled.
## 3. The simulator (`sim/`)
## 3. The Register Simulator
A host Rust library modelling the hardware the vendor SDK cannot, so driver and
supervisor logic runs in CI with no panel.
@@ -92,12 +94,12 @@ which is a **maintainer go-ahead item** (credential/remote creation). Until then
firmware-side seam and a local test double land in flare-edge, unified with `sim/`
once the dependency exists. No duplication of *logic* — only the tiny trait.
## 4. Driver hardening (the "port + harden to MC/DC" goal)
## 4. Driver Hardening
"100% MC/DC on 100% of drivers" is infeasible literally: ~97% of driver LOC is
vendor blobs (AIC8800 wifi = 88.5K lines). Tiered target:
- **Tier 1 — our own hardware code → real MC/DC.** Method: the proven `tests/uboot-ab`
- **Tier 1 — our own hardware code → real MC/DC.** Method: the proven flare-edge `tests/uboot-ab`
pattern — extract the unit behind a small injectable seam, mock its world, build
`-fcondition-coverage`, enforce with the shared `drivers/enforce-mcdc.sh` (gcc-14
`gcov --conditions`) in the CI `mcdc` job. **Done here now:** `relays.c` (40/40
@@ -116,7 +118,7 @@ Every seam gets a fault-injection mode (a wedged SDIO link, a stalled MCU
heartbeat, an RGA timeout, a GPIO write EIO) so recovery code is tested against
failure, not just the happy path.
## 5. Target-config checks (a class the sim cannot cover)
## 5. Target-Config Checks
The brick was a *memory-map* fault: the boot-loaded MCU's load address (`0x40000`)
is a reserved carve-out on Thunder-Boot boards but plain kernel RAM on ours. No
@@ -136,7 +138,7 @@ fails against a DT with no `rtos@40000` node and passes once the reservation is
added. **Next** target-config checks: partition-table-vs-image-size and
vermagic-vs-kernel.
## 6. Kernel forward-port (done — see ADR-0001)
## 6. Kernel Forward-Port
A self-built **Linux 6.18.46**, forward-ported directly from the vendor 5.10.160 tree
onto our Buildroot LTS/uClibc base — **not** the plan44/OpenWrt 6.6 fork this section
@@ -154,7 +156,7 @@ kernel move as one matched boot+oem image, never a partial reflash.
series honest against pristine 6.18.46; provenance is in `patches/README.md` and
`kernel/rv1106-enablement/`.
## 7. Device emulation (`qemu/`) — see ADR-0006
## 7. Device Emulation
The third simulator, deliberately not named "sim": a QEMU VM (`-M virt,highmem=off`,
one Cortex-A7, 256M — the RV1106G3's shape) that boots the real forward-ported
@@ -178,7 +180,7 @@ development* stays `lvglsim`; the VM is where processes, the kernel, and the
network meet. §5 still applies — no behavioural sim, this one included, catches
memory-map faults; and "boots under emulation" is never on-silicon evidence.
## 8. Order of work
## 8. Order of Work
1. **Simulator core**`membus`, `hpmcu`, the `cru` reset ladder, `modbus`, plus the
`rga`/`npu` models. **Done.**
+1 -1
View File
@@ -18,7 +18,7 @@ execute code on private infrastructure (ADR-0007).
| `prune-artifacts` | ubuntu-latest, dispatch-only | Deletes `kernel-rv1106` artifacts beyond the newest 3. |
| `badges` | ubuntu-latest | Renders loc/tests/coverage shields on push to `main` (`[skip ci]` + `paths-ignore` loop guard). |
## History: the self-hosted runner (retired)
## Runner History
`kernel-build` originally ran on a repo-scoped self-hosted runner (ADR-0004,
2026-08-25, verified end-to-end) because hosted minutes were metered on the
+1 -1
View File
@@ -1,4 +1,4 @@
# ADR 0001 — Kernel base: direct 5.10→6.18 forward-port
# ADR 0001 — Kernel Forward-Port
**Status:** Accepted (2026-08-25). Supersedes the README's original plan44/6.6 goal.
+1 -1
View File
@@ -1,4 +1,4 @@
# ADR 0002 — Tiered MC/DC coverage policy
# ADR 0002 — Tiered MC/DC
**Status:** Accepted (2026-08-25).
+1 -1
View File
@@ -1,4 +1,4 @@
# ADR 0003 — warden-sdk is a standalone repo
# ADR 0003 — Standalone Repo
**Status:** Accepted (2026-08-25). Repo-visibility half superseded by ADR-0007
(2026-08-30) — warden-sdk went public; the "private for now" consequence below
+1 -1
View File
@@ -1,4 +1,4 @@
# ADR 0004 — CI/CD runner: 3rd repo-scoped self-hosted runner on 0640
# ADR 0004 — Self-Hosted Runner
**Status:** Superseded in part by ADR-0007 (2026-08-30) — `kernel-build` moved
to GitHub-hosted runners for the public repo and the self-hosted registration
@@ -1,4 +1,4 @@
# ADR 0005 — Hardened drivers live in warden-sdk/drivers/
# ADR 0005 — Driver Source of Truth
**Status:** Accepted (2026-08-25).
+1 -1
View File
@@ -1,4 +1,4 @@
# ADR 0006 — QEMU device sim: generic `-M virt`, entered at the kernel
# ADR 0006 — QEMU Device Simulator
**Status:** Accepted (2026-08-29).
@@ -1,4 +1,4 @@
# ADR 0007 — Public repo: kernel-build moves to GitHub-hosted runners
# ADR 0007 — Hosted-Only CI
**Status:** Accepted (2026-08-30). Supersedes the runner half of ADR-0004.
@@ -0,0 +1,28 @@
# ADR 0008 — Panel Development Environment
**Status:** Accepted (2026-08-30).
## Context
warden-sdk was written as the SDK for WardenOS, and its documentation framed
it that way: a support repo for one product. Since going public (ADR-0007,
GPL-2.0-only), the actual audience is wider — anyone with a Luckfox Pico 86
Panel gets a maintained 6.18 kernel, an off-device development loop, and a
device simulator out of this repo, none of which exists elsewhere for this
board. The product-first framing undersold that and confused the entry point
for outside readers.
## Decision
Position warden-sdk as **a modern, open development environment for the
Luckfox Pico 86 Panel (RV1106)**. WardenOS is documented as the downstream
consumer it is, not the purpose. Documentation follows three rules: lead with
the board, not the product; keep private-repo references clearly marked as
context; keep titles short — a heading names a section, it does not summarize
it.
## Consequences
- README and top-level docs lead with the hardware and the developer loop
(build, simulate, test), with verified quick-start commands.
- WardenOS/flare-edge specifics stay where they are engineering truth (the
seam inventory, scenario payloads) but read as one consumer's usage.
- The honesty rule is unchanged: emulation results are never on-silicon
claims.
+17 -17
View File
@@ -1,4 +1,4 @@
# Can the RV1106 NPU be used for 3D graphics or other graphical tasks?
# NPU Graphics Feasibility
**Bottom line: no, not for 3D rendering — not "slower," but genuinely not how the
hardware works past the first pipeline stage. The RKNPU on RV1106 is a
@@ -24,9 +24,9 @@ or flagged as general knowledge / needing TRM confirmation.
---
## 1. What the RV1106 NPU actually is
## 1. What the NPU Is
### Identity and generation
### Identity and Generation
- It is the **RKNPU** — Rockchip's 4th-generation NPU IP, exposed to tooling as
the "RKNPU2" software generation (same toolchain family as RK3566/68/88), but
@@ -56,7 +56,7 @@ or flagged as general knowledge / needing TRM confirmation.
assigns **420MHz**. No datasheet states a default/rated frequency.
(`luckfox-pico-86-panel/npu.md:11-13`)
### Architecture: fixed-function command-stream engine, not a programmable core
### Architecture
This is the load-bearing fact for everything downstream. Reading the vendored
kernel driver source directly (`flare-edge/sdk/sysdrv/source/kernel/drivers/rknpu/`):
@@ -106,7 +106,7 @@ kernel driver source directly (`flare-edge/sdk/sysdrv/source/kernel/drivers/rknp
primitive operations the hardware's fixed-function units implement
underneath. It is not a route to arbitrary per-element or per-pixel code.
### Data types, memory, DDR sharing
### Data Types and Memory
- **INT8-only quantization tier** for RV1106/RV1103 (`quantize=8` mandatory at
conversion time) — inputs/outputs must be int8 and strictly 4-D.
@@ -129,7 +129,7 @@ kernel driver source directly (`flare-edge/sdk/sysdrv/source/kernel/drivers/rknp
the 128256MB shared-DDR budget is the practical ceiling well before compute
is. (`luckfox-pico-86-panel/npu.md:38`)
### Software stack — how it's actually driven
### Software Stack
1. **Kernel driver** (`rknpu.ko`, currently v0.9.2 on our shipped firmware) —
exposes `/dev/rknpu` (a DRM device or a misc device, selectable at build time
@@ -159,7 +159,7 @@ footgun on this board (no regulator wired) — never poll it.
---
## 2. 3D rendering feasibility, stage by stage
## 2. 3D Rendering, Stage by Stage
A conventional 3D pipeline: **vertex transform → primitive assembly →
rasterization → depth test → texture sampling → per-pixel shading →
@@ -175,7 +175,7 @@ framebuffer write.** Verdict per stage, given everything in §1:
| **Per-pixel shading** (arbitrary per-fragment program) | **No** | The NPU executes one fixed, precompiled graph over a whole tensor — it cannot run per-pixel conditional/arbitrary code. You could contrive a *specific* visual effect that literally is a small CNN (see §3), but that's not "shading" in the pipeline sense — it's a different, narrower thing wearing the name. |
| **Framebuffer write** (write final pixels to the display's scanout buffer) | **No** | The NPU has no display/scanout connection at all — no DRM plane, no VOP link. Its only output path is writing tensor data to a DDR buffer, which is not a display pixel format. Something else (CPU or RGA) has to dequantize (`int8 → float → pixel`) and repack it into an actual framebuffer format before it's visible — and even RGA doesn't consume NPU tensor layouts directly (see §4). |
### Verdict: full or hybrid 3D pipeline
### Verdict
**No full pipeline is possible on this hardware — five of six stages have no
mapping at all, not a slow one.** A "hybrid" design where only vertex transform
@@ -214,7 +214,7 @@ they are the wrong tool, full stop.
---
## 3. Other graphical tasks that might fit a CNN accelerator
## 3. CNN-Shaped Image Tasks
Setting 3D aside — a CNN accelerator's real strength is convolution, which
*does* map to some classic image-processing tasks. Evaluated against this
@@ -228,7 +228,7 @@ specific 0.51 TOPS-class, 128256MB-shared-DDR, no-camera product:
| **Segmentation-driven UI effects** | Yes, in principle | **Moot — no camera, no visual input of any kind to segment.** |
| **2D affine transforms** (rotate/scale/skew as matrix math) | Yes, technically a small matmul | **No — RGA already does this natively, in fixed-function hardware, cheaper.** RGA2-Enhance on this board already does scale (bicubic up / averaging down, to 16× either direction), rotate (90/180/270° on input windows), crop, and color/format conversion as dedicated blit-engine operations — no model compile, no INT8 quantization, no job-submit-and-IRQ-wait round trip, just a register-programmed blit. It is already wired into LVGL (the Monitor-page double-buffer-sync offload, verified 20%→8% CPU on real hardware) and proven in production. (`luckfox-pico-86-panel/rga.md`) |
### A concrete, on-record precedent: this was already considered and rejected once
### Prior Rejection
The product wiki records that the keyboard's touch-bias correction (snapping an
ambiguous tap to the nearest key) was **explicitly evaluated for NPU
@@ -241,7 +241,7 @@ problem has no business going through a tensor accelerator's compile-and-submit
pipeline. Nothing in this research changes that conclusion — if anything it
generalizes it.
### Realistic verdict for §3
### Realistic Verdict
None of the CNN-shaped graphical tasks clear the bar for this specific product.
Where a hardware assist genuinely helps (2D blit/scale/rotate/blend, classic
@@ -255,9 +255,9 @@ detection, touch-gesture-pattern classification) — not graphics of any kind.
---
## 4. The driver-porting reality
## 4. Driver Porting
### What porting `rknpu.ko` to 6.18 actually involves
### Porting Scope
- **This is a forward-port of Rockchip's out-of-tree vendor driver, not a
from-scratch write.** The driver already carries version-gated compatibility
@@ -299,7 +299,7 @@ detection, touch-gesture-pattern classification) — not graphics of any kind.
driver forward against a newer kernel ABI" — bounded, evidence-backed, but
real engineering, not a version-string bump. (`luckfox-pico-86-panel/rga.md:86`)
### Does "graphics" use need the full RKNN toolchain, or is there a more direct compute submit?
### Direct Submit Path
**It needs the full toolchain.** As established in §1, the raw
`DRM_IOCTL_RKNPU_SUBMIT` path exists at the kernel-ioctl level, but the
@@ -313,7 +313,7 @@ slower-to-iterate loop than driving RGA (which is a direct, synchronous
`im2d`-style C API call with no offline compile step at all) or writing plain
CPU code.
### RGA is the existing, already-adequate 2D accelerator
### RGA Comparison
Worth restating plainly since it's the thing the NPU would be compared against:
**RGA2-Enhance already does everything this panel's UI plausibly needs from 2D
@@ -332,7 +332,7 @@ silicon to work in, and it lines up with everything else in this document: RGA
---
## 5. Bottom-line recommendation
## 5. Recommendation
| | Worth prototyping? | Why |
|---|---|---|
@@ -343,7 +343,7 @@ silicon to work in, and it lines up with everything else in this document: RGA
| **Porting `rknpu.ko` to 6.18** | **Conditionally yes — but scope it for inference, not graphics** | Same bounded, evidence-backed effort class as the RGA port; keeps the door open for the platform wiki's actual identified NPU opportunity (a small non-visual classifier: audio, RS-485/sensor anomaly detection, touch-gesture patterns). Do not justify or scope the port around a graphics capability — it doesn't unlock one. |
| **A first NPU spike, if one is wanted for team familiarity** | **Only the already-identified real use case** | A tiny non-visual model (e.g. an RS-485 anomaly classifier) — not a graphics stunt. This is the same conclusion the platform wiki already reached independent of this research. |
### What would need to happen for this document to be wrong
### Falsifiers
Flagging explicitly, per the instruction to distinguish settled facts from
things needing verification:
+7 -7
View File
@@ -1,11 +1,11 @@
# Workflow flowcharts
# Workflow Flowcharts
Generated by `tools/flowgen.py` from the modelled decision paths.
Each is an outcome-first flowchart of a workflow the SDK tests, with its benchmark or MC/DC metric.
- [HPMCU watchdog: arm → beat → fire](hpmcu-watchdog.md)
- [Modbus RTU: read-holding-registers round trip](modbus-read-holding.md)
- [CRU reset ladder: cause + boot-mode survival](cru-reset-ladder.md)
- [RGA 2D offload dispatch](rga-offload.md)
- [Relay drive (Tier-1, 100% MC/DC)](relay-drive.md)
- [UI freshness contract (Tier-1, 100% MC/DC)](freshness-contract.md)
- [HPMCU Watchdog](hpmcu-watchdog.md)
- [Modbus RTU Round Trip](modbus-read-holding.md)
- [CRU Reset Ladder](cru-reset-ladder.md)
- [RGA Offload](rga-offload.md)
- [Relay Drive](relay-drive.md)
- [UI Freshness Contract](freshness-contract.md)
+2 -2
View File
@@ -1,8 +1,8 @@
# CRU reset ladder: cause + boot-mode survival
# CRU Reset Ladder
> **Outcome tested:** Reset cause is attributable and the boot-mode register survives a warm reset.
**Benchmark** (`cru_poll`): 23.0 ns/op
**Benchmark** (`cru_poll`): 21.4 ns/op
```mermaid
flowchart TD
+1 -1
View File
@@ -1,4 +1,4 @@
# UI freshness contract (Tier-1, 100% MC/DC)
# UI Freshness Contract
> **Outcome tested:** The UI never shows a stale number: it holds briefly, then marks unknown.
+1 -1
View File
@@ -1,4 +1,4 @@
# HPMCU watchdog: arm → beat → fire
# HPMCU Watchdog
> **Outcome tested:** A hung A7/flared ends in a counted reset, not a dark panel.
+2 -2
View File
@@ -1,8 +1,8 @@
# Modbus RTU: read-holding-registers round trip
# Modbus RTU Round Trip
> **Outcome tested:** A well-formed request yields the right registers; a bad one a defined fault.
**Benchmark** (`modbus_read_holding`): 88.0 ns/op
**Benchmark** (`modbus_read_holding`): 73.7 ns/op
```mermaid
flowchart TD
+1 -1
View File
@@ -1,4 +1,4 @@
# Relay drive (Tier-1, 100% MC/DC)
# Relay Drive
> **Outcome tested:** A relay is exported transparently and driven without disturbing a held contact.
+2 -2
View File
@@ -1,8 +1,8 @@
# RGA 2D offload dispatch
# RGA Offload
> **Outcome tested:** Blits go to the RGA when it succeeds, and fall back to the CPU when it doesn't.
**Benchmark** (`rga_improcess`): 7.2 ns/op
**Benchmark** (`rga_improcess`): 6.7 ns/op
```mermaid
flowchart TD