This is a Java virtual machine for the Raspberry Pi Pico, this project is based on the CLDC virtual machine and more specifically on the phoneME project from Sun/Oracle. The phoneME is a very old project that currently is not maintained anymore. However I was able to find a github repo that I used as a reference. This JVM is targeted to small embedded devices with limited resources so don't expected a full blown Java experience on Raspberry Pi Pico.
The original phoneME project used a Makefile based build system, I converted the build system to CMake so I can use more modern tools and integration with modern CI/CD workflows. There are currently two main targets : Linux (used mainly for debugging) and Pico.
Currently the JVM support CLDC 1.1 specification which is a limited subset of the Java J2SE specification and language.
Download the release package from the Releases page of this repository, extract the package. The package contains the following content :
├── bin
├── doc
├── lib
└── pjvm-X.Y.Z.uf2
The bin
directory contains tools and scripts required to post process class and jar files to be able to run them on the Raspberry Pi Pico.
The doc
directory contains the javadoc for the device specific (e.g. GPIO) classes.
The lib
directory contains the run-time class libraries (classes.jar
)
The pjvm-X.Y.Z.uf2
(where X.Y.Z is the version of the firmware) is the Java Virtual Machine UF2 file, this file needs to be flashed to the Raspberry Pi Pico using picotool. The virtual machine already contains the run time classes so these are not required to be flashed separately.
The examples
directory in this repository contains some examples you can run with an Ant build.xml
file. To build the examples and the following Hello World application you will need to setup the environment variable JAVA_PICO_HOME
to point to the extracted package location.
For example if you extracted the package to /opt/pjvm-X.Y.Z
you will need to setup the variable with the following command :
export JAVA_PICO_HOME=/opt/pjvm-X.Y.Z
You will also need JDK 8 to build application, currently the latest versions of Java are not supported.
To run a Java application on the Raspberry Pi Pico you will need to flash the Java virtual machine itself and than flash the Java application at the address 0x10100000
.
Lets say we have a simple hello world application :
class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
NOTE : The name of the class Main
is currently fixed as the first class that is loaded by the VM.
Compile the class :
javac -source 1.4 -target 1.4 -d main.dir -bootclasspath $JAVA_PICO_HOME/lib/classes.jar Main.java
Make sure to setup you environment correctly so that JAVA_PICO_HOME
points to the right place (see here)
Preverify the classes
Before running the compiled classes on the Raspberry Pi Pico we will need to Preverify them. Preverifying is the process of post processing the class files so they can be run more efficiently on the target system. Preverifying is done with the preverify
tool in the bin
directory of the package.
$JAVA_PICO_HOME/bin/preverify -d main.preverify -classpath $JAVA_PICO_HOME/lib/classes.jar main.dir
Package the application as a JAR file :
cd main.preverify
jar -cfM0 ../main.jar .
Wrap the JAR file
Now we need to wrap the JAR with a header so we can run it on the Pi Pico :
$JAVA_PICO_HOME/bin/wrapjar.sh main.jar main.jar.bin
The wrapjar.sh
script is located in the bin
directory of the package.
Flash the binary file and reboot
Now we can flash the application to address 0x10100000
using picotool
:
picotool load build/main.jar.bin --offset 10100000
Reboot your Pi Pico and you should see Hello, World!
on your terminal
This repository includes an example
directory with a complete Ant build.xml
for each example that runs all the above steps in a single command.
This project can be built on Ubuntu 22 as the build machine, please install the following packages :
sudo apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential gcc-multilib g++-multilib ninja-build
You will also need JDK 8 (Yes 8) for this, please install it and make sure it is your default Java installation.
After cloning the project cd into it and run the the usual CMake commands :
mkdir build
cd build
cmake -DPICO_SDK_PATH=/home/oren/projects/pico-sdk .. -G Ninja
cmake --build .
Make sure you set PICO_SDK_PATH
to point to your Pico SDK location.
If all goes well you should end up with a pjvm.uf2
file in your build
directory. This file can be flashed to the Pi Pico (helper scripts can be found in the tools
directory). The pjvm.uf2
file is the Java VM itself and includes the system classes already romized inside it. A Java application is loaded separately into the flash of the Pi Pico at a specific address.