Thursday Mar 28, 2013

RPi with an Oscilloscope and Java Embedded: Ready for Benchmarking (Part 6)

Well, the best laid plans of Raspberry Pi, Java Embedded and all that. There's some type of device access issue on the Raspberry Pi when trying to NIO memory map /dev/mem. So, I'm going to have take some time to debug that.

Instead let's go back to what we know works. Using pure Java Embedded API's we can use the file handle to get to the GPIO pins for access. So, let's roll back and start there again and incrementally move toward trying to match what we should be able to do with NIO.

Here's the code that we will roll back to. You can try this at home to see what type of speed you can get on your oscilloscope. I'll report what I have also.

/*
 * Example Code
 */

/*
 * Java Embedded Raspberry Pi Servo app
 */
package jerpitest;

import java.io.FileWriter;
import java.io.File;

/**
 *
 * @author hinkmond
 */
public class GPIOMaxRate {
    
    static final String GPIO_OUT = "out";
    static final String GPIO_ON = "1";
    static final String GPIO_OFF = "0";
    
    static String[] GpioChannels =  { "24" };

    /**
     * @param args the command line arguments
     */
    @SuppressWarnings("UseSpecificCatch")
    public static void main(String[] args) {
        FileWriter[] commandChannels;
        
        try {
            
            /*** Init GPIO port for output ***/
            
            // Open file handles to GPIO port unexport and export controls
            FileWriter unexportFile = 
                    new FileWriter("/sys/class/gpio/unexport");
            FileWriter exportFile = 
                    new FileWriter("/sys/class/gpio/export");

            // Loop through all ports if more than 1
            for (String gpioChannel : GpioChannels) {
                System.out.println(gpioChannel);
    
                // Reset the port, if needed
                File exportFileCheck = 
				new File("/sys/class/gpio/gpio"+gpioChannel);
                if (exportFileCheck.exists()) {
                    unexportFile.write(gpioChannel);
                    unexportFile.flush();
                }
            
                // Set the port for use
                exportFile.write(gpioChannel);   
                exportFile.flush();

                // Open file handle to port input/output control
                FileWriter directionFile =
                    new FileWriter("/sys/class/gpio/gpio" + gpioChannel + 
                        "/direction");
            
                // Set port for output
                directionFile.write(GPIO_OUT);
                directionFile.flush();
            }
            
            /*** Send fastest on/off to GPIO port ***/
            
            // Set up a GPIO port as a command channel
            FileWriter commandChannel = new 
			FileWriter("/sys/class/gpio/gpio" +
              	GpioChannels[0] + "/value");
            
            // Loop forever with fastest on/off to GPIO pin
            while (true) {
                    commandChannel.write(GPIO_ON);
                    commandChannel.flush();               

                    commandChannel.write(GPIO_OFF);
                    commandChannel.flush();        
                }
            }
            
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

This should be still pretty fast and good enough for most applications. But, we are still searching for the theoretically maximum frequency we can achieve using pure Java Embedded.

Thursday Mar 21, 2013

RPi with an Oscilloscope and Java Embedded: Ready for Benchmarking (Part 5)

One way to convert the C language GPIO access of /dev/mem is to use a Java NIO memory mapped buffer to open the Raspberry Pi memory as a device (with a Linux file descriptor), then get the file channel, then map it into the Java NIO accessible memory.

This is essentially the same process that Gordon Drogon is using in his WiringPi.c file. Instead of Java NIO, he is using the C and the Linux mmap() function to a file descriptor pointing to /dev/mem. So, our Java translation of that same functionality would look something like this.

/*
 * Example Code
 */

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

//...

  RandomAccessFile fileHandle = new 
    RandomAccessFile("/dev/mem", "rw");

  FileChannel fileChannel = fileHandle.getChannel();

  MappedByteBuffer gpioMem = fileChannel.map(
    FileChannel.MapMode.READ_WRITE, BCM2708_PERI_BASE + 0x200000, 
    PAGE_SIZE);

So, we have our Java code. Let's take a look if this works on the Raspberry Pi with our Java Embedded stack...

Monday Mar 18, 2013

RPi with an Oscilloscope and Java Embedded: Ready for Benchmarking (Part 4)

The next step in making Java Embedded just as fast as C native for Raspberry Pi GPIO pulse-wave modulation (PWM) is to match what C native does in the fastest programming case.

And, this means the place to look is in Gordon Drogon's canonical C native Wiring Pi library for the Arduino-compatible RPi GPIO. It's the best C code implementation currently out there, and it's what Pi4J uses underneath it's Java implementation.

See: WiringPi C Native Library

What we see when we carefully read the wiringPi.c file is that Gordon is using C native memory mapping of "/dev/mem" to access the GPIO portion of the RPi memory map for the quickest access possible. That's awesome! That's a very simple way to get at the GPIO pins with high performance for both reading and writing. So, of course we can do the same in Java (without JNI) using an NIO memory mapped file/device for that same high performance (in theory). Cool!

Here's the code we will consider...

/*
 * Example C Native Code: From wiringPi.c 
 * See: 
 * https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.c
 */
#define BCM2708_PERI_BASE 0x20000000
//...
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

//...

// Open the master /dev/memory device

  if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
  {
    fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", 
      strerror (errno)) ;
    return -1 ;
  }

// GPIO:

// Allocate 2 pages - 1 ...

  if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
  {
    fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", 
      strerror (errno)) ;
    return -1 ;
  }

// ... presumably to make sure we can round it up to a whole page size

  if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
    gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;

  gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, 
    PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, 
    GPIO_BASE) ;

Next, this needs to be translated from C to Java. We do this using NIO (New I/O) in Java SE Embedded. Note that NIO is not available in Java ME Embedded. Java SE Embedded has the full set of Java SE API's (including NIO) which is the crucial part of this exercise in order to get the same performance as C native.

More in the next blog post...

Thursday Mar 14, 2013

Open Now Until April 12: JavaOne 2013 San Francisco Call for Papers

Yes! The JavaOne 2013 Conference (San Francisco) Call for Papers is now open! Submit your cool and interesting ideas for talks at this Web page:

See:

JavaOne 2013 Call for Papers

Here's a quote:

 The Call for Proposals is open. Have 
 something interesting to present to 
 the world’s largest gathering of 
 Oracle technologists and business 
 leaders? Making breakthrough 
 innovations with Java or MySQL? We 
 want to hear from you...
Let's see how many talks we can get this year on Java Embedded and the Raspberry Pi. Let me know if there are other Java Embedded areas that you'd like to see covered. You have until April 12, 2013. Don't delay...

Tuesday Mar 12, 2013

RPi with an Oscilloscope and Java Embedded: Ready for Benchmarking (Part 3)

The first step in our investigation is to reproduce what Robert Savage saw in his benchmarking. See: Java GPIO Benchmarking

In his study, Robert Savage measured the Pi4J library on Oracle Java JDK 8 Preview for Linux/ARM yielding about 153 kHz on the Raspberry Pi GPIO output. So, following the scientific method, we should be able to reproduce the experiment.

And, with the following Java Embedded app on my RPi running with Oracle JDK 8 Preview for Linux/ARM and using my HP logic analyzer/oscilloscope I'm seeing about the same: 166 kHz. Click on the above photo to zoom in and look at the red circle area.

Here's the code I used:

/*
 * Example Code
 */

/*** Pi4J Core APIs ***/
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

//...
            
 /*** Pi4J initialization ***/
 
 // Create Pi4J GPIO Controller
 final GpioController gpio = GpioFactory.getInstance();
        
 // Use Pi4J GPIO pin #05 (Header Pin #18) as an output and turn on
 final GpioPinDigitalOutput pin = 
         gpio.provisionDigitalOutputPin(RaspiPin.GPIO_05, 
         PinState.LOW);
 
 // Loop forever to create smallest PWM as possible
 while (true) {          
     pin.setState(true);
     pin.setState(false);
 }
 

And, Robert reports he can get around 5 MHz using C native. So, that's our goal. In the next blog posts we'll explore ways to get our 166 kHz score on the benchmark a lot higher, hopefully matching C native with 5 MHz...

Friday Mar 08, 2013

RPi with an Oscilloscope and Java Embedded: Ready for Benchmarking (Part 2)

You now have your PicoScope or your extravagant logic analyzer with oscilloscope, and you're ready to hook it up to your Raspberry Pi to measure your Java app. It's pretty straight-forward.

Attach your scope probe (refer to your documentation for your specific oscilloscope), then find an open GPIO pin that you'll use. I'm going to use GPIO24 which is Pin #18 on the header (see diagram below).

The easiest way to do this is to take a male/female jumper wire (See: link) and connect the female end to Pin #18 (GPIO24) and the male end to the probe hook (See: top photo).



Then connect the alligator clip on the probe (which needs to be connected to ground -) to anything metal on the Raspberry Pi that is grounded. One safe place that is grounded is the outer part of the USB port (See: top photo). That's where I clipped my probe alligator clip.

That's it. You're connected now to use your scope. Next we'll take a look at different Java Embedded apps to drive the GPIO24 pin and start to benchmark the different approaches...

Thursday Mar 07, 2013

RPi with an Oscilloscope and Java Embedded: Ready for Benchmarking (Part 1)

So, the oscilloscope that Gary C. and Vlad D. found for our Java Embedded on Raspberry Pi analysis (see top photo) is actually a fancy-schmancy HP 16700A logic analyzer with an HP 16534A oscilloscope module -- which in plain English means it cost SavaJe beaucoup bucks to buy (4 G's back in 2001). And, I'm guessing that as a typical RPi hobbyist, you're not going to want to drop $4k on your project just to measure the frequency of a Java Embedded generated PWM wave. Am I right?

Thought so. Well, if you are interested in using an oscilloscope to play around with, there is hope. For example, here's a price-friendly PicoScope 2205A Oscilloscope.

This PicoScope only costs $275 at Allied Electronics, see PicoScope link. It does pretty much the same thing as the HP logic analyzer I have in my office, but at a much lower price... and with a lot less noise!

So, the first step for all you developers playing along at home is to beg, borrow, or buy an oscilloscope, or the PicoScope for a fraction of the price (if you don't have the luxury of using an HP logic analyzer from a previous high tech acquisition that is). Once you have that, come back to my future blog post and see how to hook it up to your Raspberry Pi for some GPIO benchmarking.

Monday Mar 04, 2013

RPi with an Oscilloscope and Java Embedded: Ready for Benchmarking

Houston, we have an oscilloscope!

Yes, through hard work and determination, well... actually through the luck of the donation of an old leftover logic analyzer with an oscilloscope module from the former SavaJe acquisition via Sun Microsystems, Inc., which is now here at Oracle, we now have a scope here in the office connected to our Raspberry Pi running Java Embedded technology! Woo-hoo!

I want to thank Gary C. and Vlad D. in their help tracking down this awesome (er, uh... a bit old) piece of electronic equipment. In a back storage closet somewhere in the darkest reaches of our Burlington, MA office, this logic analyzer with oscilloscope module from SavaJe days, sat collecting dust. But, luckily Gary remembered it was sitting there unused, when I asked if he knew if we had a scope in our group for some needed RPi/Java Embedded work. And, then Vlad and Barb helped ship it out here to California and the rest is history.

After dusting it off, plugging it in, and firing it up, it works!

What you see in the top photo is a computer screen grab of the oscilloscope output reading of the GPIO port signal from the Raspberry Pi with a Java Embedded app driving a Pulse Width Modulation (PWM) wave. And look, Ma, no native C programming involved!

We can go over this in detail in my future blog posts so that you can do this at home as well, as we benchmark how fast we can get Java Embedded to drive that GPIO pin signal (I'm hoping for > 5MHz, but what you see in the graph above is a signal driving a blinking LED, so don't get all hypercompetitive... yet). And, might as well compare it to C native, since everyone else does. :-)

Let the games begin...

About

Hinkmond Wong's blog on making Machine to Machine (M2M) and the Incredible Internet of Things (IoT) smarter with Java Embedded Technologies

Search

Categories
Archives
« March 2013 »
SunMonTueWedThuFriSat
     
1
2
3
5
6
9
10
11
13
15
16
17
19
20
22
23
24
25
26
27
29
30
31
      
Today