3

I appreciate the PI4J project and the access it provides to GPIO from Java (my language of choice) however, compared to C, Java is much slower. Normally this is not a problem but I was working with accessing the HC-SR04 ultrasonic TX/RX and I needed to make timings at the microsecond level. For example, to measure a distance of 10cm, I need to measure a pulse that is high for only 590 usecs.

My belief is that Java is too slow for these rates. When I wrote my app in C, it was more than fast enough to take a measurement. However, I only needed to report the measured distance every second to my user. This meant that I could write my interfacing code in C but write the remainder of my logic in Java.

This worked great. Using Java's JNI, I could call "wiringPi" directly and without issue. However, prior to calling the wiringPi APIs to change the state of pins and watch for changes, I have to call wiringPi setup functions including defining the input or output direction off a pin. I figured that I could use PI4J to setup my environment and then call C to perform my measurements. This appeared not to work and I had to do all my wiringPi APIs from C and ignore the PI4J library altogether.

And with this pre-amble, now the question.

If I wish to make direct wiringPi API calls from a C function and the C function is called from Java via JNI, can we "mix in" the use of PI4J in conjunction with direct wiringPi API calls?

Kolban
  • 1,794
  • 2
  • 16
  • 28

2 Answers2

2

This may seem like a slight aside, but perhaps may answer your question a little better. If this is all clear to you, I'll answer anyway in the hopes it is useful to someone else.

All access to GPIOs in Linux is done through the kernel. And there's a specific GPIO subsystem to handle this. Your very best performance would be to write a kernel driver.

However, the GPIO driver writers have provided a very clean and simple interface to the GPIO subsystem. This can be accessed from userspace via the sysfs filesystem. Specifically, via /sys/class/gpio/.

Any userspace API that is accessing GPIOs either wrote their own driver, did some mmap()ing directly to the GPIO registers (BAD!), or used the sysfs interface mentioned above. The is true of WiringPi and any others.

Bottom line is that you can directly use sysfs interface - its quite easy to use. Google for more info on it (include the kernel docs).

Here's a super duper simple example. To use GPIO 12 as an input (the default), and view its current value:

pi@raspberrypi ~ $ echo 12 > /sys/class/gpio/export pi@raspberrypi ~ $ cat /sys/class/gpio/gpio12/value 1

Brian
  • 577
  • 3
  • 9
0

If I wish to make direct wiringPi API calls from a C function and the C function is called from Java via JNI, can we "mix in" the use of PI4J in conjunction with direct wiringPi API calls?

There's only one way to find out for sure, but I don't see why not. They're both presumably using the same basic methodology, which is to mmap() part of kernelspace. I don't think it is possible for one process to prevent another process from doing the same thing at the same time in this sense, and it certainly isn't desirable to prevent it, or you could only have one program on the system using this at a time.

goldilocks
  • 60,325
  • 17
  • 117
  • 234