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...

Comments:

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