PicOS v0.2.0
Highlights
Signed firmware updates. OTA images must carry an ECDSA P-256 signature (picocalc_os.sig, published with every release) that verifies against the key built into the running firmware. sys.applyUpdate also needs an on-screen confirm that apps cannot pre-answer, and the boot flashes an image only with a one-shot token set after that confirm. Refused images are renamed update.bin.rejected and never retried.
TLS certificates are verified. HTTPS and tls:// connections now check the server's chain (built-in CA bundle), validity dates and host name, and wait for SNTP to set the clock. Randomness comes from a TRNG-seeded CTR_DRBG. setInsecure(true) (Lua) or PCTCP_TLS_INSECURE (native) opts one connection out, for self-signed dev servers.
App sandbox enforced in C. Permissions come from the launcher's record of the running app, not the writable APP_* globals. The sound, MOD, video and sha256File loaders are path-checked like picocalc.fs; picocalc.sysconfig needs the "sysconfig" requirement and sys.applyUpdate needs "system-update".
Apps clean up after themselves. Native apps get every handle they leak (files, images, players, connections, fonts, crypto contexts, menu items, zip handles) freed on exit. Lua file handles are real objects closed by __gc or <close>, and files an app leaves open are closed after it, so FatFS's 16-file limit no longer wears down until a reboot.
Stack and memory hardening. MSPLIM/PSPLIM stack guards on the RP2350; Lua and native apps share one guarded app stack; dev commands run on their own. The Lua heap packs small objects into slab pools instead of spending a whole 200-byte block on each, so apps with many small tables no longer run the heap out of memory. A dirty-exit marker, heap fragmentation figures in /system/error.log, min_psram_kb in app.json, and boot-loop protection (after three failed boots the device halts instead of looping).
New APIs (native API v5 → v8)
- Fonts (v6): 4 built-in and 8 loadable proportional
.pfnfonts (setFont,loadFont,textWidth, transparent text…);tools/mkfont.pybuilds them from BDF/TTF/PNG. - Video (v7): time-based seek and position, a progress OSD,
hasEnded. - ZIP read-in-place archive handles (v5), plus on-device
unzip/rmdev commands. - TLS (v8):
http->setInsecure,tcp->connectEx. - Display: clip rect and mode-7
drawPlane(v4), LCD hardware scrolling,fillHLine,fillTriangle, transparent-background text. - Input:
pollEvent()ordered key events,isKeyDown(k), button auto-repeat. picocalc.json, withgame.saverebuilt on it.- Store: catalog from picos.jeffory.dev, streaming downloads with mandatory SHA-256 (and signature, for firmware).
Fixes and performance
- Unified 44.1 kHz audio mixer: no more PWM whistle, and sound effects no longer cut the music.
- HTTP/TCP: a cross-core close protocol with one lock per pool, correct chunked/close-delimited bodies, timeouts that run with the link down, ARP requests retried.
- Configs are saved atomically; display primitives clip once (huge coordinates cost only the visible pixels); an adaptive Lua service hook.
Changes that can affect apps
- HTTPS to an untrusted or self-signed server now fails with
TLS: certificate not trusted …; a request made before the clock is set fails withclock not set(retry after a few seconds). picocalc.sysconfigisnilunless the app declares"sysconfig", andget("wifi_pass")returnsnil.- App ids must be 1-79 characters of
[A-Za-z0-9._-]and are folded to lower case (data lives in/data/<lower-case id>); an invalid id is refused at launch. game.saveslots moved to/data/<app_id>/saves/; a legacy/saves/<name>.jsonis copied into the slot on first read.- Lua
loadaccepts text only (bytecode is rejected);dofile/loadfileare gone. - Numeric arguments to display, audio, video, input and
sys.sleepround to nearest instead of truncating; volumes and colour components clamp. sys.qmiPsramAllocreturns a bounds-checked buffer handle, and Lua PIO PSRAM access starts at0x48000.- A held key repeats; it is never a new press edge.
Firmware
picocalc_os.uf2: drag onto the Pico (Pimoroni Pico Plus 2 W, RP2350) in BOOTSEL mode.picocalc_os.bin+.sha256+.sig: OTA through the updater or store.
This is the first release built with the release signing key. Devices on v0.1.0 can update through the updater or store as usual. A device running a local development build (which embeds the repository's test key) will refuse this image over OTA: flash the .uf2 once.