Embedded Java Hello World On Raspberry Pi Zero
I am going to show you how to build, deploy, and run a simple “Hello World!” application on a Raspberry Pi Zero, without an operating system, in Java. In the embedded world, this means making the green ACT LED blink.
Prerequisites1
Make sure you have the following hardware/software for this guide:
- a Mac host (Windows setup here)
- a Raspberry Pi Zero
- USB to TTL Serial Cable like this one from Adafruit
- Java 1.8 or better
- ARM cross compiler
- Gradle build tool
- optional - a development editor like VSCode or Atom; old-school vi works too :-)
Check Your Environment
From terminal, let’s check to make sure all needed software is working. It you do not see something like the responses below, make sure you have the prerequisites installed.
First, let’s check Java.
$ java --version
openjdk 11.0.2 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
Next, check the ARM cross compiler:
$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Finally, check for Gradle:
$ gradle --version
------------------------------------------------------------
Gradle 5.1.1
------------------------------------------------------------
Build time: 2019-01-10 23:05:02 UTC
Revision: 3c9abb645fb83932c44e8610642393ad62116807
Kotlin DSL: 1.1.1
Kotlin: 1.3.11
Groovy: 2.5.4
Ant: Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM: 11.0.2 (Oracle Corporation 11.0.2+9)
OS: Mac OS X 10.14.6 x86_64
Step By Step Guide
Step 1: Create a Gradle Wrapper
In terminal, create a directory for your project. Start by creating a gradle wrapper for your project. This enables a build to be run for this project without a local install gradle install, and for a known good gradle version.
$ mkdir helloworld
$ cd helloworld/
$ gradle wrapper --gradle-version 5.6.4
BUILD SUCCESSFUL in 3s
1 actionable task: 1 executed
Step 2: Create settings.gradle
In the root of your project directory, create a settings.gradle file. Add the following to this file.
sourceControl {
gitRepository("https://github.com/chuckb/raspbootin") {
producesModule("com.github.chuckb.raspbootin:raspbootcom")
producesModule("com.github.chuckb.raspbootin:raspbootin2")
}
}
These settings enable the building of a serial bootloader that will run on your host and the Raspberry Pi Zero.
Step 3: Create build.gradle
Also in the root of your project directory, create the build.gradle. Add the following to this file.
buildscript {
dependencies {
classpath 'com.github.chuckb:HaikuVMPlugin:master-SNAPSHOT'
}
repositories {
maven { url 'https://jitpack.io' }
}
}
apply plugin: 'com.github.chuckb.haikuvm'
haikuvm {
haikuVMConfig = "rpi"
port = "/dev/tty.SLAB_USBtoUART"
}
These settings reference my HaikuVMPlugin plugin, which automates building and deploying of embedded Java projects. The port
variable may need to be modified. We’ll get to that later.
Step 4: Create the application
Create a src/main/java directory off of the project root. Inside the java directory, create a Main.java file. Add the following to that file:
import haiku.vm.NativeCBody;
import haiku.vm.NativeCFunction;
@NativeCBody(cImpl ="volatile unsigned int* gpio = (unsigned int*)0x20200000UL;")
public class Main {
@NativeCFunction(cImpl = "gpio[arg1] = arg2;")
private static native void setGPIO(int offset, int value);
@NativeCFunction(cImpl = "return gpio[arg1];")
private static native int getGPIO(int offset);
public static final int GPIO_GPFSEL4 = 4; // GPIO Function Select 4
public static final int LED_GPFSEL = GPIO_GPFSEL4;
public static final int GPIO_GPSET1 = 8; // GPIO Pin Output Set 1
public static final int GPIO_GPCLR1 = 11; // GPIO Pin Output Clear 1
public static final int LED_GPFBIT = 21;
public static final int LED_GPSET = GPIO_GPSET1;
public static final int LED_GPCLR = GPIO_GPCLR1;
public static final int LED_GPIO_BIT = 15;
/**
* Main function entry point for app
*/
public static void main(String[] args) {
int tim;
/* Write 1 to the GPIO init nibble in the Function Select GPIO peripheral register to set
the GPIO pin for the ACT LED as an output */
setGPIO(LED_GPFSEL, (1 << LED_GPFBIT) | getGPIO(LED_GPFSEL)&0xFFFFFFFF);
while(true) {
// Delay
for(tim = 0; tim < 50000; tim++);
/* Set the LED GPIO pin low ( Turn OK LED on for original Pi, and off for plus models ) */
setGPIO(LED_GPCLR, (1 << LED_GPIO_BIT));
for(tim = 0; tim < 50000; tim++);
/* Set the LED GPIO pin high ( Turn OK LED off for original Pi, and on for plus models ) */
setGPIO(LED_GPSET, (1 << LED_GPIO_BIT));
}
}
}
I explain this application works in Dissecting Raspberry Pi Embedded Java Hello World. Suffice it to say, it blinks the green Pi ACT LED.
Step 5: Build And Deploy Raspberry Pi Zero Serial Bootloader Image
For this step, we will build the Raspberry Pi Zero binary image containing a serial bootloader, which will load the above app over a serial cable. This image will will be deployed to a micro SD card.
Go to the project root, and do this:
$ ./gradlew buildPiImage
You should see:
> Task :raspbootin:raspbootin2:make
rm -f *.o
rm -f kernel.img kernel.elf
rm -f kernel.list kernel.map
rm -f kernel
arm-none-eabi-as -I. -march=armv6 -mcpu=arm1176jzf-s -g start.s -o start.o
arm-none-eabi-gcc -DPLATFORM_RPI -I. -std=c99 -Wall -pedantic -g -O0 main.c -c -o main.o
arm-none-eabi-gcc -DPLATFORM_RPI -I. -std=c99 -Wall -pedantic -g -O0 uart.c -c -o uart.o
arm-none-eabi-ld --no-undefined start.o main.o uart.o -Map kernel.map -o kernel.elf -T kernel.ld
arm-none-eabi-objcopy kernel.elf -O binary kernel.img
> Task :raspbootin:raspbootcom:make
g++ -O0 -W -Wall -g -c raspbootcom.cc -o raspbootcom.o
g++ -o raspbootcom raspbootcom.o
> Task :buildPiImage
-> /Users/chuck_benedict/Projects/helloworld/build/firmware/pi/files/kernel.img
-> /Users/chuck_benedict/Projects/helloworld/build/firmware/pi/files/config.txt
-> /Users/chuck_benedict/Projects/helloworld/build/firmware/pi/files/bootcode.bin
-> /Users/chuck_benedict/Projects/helloworld/build/firmware/pi/files/fixup.dat
-> /Users/chuck_benedict/Projects/helloworld/build/firmware/pi/files/start.elf
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.6.4/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 5s
2 actionable tasks: 2 executed
If the gradle task ends with BUILD SUCCESSFUL
as above, change directory into build/firmware/pi
.
To deploy the bootable image to your SD card, first you need to determine which device Mac assigned to your card. Plug in your card and then do this:
$ diskutil list
You will see something like this:
/dev/disk0 (internal):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme 960.2 GB disk0
1: EFI EFI 209.7 MB disk0s1
2: Apple_APFS Container disk1 960.0 GB disk0s2
/dev/disk1 (synthesized):
#: TYPE NAME SIZE IDENTIFIER
0: APFS Container Scheme - +960.0 GB disk1
Physical Store disk0s2
1: APFS Volume Macintosh HD 492.5 GB disk1s1
2: APFS Volume Preboot 41.4 MB disk1s2
3: APFS Volume Recovery 507.4 MB disk1s3
4: APFS Volume VM 11.8 GB disk1s4
/dev/disk2 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: RPIBOOT *32.0 GB disk2
I have a 32GB card, and disk2 is marked external
, so I can be pretty sure, IN MY CASE, my card is /dev/disk2
. YMMV.
Warning: Don’t screw this up or the following command can nuke your system. You have been warned.
Warning: This action will erase and overwrite your micro SD card! If you have Raspbian installed, or more importantly, any non-recoverable data on the card, back it up first.
Now do the following, substituting diskx
for your device:
$ sudo umount /dev/diskx
$ sudo dd if=boot.img of=/dev/diskx bs=512
You should see:
67584+0 records in
67584+0 records out
34603008 bytes transferred in 17.837279 secs (1939926 bytes/sec)
Unplug your SD card and then plug it back in. Go to the Finder and look under Locations for RPIBOOT
. Click on it and you should see a listing like the following:
Now you can eject your card and plug it into the Pi.
Step 6: Determine USB Serial Cable Device Name
I mentioned in step 3 that the port
variable in the build.gradle
might need to be adjusted. I am using the Adafruit USB serial cable based on the CP2102 chip. Be sure to follow the driver install instructions. You don’t have to use this cable. Any USB to serial cable that deals in 3.3V TTL signals will work. Whatever the case, you will need to know the device name that Mac gave to the cable. Plug in your cable and do this:
$ ls /dev/tty* | grep -i usb
In my case, I got:
/dev/tty.SLAB_USBtoUART
Fill in whatever name you got for the port
variable.
Step 7: Plug In The Serial Cable Pins To The Raspberry Pi
I am assuming you have the Adafruit cable. Leave the red wire off for now. Hook the rest up as follows:
The bootloader uses UART0, so if you are using another cable, use this pinout as a guide.
Plug in the USB side to your workstation.
Step 8: Deploy The Application
Now for the anti-climactic fun. Go to the root project directory and type:
$ ./gradle deploy
You will see a lot of output. I have included it here in case you want to compare.
> Task :haikulink
Looking for 'HaikuVM.properties' in path: '/Users/chuck_benedict/Projects/helloworld';'/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/config'
Loaded from '/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/config/HaikuVM.properties'
$Version 1.4.3 $ $Id: HaikuVM.java 765 2017-04-30 10:32:24Z genom2 $
user .h/.c/.cpp files from /Users/chuck_benedict/Projects/helloworld into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility
Copy HaikuVM-VM into '/Users/chuck_benedict/Projects/helloworld/build'.
Because '/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src/HaikuAppMain.c' is newer than '/Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/HaikuAppMain.c'.
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/.settings
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/examples
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/examples/HaikuVM
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src/platforms
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src/platforms/pi
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src/aotVariants
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src/gcVariants
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src/lib
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src/lib/ldscripts
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/./haikuVM/src/utility
#################### closure start on haiku.bcm.lib.HaikuMicroKernel
included; haiku.bcm.lib.HaikuMicroKernel.main([Ljava/lang/String;)V
included: haiku.vm.MicroKernel.clinitHaikuMagic()V
included: haiku.vm.MicroKernel.panic(II)V
included: Main.main([Ljava/lang/String;)V
included: Main.getGPIO(I)I
included: Main.setGPIO(II)V
included: java.lang.Thread.currentThread()Ljava/lang/Thread;
virtual : stop()V
#### rescan because:
###### usage of (invokevirtual || invokeinterface) for message --> stop()V
###### usage of message --> Main.getGPIO(I)I
###### usage of message --> Main.main([Ljava/lang/String;)V
###### usage of message --> Main.setGPIO(II)V
###### usage of message --> haiku.vm.MicroKernel.clinitHaikuMagic()V
###### usage of message --> haiku.vm.MicroKernel.panic(II)V
###### usage of message --> java.lang.Thread.currentThread()Ljava/lang/Thread;
###### usage of new Class (1 bc) --> Main
###### usage of new Class (1 bc) --> java.lang.Thread
###### usage of new Class (2 bc) --> haiku.vm.MicroKernel
included: java.lang.NullPointerException.<init>(Ljava/lang/String;)V
included: java.lang.RuntimeException.<init>(Ljava/lang/String;)V
included: java.lang.Exception.<init>(Ljava/lang/String;)V
included: java.lang.Throwable.<init>(Ljava/lang/String;)V
included: java.lang.ArrayStoreException.<init>()V
included: java.lang.RuntimeException.<init>()V
included: java.lang.IndexOutOfBoundsException.<init>(Ljava/lang/String;)V
included: java.lang.StringBuilder.<init>()V
included: java.lang.Object.<init>()V
virtual : append(Ljava/lang/String;)Ljava/lang/StringBuilder;
virtual : append(I)Ljava/lang/StringBuilder;
virtual : toString()Ljava/lang/String;
included: java.lang.NoSuchMethodError.<init>(Ljava/lang/String;)V
included: java.lang.Error.<init>(Ljava/lang/String;)V
included: java.lang.StackOverflowError.<init>(Ljava/lang/String;)V
included: java.lang.OutOfMemoryError.<init>(Ljava/lang/String;)V
included: java.lang.ClassCastException.<init>(Ljava/lang/String;)V
included: java.lang.ArrayIndexOutOfBoundsException.<init>(I)V
included: java.lang.InternalError.<init>(Ljava/lang/String;)V
included: java.lang.VirtualMachineError.<init>(Ljava/lang/String;)V
included: java.lang.ArithmeticException.<init>(Ljava/lang/String;)V
included# java.lang.Object.toString()Ljava/lang/String;
included: java.lang.System.identityHashCode(Ljava/lang/Object;)I
included: java.lang.System.getDataAddress(Ljava/lang/Object;)I
included# java.lang.Thread.stop()V
virtual : setStateAndSwitch(I)I
included# java.lang.Thread.setStateAndSwitch(I)I
virtual : fillInStackTrace()Ljava/lang/Throwable;
included# java.lang.Throwable.toString()Ljava/lang/String;
included# java.lang.Throwable.fillInStackTrace()Ljava/lang/Throwable;
included# java.lang.String.toString()Ljava/lang/String;
#### rescan because:
###### usage of (invokevirtual || invokeinterface) for message --> append(I)Ljava/lang/StringBuilder;
###### usage of (invokevirtual || invokeinterface) for message --> append(Ljava/lang/String;)Ljava/lang/StringBuilder;
###### usage of (invokevirtual || invokeinterface) for message --> fillInStackTrace()Ljava/lang/Throwable;
###### usage of (invokevirtual || invokeinterface) for message --> setStateAndSwitch(I)I
###### usage of (invokevirtual || invokeinterface) for message --> toString()Ljava/lang/String;
###### usage of message --> java.lang.ArithmeticException.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.ArrayIndexOutOfBoundsException.<init>(I)V
###### usage of message --> java.lang.ArrayStoreException.<init>()V
###### usage of message --> java.lang.ClassCastException.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.Error.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.Exception.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.IndexOutOfBoundsException.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.InternalError.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.NoSuchMethodError.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.NullPointerException.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.Object.<init>()V
###### usage of message --> java.lang.OutOfMemoryError.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.RuntimeException.<init>()V
###### usage of message --> java.lang.RuntimeException.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.StackOverflowError.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.StringBuilder.<init>()V
###### usage of message --> java.lang.System.getDataAddress(Ljava/lang/Object;)I
###### usage of message --> java.lang.System.identityHashCode(Ljava/lang/Object;)I
###### usage of message --> java.lang.Throwable.<init>(Ljava/lang/String;)V
###### usage of message --> java.lang.VirtualMachineError.<init>(Ljava/lang/String;)V
###### usage of new Class (1 bc) --> java.lang.ArithmeticException
###### usage of new Class (1 bc) --> java.lang.ArrayIndexOutOfBoundsException
###### usage of new Class (1 bc) --> java.lang.ArrayStoreException
###### usage of new Class (1 bc) --> java.lang.ClassCastException
###### usage of new Class (1 bc) --> java.lang.Error
###### usage of new Class (1 bc) --> java.lang.Exception
###### usage of new Class (1 bc) --> java.lang.IndexOutOfBoundsException
###### usage of new Class (1 bc) --> java.lang.InternalError
###### usage of new Class (1 bc) --> java.lang.NoSuchMethodError
###### usage of new Class (1 bc) --> java.lang.NullPointerException
###### usage of new Class (1 bc) --> java.lang.OutOfMemoryError
###### usage of new Class (1 bc) --> java.lang.RuntimeException
###### usage of new Class (1 bc) --> java.lang.StackOverflowError
###### usage of new Class (1 bc) --> java.lang.StringBuilder
###### usage of new Class (1 bc) --> java.lang.System
###### usage of new Class (1 bc) --> java.lang.VirtualMachineError
included: java.lang.Exception.<init>()V
included: java.lang.Throwable.<init>()V
included# java.lang.StringBuilder.toString()Ljava/lang/String;
included: java.lang.String.<init>([C)V
included# java.lang.StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
included# java.lang.StringBuilder.append(I)Ljava/lang/StringBuilder;
included: java.lang.String.valueOf(I)Ljava/lang/String;
#### rescan because:
###### usage of message --> java.lang.Exception.<init>()V
###### usage of message --> java.lang.String.<init>([C)V
###### usage of message --> java.lang.String.valueOf(I)Ljava/lang/String;
###### usage of message --> java.lang.Throwable.<init>()V
virtual : append(C)Ljava/lang/StringBuilder;
included# java.lang.StringBuilder.append(C)Ljava/lang/StringBuilder;
included: java.lang.String.<init>(C)V
#### rescan because:
###### usage of (invokevirtual || invokeinterface) for message --> append(C)Ljava/lang/StringBuilder;
###### usage of message --> java.lang.String.<init>(C)V
#################### closure complete!
Effective configuration for 'rpi':
AOTVariant = HAIKU_AOTBytecodeAsJump
APP_BASE = /Users/chuck_benedict/Projects/helloworld/build
APP_NAME = Main
Align = 4
ArduinoCore = null
ArduinoDir = null
AsuroTiming = null
BOOTCLASSPATH = null
Baud = null
CC = null
CC_OPT = null
CFLAGS =
CLIBS =
CPUARCH = null
CXX = null
CXX_OPT = ${HAIKU_CC_OPT}
Char = HAIKU_CHAR_16
Clock = null
Config = rpi
Extends = root4c
Extension = .undefined Extension
GC = HAIKU_ConservativGC
GenerateFullVM = null
HAIKUVM4C = ./haikuVM
HOME = /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK
IncrementalGCSlice = HAIKU_MemorySize/5
InitialMainThreadStackSize = 500
InitialOtherThreadStackSize = 100
LDFLAGS =
LINKER = $(HAIKU_CXX)
Lower_MCU = null
MCU = null
MCU_LD = null
MemorySize = 30000
MicroKernel = haiku.bcm.lib.HaikuMicroKernel
MillisDividend = 128
MillisDivisor = 125
MillisPrescale = 64
Mode = HAIKU_32_32
Output = $(HAIKU_APP_NAME)$(HAIKU_EXTENSION)
PanicExceptions = NullPointerException | NoSuchMethodError | OutOfMemoryError | ClassCastException | InternalError | ArrayIndexOutOfBoundsException | StackOverflowError | ArithmeticException
PanicSupport = 1
Port = null
Programmer = null
Warning: unsupported value 'rpi' for property 'Target'!
Target = rpi
Threads = 0
TimerInterrupt = null
Upload = null
UserMain = null
VM_BASE = ../../HaikuVM
#################### closure start on java.lang.Thread
#################### closure complete!
#################### closure start on java.lang.String
#################### closure complete!
link > haiku.bcm.lib.HaikuMicroKernel.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/bootstrap/master-SNAPSHOT/b3079486a387e0207b93dd54d2d9fa5b6c18a003/bootstrap-master-SNAPSHOT.jar
const class_t haiku_bcm_lib_HaikuMicroKernel__class PROGMEM = {
& haiku_vm_MicroKernel__class,
SIZEOF_haiku_bcm_lib_HaikuMicroKernel,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.Throwable.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/haikuRT/master-SNAPSHOT/207b6d3a7213bb212e2886745d366b7f3d415f6c/haikuRT-master-SNAPSHOT.jar
const class_t java_lang_Throwable__class PROGMEM = {
& java_lang_Object__class,
SIZEOF_java_lang_Throwable,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.Object.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/haikuRT/master-SNAPSHOT/207b6d3a7213bb212e2886745d366b7f3d415f6c/haikuRT-master-SNAPSHOT.jar
const class_t java_lang_Object__class PROGMEM = {
NULL,
SIZEOF_java_lang_Object,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.StringBuilder.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/haikuRT/master-SNAPSHOT/207b6d3a7213bb212e2886745d366b7f3d415f6c/haikuRT-master-SNAPSHOT.jar
const class_t java_lang_StringBuilder__class PROGMEM = {
& java_lang_Object__class,
SIZEOF_java_lang_StringBuilder,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.String.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/haikuRT/master-SNAPSHOT/207b6d3a7213bb212e2886745d366b7f3d415f6c/haikuRT-master-SNAPSHOT.jar
const class_t java_lang_String__class PROGMEM = {
& java_lang_Object__class,
SIZEOF_java_lang_String,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.System.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/haikuRT/master-SNAPSHOT/207b6d3a7213bb212e2886745d366b7f3d415f6c/haikuRT-master-SNAPSHOT.jar
const class_t java_lang_System__class PROGMEM = {
& java_lang_Object__class,
SIZEOF_java_lang_System,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
PREPROCESSING haikuReleaseLock: java.lang.Thread.haikuReleaseLock(Ljava/lang/Object;)V
link > java.lang.Thread.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/haikuRT/master-SNAPSHOT/207b6d3a7213bb212e2886745d366b7f3d415f6c/haikuRT-master-SNAPSHOT.jar
const class_t java_lang_Thread__class PROGMEM = {
& java_lang_Object__class,
SIZEOF_java_lang_Thread,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > haiku.vm.MicroKernel.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/bootstrap/master-SNAPSHOT/b3079486a387e0207b93dd54d2d9fa5b6c18a003/bootstrap-master-SNAPSHOT.jar
const class_t haiku_vm_MicroKernel__class PROGMEM = {
& java_lang_Object__class,
SIZEOF_haiku_vm_MicroKernel,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.NullPointerException.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_NullPointerException__class PROGMEM = {
& java_lang_RuntimeException__class,
SIZEOF_java_lang_NullPointerException,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.RuntimeException.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_RuntimeException__class PROGMEM = {
& java_lang_Exception__class,
SIZEOF_java_lang_RuntimeException,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.Exception.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_Exception__class PROGMEM = {
& java_lang_Throwable__class,
SIZEOF_java_lang_Exception,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.ArrayStoreException.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_ArrayStoreException__class PROGMEM = {
& java_lang_RuntimeException__class,
SIZEOF_java_lang_ArrayStoreException,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.IndexOutOfBoundsException.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_IndexOutOfBoundsException__class PROGMEM = {
& java_lang_RuntimeException__class,
SIZEOF_java_lang_IndexOutOfBoundsException,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.NoSuchMethodError.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_NoSuchMethodError__class PROGMEM = {
& java_lang_Error__class,
SIZEOF_java_lang_NoSuchMethodError,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.Error.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_Error__class PROGMEM = {
& java_lang_Throwable__class,
SIZEOF_java_lang_Error,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.StackOverflowError.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_StackOverflowError__class PROGMEM = {
& java_lang_Error__class,
SIZEOF_java_lang_StackOverflowError,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.OutOfMemoryError.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_OutOfMemoryError__class PROGMEM = {
& java_lang_Error__class,
SIZEOF_java_lang_OutOfMemoryError,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.ClassCastException.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_ClassCastException__class PROGMEM = {
& java_lang_RuntimeException__class,
SIZEOF_java_lang_ClassCastException,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.ArrayIndexOutOfBoundsException.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_ArrayIndexOutOfBoundsException__class PROGMEM = {
& java_lang_IndexOutOfBoundsException__class,
SIZEOF_java_lang_ArrayIndexOutOfBoundsException,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.InternalError.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_InternalError__class PROGMEM = {
& java_lang_VirtualMachineError__class,
SIZEOF_java_lang_InternalError,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.VirtualMachineError.class from /Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/lib/nxt/classes.jar
const class_t java_lang_VirtualMachineError__class PROGMEM = {
& java_lang_Error__class,
SIZEOF_java_lang_VirtualMachineError,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > java.lang.ArithmeticException.class from /Users/chuck_benedict/.gradle/caches/modules-2/files-2.1/com.github.chuckb.haikuVM/haikuRT/master-SNAPSHOT/207b6d3a7213bb212e2886745d366b7f3d415f6c/haikuRT-master-SNAPSHOT.jar
const class_t java_lang_ArithmeticException__class PROGMEM = {
& java_lang_RuntimeException__class,
SIZEOF_java_lang_ArithmeticException,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
link > Main.class from /Users/chuck_benedict/Projects/helloworld/build/classes/java/main/Main.class
const class_t Main__class PROGMEM = {
& java_lang_Object__class,
SIZEOF_Main,
};
into /Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility/haikuJava.c
Building makefile for all subdirectories in your given directory '/Users/chuck_benedict/Projects/helloworld/build' ...
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/tools/avr/share/tk8.4
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/bootloaders/optiboot
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/bootloaders/atmega8
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/bootloaders/stk500v2
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/bootloaders/lilypad/src
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/bootloaders/caterina-LilyPadUSB
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/bootloaders/bt
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/bootloaders/atmega
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/bootloaders/caterina
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/cores/arduino
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/atmegaxxu2/arduino-usbdfu
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/atmegaxxu2/arduino-usbserial
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/DRIVERS/PM
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/DRIVERS/INTC
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/DRIVERS/USART
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/DRIVERS/GPIO
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/UTILS/DEBUG
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/BOARDS/EVK1105
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/BOARDS/ARDUINO
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/SERVICES/MEMORY/CTRL_ACCESS
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifi_dnld/src
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/PM
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/INTC
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/PDCA
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/TC
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/SPI
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/EBI/SMC
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/RTC
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/USART
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/GPIO
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/EIC
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/DRIVERS/FLASHC
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/UTILS/DEBUG
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/COMPONENTS/MEMORY/DATA_FLASH/AT45DBX
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/BOARDS/EVK1105
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/BOARDS/ARDUINO
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/SERVICES/MEMORY/CTRL_ACCESS
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/SERVICES/LWIP/lwip-1.3.2/src/core/ipv4
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/SERVICES/LWIP/lwip-1.3.2/src/core
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/SERVICES/LWIP/lwip-1.3.2/src/netif
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/SERVICES/LWIP/lwip-port-1.3.2/HD/if/netif
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src/SOFTWARE_FRAMEWORK/SERVICES/DELAY
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/hardware/arduino/firmwares/wifishield/wifiHD/src
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/haikuVM/src/platforms/pi
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/haikuVM/src/platforms
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/haikuVM/src/gcVariants
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/haikuVM/src/utility
/Users/chuck_benedict/Projects/helloworld/build/haikuVMSDK/haikuVM/src
/Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/platforms/pi
/Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/platforms
/Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/gcVariants
/Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src/utility
/Users/chuck_benedict/Projects/helloworld/build/HaikuVM/src
totalMethods= 42
totalBClength= 983
Warnings:
totalConstLength= 507
Warning: unsupported value 'rpi' for property 'Target'!
totalClassesLength=145
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.6.4/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 11s
9 actionable tasks: 9 executed
If it ends with BUILD SUCCESSFUL
, you should have noticed a new terminal window pop up with something like the following:
Now connect the red wire from the serial cable to pin 2 on the Pi.
Your new terminal window should show something like:
Last but not least, the green LED on your Pi should be blinking. If it is, congrats, you have just deployed a bare-metal embedded Java app on a Raspberry Pi Zero!
-
I will be testing and expanding the test coverage across platforms and boards, but this is where I am for now. ↩