Index · 01

picodroid

A stripped-down, FreeRTOS-based Android for the Raspberry Pi Pico. Java apps run on a JVM interpreter written in Rust, directly on bare-metal hardware.

Status
Active
Commits
900+
Started
2026-03
Licence
GPL-3.0
[Photo of a Pico running a picodroid app]

Why

Android's app model is a good way to structure small interactive programs: activities with a lifecycle, a back stack, views, preferences, background threads. It also assumes a phone. picodroid asks how much of that model survives on a four-dollar microcontroller with a few hundred kilobytes of RAM.

The answer so far is: enough to write real apps in Java against an Android-compatible API, install them over USB without reflashing the firmware, and run them on both cores under FreeRTOS.

What runs today

  • ActivitiesFull lifecycle with a back stack
  • UILVGL-backed widgets: Toast, AlertDialog, Keyboard, gestures, property animations
  • StorageFiles on LittleFS, SharedPreferences
  • NetworkingTCP, UDP and HttpURLConnection over WiFi on the Pico 2 W
  • SensorsSensorManager with a BME688 environmental sensor
  • ThreadsThread.start() creates FreeRTOS tasks; concurrency utilities
  • MemoryMark-sweep garbage collector, runs every 256 allocations
  • ToolingHot-swap installs and a device monitor over USB, plus a desktop simulator with mouse-as-touch

Build log

Shrinking the firmware

Dead .class debug attributes stripped from the device image, and the shrunk java/** classes moved under a short b/ namespace that the JVM un-shrinks on load. Measured together: 969,452 bytes down to 959,911.

First light: LED blink from a no_std binary

Where it started. Boots through cortex-m-rt into main, takes the peripherals, sets GPIO25 as a push-pull output and toggles it on a busy-wait delay. No RTOS, no JVM, no display.

let mut led = pins.gpio25.into_push_pull_output();

loop {
    led.set_high().ok();
    cortex_m::asm::delay(12_000_000);
    led.set_low().ok();
    cortex_m::asm::delay(12_000_000);
}
Next

[Next milestone]

[What you are working on next. Each milestone gets its own entry above.]