|
RGB Sunglasses Animation Extension API fw-v3.8.1-1-geacf2f0
rgbx ABI + C++ wrapper for sandboxed .llext animations
|
This directory is the registry of community rgbx animation extensions — extensions developed in standalone repos (from rgbx-extension-template) and shipped on this repo's firmware releases. The worked example is rgbx-demo-wave; the design rationale is in fw/docs/standalone-extension-repos.md.
./build.sh, test by dragging the .wasm onto https://rgb-sunglasses.autom8ed.com/sim/).registry.json:name — must equal your CMake project() name and match ^[a-z0-9_]{1,25}$ (it becomes the .llext filename on the device)repo — your public GitHub reporev — the full 40-hex commit SHA to publish (never a branch/tag; changing it later means another reviewed PR)description, author, license (OSI-approved; your repo must carry the license file)community-extensions.yml) validates the registry and builds your pinned commit from source — both targets, pinned toolchains, all gates (undefined symbols vs the device's export table, section layout, heap fit, wasm import/export contract).Once merged, every fw-v* firmware release rebuilds your extension from its pinned rev against that release's SDK and attaches two release assets: <name>.llext (debug info stripped — the file that reaches devices) and <name>.llext.debug (the same partial link with its DWARF kept, for resolving a fault PC offset against exactly the object that shipped; see fw/docs/standalone-extension-repos.md). The companion app then installs the .llext onto devices automatically (it syncs every asset ending in .llext on the latest firmware release, so the .debug sidecar is ignored). A build failure at release time (e.g. after an ABI bump) drops your extension from that release — visibly, in the release workflow summary — without blocking the firmware; fix and PR a new rev to ride the next release.
Nothing in CI can catch this, so it is on you and on the reviewer.
If your extension calls sinf/cosf/tanf on a phase that accumulates every tick, wrap that accumulator. The device's libm is cheap only while |x| <= 201.06 and gets continuously more expensive above it, so an unwrapped accumulator makes an extension run at full speed for a minute or two and then degrade — invisibly to a short test, because the accumulator resets every time the extension is activated.
This is not hypothetical: the first two extensions in this registry shipped with it. Issue #304 — plasma's per-tick cost climbed 3.4 ms -> 25 ms over five minutes and missed essentially every frame.
Full explanation, the wrap idiom, the fmodf sign trap, and how to soak-test it: "Bound your phase accumulators" in fw/extensions/README.md.