Hot-swap with pdb
The Picodroid Debug Bridge (pdb) lets you push a new app to a running device over USB CDC without reflashing the firmware. The firmware exposes a USB CDC serial port (e.g. /dev/cu.usbmodem102 on macOS, /dev/ttyACM0 on Linux) that pdb talks to — no extra wiring required beyond the USB cable.
Quick access via script
./scripts/pdb.sh devices./scripts/pdb.sh -s /dev/cu.usbmodem102 ping./scripts/pdb.sh -s /dev/cu.usbmodem102 install build/apks/blinky.papk./scripts/pdb.sh -s /dev/cu.usbmodem102 sysmon./scripts/pdb.sh -s /dev/cu.usbmodem102 input tap 120 80./scripts/sim.sh --app foo | ./scripts/pdb.sh logcat --stdin --tag FooThe subcommands are devices, ping, install, sysmon, input
(tap/swipe/keyevent injection), and logcat (tag/level log filtering) — see
the pdb command reference for every flag.
Install the host tool globally (optional)
cargo install --path tools/pdbPush an app
# Build the app first./scripts/build-apk.sh --app blinky
# Find the serial portpdb devices
# Push the PAPKpdb -s /dev/cu.usbmodem102 install build/apks/blinky.papkThe device stops the running JVM (including any sleeping child threads), writes the new PAPK to flash, and restarts execution — typically in under a second.
Compatibility checks
Before flashing, pdb install runs two compatibility gates so a bad install never reboots the device:
- Host pre-flight — parses the PAPK manifest for
framework-map-version, compares it to the firmware’s version learned from PING, and exits with a clear error if they don’t match. - Device-side check — after stopping the JVM but before erasing flash, the device peeks the install header and refuses with
STATUS_INCOMPATon mismatch. (During the flash writes themselves the JVM stays blocked on core 0 and core 1 is parked by theflashparktask.)
Mismatches mean your PAPK was built against a different release than the firmware currently running. Rebuild the APK, or reflash a matching firmware. See Class-name shrinker → Diagnosing version mismatch.
Verify connectivity
pdb -s /dev/cu.usbmodem102 pingSystem monitor
Query heap usage, task states, stack high-water marks, and per-task CPU usage:
pdb -s /dev/cu.usbmodem102 sysmonCPU % is computed from the delta between consecutive queries. The first query reports CPU % as N/A; run it again after a few seconds to see actual per-task CPU usage.
Inspect a PAPK file
cargo run -p papk-info -- build/apks/blinky.papkPrints the manifest, class list, bytecode size of each class, and (if present) the bundled-asset section.