Known issues & current limits
What doesn’t work (yet), as of v0.14.0. Items here are confirmed and tracked — not speculative.
Networking (Pico 2 W)
- Personal auth only. Open, WPA2-AES, and WPA3-SAE (
PICODROID_WIFI_AUTH) — no WPA2/WPA3-Enterprise. IPv4 only. - No TLS.
HttpURLConnectionspeaks plain HTTP; there is nohttps://support. - Socket throughput is chunked. Socket I/O crosses the native boundary in 256-byte chunks; large transfers work correctly but pay a per-chunk cost.
- The device closes HTTP connections with RST. After a complete response the FreeRTOS+TCP side resets rather than closing cleanly, so a client sees a transport error alongside a full, correct payload (
curlexits 56 withhttp_code200). Scripts probing a device HTTP server must judge success by the status code and body, not the client’s exit code. Simulator connections close normally. - Boot-time race. The network takes up to ~10 s after reset (WiFi join + DHCP); apps must poll
NetworkInfo.isConnected()before their first socket call — see WiFi & networking setup.
Concurrency
- Equal-priority threads do not round-robin. Every task that interprets Java runs at one FreeRTOS priority with time slicing off — that is what makes the shared heap safe without locks — so a thread yields only when it blocks. A compute-bound thread therefore starves its siblings until it calls
sleep,join,wait, or blocking I/O. A safepoint-yield fix is designed but ungated on performance; seedocs/quality-roadmap.md. Thread.setPriorityis advisory. The value is stored and reported back, never applied, for the same reason.volatileis ignored and the interpreter emits no memory barriers. Correct only while a single core interprets Java, which is the invariant every JVM-adjacent task is pinned to. As of 2026-08-31 it is enforced rather than remembered:platforms/rp/src/task_affinity.rsis the only way the RP family creates a task — it names the core and makes create+pin scheduler-atomic — and its source scan failsscripts/test.shfor any spawn that bypasses it. What remains isvolatileitself, which parses and is ignored — tracked indocs/quality-roadmap.md(THR-04 / X1 indocs/parity-audit.mdrecords the trace).java.util.concurrentis excluded ontestbench_rp2040. The board drops thepicodroid.concurrentpool,Future, atomic and latch classes to stay inside its flash budget, so an app using them fails to resolve there rather than failing at runtime.Thread,synchronizedandObject.wait/notifyare available on every board.- Spurious wakeups are possible.
Object.waitmay return without a matchingnotify, as the JLS allows — always wait in a loop over the condition.
Simulator ↔ hardware gaps
- The sim is single-core. The simulator runs the real FreeRTOS kernel, but on the single-core POSIX port — cross-core interactions (and cross-core races) only exist on hardware.
- Finished threads park instead of exiting. A sim thread whose
run()returns leaves its FreeRTOS task parked; an app churning through tens of thousands of short-lived threads will exhaust host threads. Long-running worker threads are unaffected. - Sim networking is the host stack.
picodroid.netin the simulator uses your machine’s network directly — connection timing, buffer limits, and error codes differ from the device’s FreeRTOS+TCP stack. - macOS is untested since the simulator moved onto the FreeRTOS scheduler. Linux (windowed and headless) is exercised continuously.
Platform
- RP2040 flash is nearly full. A
--releaseRP2040 image sits at ~98% of the 896 K program region (897,287 of 917,248 bytes), and a committed size ratchet gates any growth.scripts/build.shhandles this (it disables LTO on RP2040, which paradoxically shrinks the image); a rawcargo build --releasefor RP2040 can overflow FLASH at link time. - Stale-widget detection is sim-first. The generation-tagged widget handle table that catches use-after-delete runs in the 64-bit simulator; on 32-bit devices it is staged behind the default-off
handle-table-32feature pending a hardware soak. A stale-handle bug can therefore surface on hardware without reproducing in the sim. - BME688 gas resistance is constant on hardware. The gas sensor’s heater profile is never programmed, so gas/IAQ readings sit at a fixed value on the device (temperature, humidity, and pressure are fine). Affects the picoenvmon IAQ tile cosmetically.
Where these are tracked
Networking items carry NET-* IDs in docs/networking-followups-2026-08.md; broader quality items live in docs/quality-roadmap.md.