RPi and Java Embedded GPIO: Big Data and Java Technology

Java Embedded and Big Data go hand-in-hand, especially as demonstrated by prototyping on a Raspberry Pi to show how well the Java Embedded platform can perform on a small embedded device which then becomes the proof-of-concept for industrial controllers, medical equipment, networking gear or any type of sensor-connected device generating large amounts of data.

The key is a fast and reliable way to access that data using Java technology. In the previous blog posts you've seen the integration of a static electricity sensor and the Raspberry Pi through the GPIO port, then accessing that data through Java Embedded code. It's important to point out how this works and why it works well with Java code.

First, the version of Linux (Debian Wheezy/Raspian) that is found on the RPi has a very convenient way to access the GPIO ports through the use of Linux OS managed file handles. This is key in avoiding terrible and complex coding using register manipulation in C code, or having to program in a less elegant and clumsy procedural scripting language such as python. Instead, using Java Embedded, allows a fast way to access those GPIO ports through those same Linux file handles.

Java already has a very easy to program way to access file handles with a high degree of performance that matches direct access of those file handles with the Linux OS. Using the Java API java.io.FileWriter lets us open the same file handles that the Linux OS has for accessing the GPIO ports. Then, by first resetting the ports using the unexport and export file handles, we can initialize them for easy use in a Java app.

            // 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");
...
            // Reset the port
            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();

Then, another set of file handles can be used by the Java app to control the direction of the GPIO port by writing either "in" or "out" to the direction file handle.

                // Open file handle to input/output direction control of port
                FileWriter directionFile =
                    new FileWriter("/sys/class/gpio/gpio" + gpioChannel + 
                        "/direction");
            
                // Set port for input
                directionFile.write("in");  // Or, use "out" for output
                directionFile.flush();

And, finally, a RandomAccessFile handle can be used with a high degree of performance on par with native C code (only milliseconds to read in data and write out data) with low overhead (unlike python) to manipulate the data going in and out on the GPIO port, while the object-oriented nature of Java programming allows for an easy way to construct complex analytic software around that data access functionality to the external world.

               
      RandomAccessFile[] raf = new RandomAccessFile[GpioChannels.length];
...
      // Reset file seek pointer to read latest value of GPIO port
      raf[channum].seek(0);
      raf[channum].read(inBytes);
      inLine = new String(inBytes);

It's Big Data from sensors and industrial/medical/networking equipment meeting complex analytical software on a small constrained device (like a Linux/ARM RPi) where Java Embedded allows you to shine as an Embedded Device Software Designer.

Comments:

Hinkmond... don't lie to yourself. You know this is not the way to do I/O. Who is responsible for hardware in Java? I mean stuff like ping, USB, PCI, MB serial number etc. Is it really so hard to link this with JNA/JNI ?

Posted by guest on December 13, 2012 at 03:09 PM PST #

K.I.S.S. Principle of Keeping It Simple, means avoiding the need for javah, *.h files, extra steps in building, etc, etc, and is a good thing, especially if all you have to copy to the RPi device is a simple single *.jar file. No .so, .o, or native code needed. And, my performance measurement results show equal speed to C native access. So, it's a win-win situation.

Posted by Hinkmond Wong on December 13, 2012 at 03:50 PM PST #

Yes, this is true. I thought about Java in general. It would be great if there were some libraries to access hardware. Even if you had to download it separately. I need now a USB library and i'm struggling with joining libusb with Java wrapper with Java. If there only was a libusb.jar ...

Anyway i love to read your blog, keep it going! :)
Martin

Posted by guest on December 14, 2012 at 02:17 PM PST #

Hi Martin,

That's a actually a great topic for a future blog post. I can describe how to use Java Embedded and the Linux libusb on the RPi. But, there's the same all-Java (no JNI) high-performance approach that can be used as I do with the GPIO ports, except using fast Java I/O code to access the /dev/ldusbNN file handle (such as /dev/ldusb0) for USB devices plugged into the RPi or other Linux devices. More on that topic in a future blog post...

Thanks for reading my blog!
Hinkmond

Posted by Hinkmond Wong on December 14, 2012 at 03:46 PM PST #

> But, there's the same all-Java (no JNI) high-performance approach

You realize, the Java file APIs use JNI internally?
And that a JNI "downcall" on x86 takes usually no more than 10-20cycles?

Furthermore the Java-IO-APIs you use are considered to be outdated, so while they migh provide high performance for your use-case, for doing real stuff with large data you should look at NIO/NIO2.

Posted by Dude on December 16, 2012 at 03:52 AM PST #

Hi Regina,

Good point about NIO/NIO2. However, the Java core libraries do not require the use of JNI for calling down to the native layer. In our Hotspot VM and in JDK Java core libraries (not your typical Java apps), our java.io.* API calls can bypass JNI and make calls directly into native C/C++ to the OS or can even use assembly language code injection where appropriate for optimal native interaction versus the typical JNI from a compiled Java app. Not something a normal Java app developer can do or knows about, but something we do in the Hotspot VM and JDK Java core libraries for you without you needing to figure that out on your own using the a cumbersome and slow JNI library. This is done in the Java core libraries for high performance. And, that is why it's better to use an all-Java app in this case.

For NIO/NIO2, I will cover that in a future blog post in terms of how that is used with Java Embedded on the Raspberry Pi for GPIO, without the need of JNI or any native C programming by the developer also. That's a great suggestion for a future blog post.

The key take-away is that writing a 100% pure Java app in some cases will yield the highest performance instead of using JNI on the Java app level.

Thanks!

Posted by Hinkmond Wong on December 16, 2012 at 03:19 PM PST #

"(only milliseconds to read in data and write out data)"

Is it really that slow?

Posted by Bruce on December 16, 2012 at 04:58 PM PST #

Bruce, dude, "only milliseconds to read data in" is really that *fast*. About 1-1.25 ms for actual the GPIO hardware measurement, and about another 1 or 2 ms to report that data as output to console. It's about 2-3 milliseconds in total when written in 100% pure Java. That's fast, not slow. And, more importantly the same as C native reads of GPIO with a printf to stdout. It's fast enough that if it were off by another order of magnitude, you would never be able to see the difference.

Posted by Hinkmond Wong on December 17, 2012 at 10:37 AM PST #

Post a Comment:
Comments are closed for this entry.
About

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

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today