Recent Changes - Search:

Tracking

Hardware

Software

Mega Plan

Etc.

Java

We have available limited code for controlling both the Brainstem (over I2C or Serial) and the CMUCam2 (over Serial). This code has many bugs in it that we are still ironing out, and we're including it, like other code on this site, primarily to give you a better jumping-off point for development. In particular, we believe a conflict may arise between JamVM and I2C which causes freezing at intermittent points; we're still working on it.

Virtual Machines

We have tried three virtual machines on the Gumstix: JamVM, Wonka, and kaffe. All three VMs are simply bytecode interpreters, so don't expect astonishing speed. JamVM and Wonka have binaries for the ARM architecture; kaffe requires cross-compilation. The long and short of it: use JamVM. It's much faster, smaller, and cleaner. kaffe is the slowest, biggest, and most difficult to port.

JamVM also requires the GNU Classpath class library, which has to be loaded onto the Gumstix as well per instructions on the JamVM web page.

Using Kaffe (if you must)

Download Kaffe as kaffe-console.tar.gz and copy it to the Gumstix. Unpack it into these directories:

 /mnt/mmc/usr/
 /mnt/mmc/usr/lib/
 /mnt/mmc/usr/lib/kaffe-console/
 /mnt/mmc/usr/lib/kaffe-console/lib/
 /mnt/mmc/usr/lib/kaffe-console/jre/lib/
 /mnt/mmc/usr/lib/kaffe-console/jre/lib/security/
 /mnt/mmc/usr/lib/kaffe-console/jre/lib/arm/
 /mnt/mmc/usr/lib/kaffe-console/jre/bin/

Create a symlink back to the root filesystem by running

 ln -s /mnt/mmc/usr/lib/kaffe-console /usr/lib/

Then run java

  /usr/lib/kaffe-console/jre/bin/java -cp /mnt/mmc test

to get

 # /usr/lib/kaffe-console/jre/bin/java -cp /mnt/mmc test
 Hello World!

You can also add to the default path and just run 'java'

 # export PATH=$PATH:/usr/lib/kaffe-console/jre/bin/
 # java -cp /mnt/mmc test
 Hello World!

Notes

  • Kaffe seems to be really slow, at least to start up (perhaps compiling with the jit engine instead of intrp will help a little?)
  • /usr/lib/kaffe-console/jre/lib/arm contains copies of system libraries such as libm, libdl, libresolv, libc, etc because the ones that are on the gumstix / compiled by the gumstix buildroot don't seem to work right
  • Since symlinks don't work on vfat (i.e. the mmc card) there are two copies of each library in /usr/lib/kaffe-console/jre/lib/arm
  • We did not prune any of the unneeded files from /usr/lib/kaffe-console/jre/lib/rt.jar (currently 6.6mb): all the awt, microsoft and other unneeded classes could be removed from in there to save a few megabytes

Where to Put Java and Jar Files

Put "permanent" robot jar files in /usr/local/robot/jar and your working files wherever you like. Our approach to Java on the Gumstix is to assume that VM's CLASSPATH includes your existing CLASSPATH, the current directory, ~/java, and all jar files in the /usr/local/robot/jar/ directory. Once you've installed a Java VM on your box, you might use a script along these lines as your /usr/local/bin/java file (the example below shows how to do it for JamVM):

 #!/bin/sh

 # Set up the classpath to be: .:~/java: ... and various
 # jars in /usr/local/robot/jar

 CLASSPATH=.:${HOME}/java:$CLASSPATH
 for i in `ls /usr/local/robot/jar/*.jar`
         do
         CLASSPATH=${CLASSPATH}:$i
         done
 export CLASSPATH

 # Add additional stuff to the CLASSPATH just for JamVM
 CLASSPATH=${CLASSPATH}:/usr/local/share/classpath/glibj.zip
 CLASSPATH=${CLASSPATH}:/usr/local/share/jamvm/classes.zip

 # Run JamVM
 /usr/local/bin/jamvm -C $CLASSPATH $*

BeanShell

BeanShell is an enormously useful jar file to have on the Gumstix. It provides a command line for Java, allowing you to issue Java method calls by hand. The bsh-core is sufficient for most needs. Once the jar file has been installed in your CLASSPATH, you can run it with java bsh.Interpreter

Java Compilers

Both Jikes and KJC (a free javac replacement) work on the Gumstix, part of the Kopi Project. We think that Jikes may occasionally produce incorrect bytecode -- but it's really fast.

KJC

  1. First download the following two files: Attach:javac and Attach:kjc-2.1B-bin.jar
  2. Second, put these two files in swarm's home directory. (/mnt/mmc/home/swarm/)
  3. Third, as root, issue the following commands

mv /mnt/mmc/home/swarm/javac /usr/local/bin/javac
chmod ugo+x /usr/local/bin/javac
mv /mnt/mmc/home/swarm/kjc-2.1B-bin.jar /usr/local/robot/jar/
chmod ugo+r /usr/local/robot/jar/kjc-2.1B-bin.jar

You can run KJC as java at.dms.kjc.Main or just run the provided javac script. The documentation for the whole "Kopi Suite" (of which we only are including kjc) can be found here: Attach:kopi.html

Jikes

  1. First, download the following two files: Attach:jikes and Attach:javac-jikes
  2. Second, put these two files in swarm's home directory. (/mnt/mmc/home/swarm/)
  3. Third, as root, issue the following commands

mv /mnt/mmc/home/swarm/javac-jikes /usr/local/bin/javac-jikes
chmod ugo+x /usr/local/bin/javac-jikes
mv /mnt/mmc/home/swarm/jikes /usr/local/bin
chmod ugo+r /usr/local/bin/jikes

The easiest way to run jikes is the provided javac-jikes script, which automatically sets the linker path, classpath and boot classpath.

Communicating with the Brainstem Over Serial

You can use Acroname's proprietary java code to communicate with the brainstem via the serial daemon with a few modifications. First, delete the jStem.serialEvent method and replace it with the following:

 public void nonBlockingEvent() {
     if (in != null) {
         byte readBuffer;
         try {
             while (in.available() > 0) {
                 readBuffer = (byte)(in.read());
                 handleByte(readBuffer);
             }
         } catch (IOException e) {
             System.out.println("error handling byte");
             e.printStackTrace();
         }
     }
 }

Next, compile following Java code and include in Acroname's jar file: NonBlockingInputStream.java

You can use the code like this:

Socket s = new Socket("localhost", 5002);
inputStream = new NonBlockingInputStream(s.getInputStream());
((NonBlockingInputStream)inputStream).registerNonBlockingEvent(stem);
/* tell the stream where to get I/O */
stem.SetStream(inputStream, s.getOutputStream());

Communicating with the Brainstem over I2C

We have made a simple class which communicates with the Brainstem over I2C by accessing the /dev/brainstem device file. The file is called Brainstem.java and like the serial code above, it needs our NonBlockingInputStream.java file. However, it does not require any Acroname code at all. Keep in mind that to use I2C you must modify the Brainstem's internal I2C address as described here.

Usage:

 import acroname.*;
 int a;
 Brainstem b = new Brainstem();
 b.setServo(4,2,220);  // set brainstem #4's second servo to 220 
 a = b.getA2D(4,2);  // get brainstem #4's second analog (0 to 64K)
 a = b.getDigital(4,2);  // get brainstem #4's second digital (0 or 1) 
 a = b.getCharScratchpad(4,2);  // get brainstem #4's second pad as a byte) 
 a = b.getIntScratchpad(4,2);  // get brainstem #4's second and third
                               // scratchpads together as an int) 
 b.setCharScratchpad(4,2,220);  // set brainstem #4's second pad to 
                               // 220 as a byte)
 b.setIntScratchpad(4,2,1000);  // get brainstem #4's second and third 
                               //scratchpads together to 1000 as an int)

In all cases the functions return Brainstem.FAIL (-1024 presently) if the operation failed on the Brainstem.

Communicating with the CMUCam2 over Serial

The cmucam.jar file provides some basic code for communicating with the CMUCam2 over the serial daemon on the Gumstix. Java source is included in the jar file (it's only three Java files). The following CMUCamExample.java file provides an example for using the code.

The alternative is to use a JNI native interface. We have been working on one designed for use with the CMUCam. It's available as cmucamlibjava.tar.gz with source code. Usage:

  • Put CMUCam2.jar in /usr/local/robot/jar
  • Put libjavaCMUCam2.so in /usr/local/lib
  • Create an instance of CMUCam2: CMUCam2 camera = new CMUCam2(5002) [see camTest.java]
  • Run commands using camera.runCommand("command")
  • Look at output type stored in camera.returnType (equal to camera.typeT, camera.typeS, camera.typeSTR, camera.typeACK...)
  • Access data based on return type (camera.STR, camera.T.mx, camera.S.Rmean)
  • Run camera.print() to print out all returned data
  • Run camera.unInit() when done
  • Ensure the following paths so java knows where to find the .so files:
    • LD_LIBRARY_PATH=/usr/local/lib

Yet to do:

  • Translate errors in init() to exceptions
  • Accept a baud rate in the constructor
  • Implement debugging output in java-space with CMUCam2.print() and debug toggle in constructor
Edit - History - Print - Recent Changes - Search
Page last modified on June 18, 2005, at 02:25 PM