Build & flash (RP)
This page walks the Raspberry Pi Pico (RP2040 / RP2350) path.
Prerequisites
Rust toolchain
# RP2040 (Cortex-M0+)rustup target add thumbv6m-none-eabi
# RP2350 (Cortex-M33) — only needed if targeting Pico 2rustup target add thumbv8m.main-none-eabihfC cross-compiler (for FreeRTOS)
# macOSbrew install arm-none-eabi-gcc
# Ubuntu/Debiansudo apt install gcc-arm-none-eabiRust tools
cargo install flip-linkcargo install probe-rs-tools --locked # installs probe-rscargo install elf2uf2-rs # optional: needed for --uf2 flagLocal CI (pre-commit hook)
The pre-commit hook runs Java formatting check, cargo fmt, APK build, Clippy (RP2040, RP2350, and sim), firmware build, and tests before each commit.
Install the hook after cloning by symlinking so it stays in sync with scripts/pre-commit:
ln -s ../../scripts/pre-commit .git/hooks/pre-commitTo skip the hook in exceptional cases: git commit --no-verify.
Java Development Kit (JDK 11+)
App sources are compiled by the Gradle multi-project under the repo root. The ./gradlew wrapper ships in-tree, so no separate Gradle install is required — only a JDK. App code targets Java 1.8 (configured in build.gradle.kts), but JDK 11 or later is required because the Java formatter tool needs it.
Compilation is followed by verifyApiContract, which fails the build for any
java.* class or member pico-jvm does not implement (see the
compatibility matrix and
troubleshooting). scripts/build-apk.sh --board <name>
— passed automatically by build.sh, flash.sh and sim.sh — also rejects
classes that board excludes from its framework.
# macOSbrew install openjdkbrew link openjdk --force
# Ubuntu/Debiansudo apt install default-jdkVerify: javac --version
Java formatting (google-java-format)
Java source files must follow Google Java Style. No separate installation needed — the formatter JAR is downloaded automatically on first use.
# Reformat all Java files in-place./scripts/format_java.sh format
# Check formatting without modifying files (runs in pre-commit hook and CI)./scripts/format_java.sh checkBuilding and Flashing
# Clone with submodules (third_party/FreeRTOS-Kernel, vendor/lvgl,# vendor/freertos-plus-tcp, vendor/cyw43-driver)git clone --recurse-submodules https://github.com/shivrajora/picodroid-rscd picodroid-rs
# Build firmware with the default example (helloworld) for testbench_rp2350./scripts/build.sh
# Flash to Pico and view RTT log output./scripts/flash.shChoosing a board
Both scripts accept a --board flag. The default is testbench_rp2350.
| Flag | MCU | Target |
|---|---|---|
--board testbench_rp2040 | RP2040 | Raspberry Pi Pico |
--board testbench_rp2350 | RP2350 | Raspberry Pi Pico 2 |
--board testbench_rp2350w | RP2350 | Raspberry Pi Pico 2 W (adds WiFi via cyw43 + FreeRTOS+TCP; WiFi credentials are baked in at build time — see WiFi & networking setup) |
--board pico_enviro_mon | RP2350 | Pico Enviro Mon (1.14” 240x135 ST7789, no touch) |
--board pico_enviro_mon_w | RP2350 | Pico Enviro Mon on a Pico 2 W — same wiring plus WiFi (credentials baked in at build time; see WiFi & networking setup) |
# Build / flash for Pico (RP2040)./scripts/build.sh --board testbench_rp2040./scripts/flash.sh --board testbench_rp2040For day-to-day work, the per-board cargo aliases (cargo b-testbench-rp2040, cargo r-testbench-rp2350w, etc.) skip the script and call cargo directly — see Cargo aliases.
Choosing an example
Pass --app <name> to select which example to build or flash:
./scripts/build.sh --app blinky # default board./scripts/build.sh --app uart --board testbench_rp2040 # RP2040./scripts/build.sh --app helloworld --release
./scripts/flash.sh --app blinky./scripts/flash.sh --app uart --board testbench_rp2040./scripts/flash.sh --app helloworld --releaseThe --app flag selects which example to build. build.sh compiles the Java sources into a .papk file and embeds it into the firmware — no Cargo feature flags are involved.
Shrinking class names
Both build.sh and flash.sh accept --shrink, which applies the active release class-name shrink map (off by default):
./scripts/build.sh --app helloworld --release --shrink./scripts/flash.sh --app helloworld --release --shrinkFirmware and PAPK must be built with the same setting, or the install is rejected with a version mismatch — see Class-name shrinker.
Generating a UF2 file
Pass --uf2 to build.sh to convert the ELF to a UF2 file after building. This is useful for flashing without a debug probe — just drag-and-drop the .uf2 onto the Pico’s USB Mass Storage drive.
./scripts/build.sh --app blinky --uf2./scripts/build.sh --app blinky --board testbench_rp2350 --release --uf2The UF2 is written alongside the ELF (e.g. target/thumbv6m-none-eabi/debug/picodroid.uf2). Requires elf2uf2-rs (cargo install elf2uf2-rs).
Next steps
- Host simulator — run apps on your dev machine without hardware.
- Hot-swap with pdb — push a new app over USB CDC without reflashing.
- Your first app — scaffold a Java app and wire its lifecycle.