The Pi4J Project now supports non-privileged access to the basic GPIO input and output functions of the Raspberry Pi as well as serial (UART), I2C and SPI communication. What this means is that launching your Java application with "sudo" or running as a user account with "root" permissions is no longer required!
How Does it Work?
The latest Raspbian images now includes kernel support for a user accessible mapped memory access to the GPIO hardware via the "/dev/gpiomem" interface. The latest images also include the predefined UDEV rules configuration allowing read/write access to the GPIO interfaces for users accounts that are members of the "gpio" group. The UDEV rules also permit SPIDEV access to users who are members of the "spi" group and I2C access to users who are members of the "i2c" group. Be default the "pi" user is a member of all three of these groups.
What Do I Need?
You will need to be running the latest Raspbian Jesse image for the Raspberry Pi:
You will need the Device Tree enabled. Don't worry, its enabled by default in the latest images. That is unless you disabled it :-) You can enable it under the "Advanced" menu in the "raspi-config" utility. More information on device tree support: https://www.raspberrypi.org/documentation/configuration/device-tree.md
Latest Pi4J Libraries
You will need the latest Pi4J-1.1-SNAPSHOT builds (dated 2015-12-14 or later).
Non-Privileged Access for Serial (UART), SPI, I2C
For SPI and I2C communications, no further action is needed to enable non-privileged access. For Serial (UART), if you are trying to use the default hardware UART ("/dev/ttyAMA0"), then the login shell feature must be disabled under the "Advanced" menu in the "raspi-config" utility.
Non-Privileged Access for GPIO
Non-privileged access for GPIO is not enabled by default due to the fact that some functions such as PWM are not yet supported in a non-privileged context. So you must explicitly enable non-privileged GPIO access either via an environment variable or via a one line addition to your Java source code.
Note: Enabling non-privileged GPIO access will prevent clock and PWM functions from working.
Enable via Java Code
The Java code is probably the easiest method so we will start with that. Its basically just a single line of code (as shown below) that must be called before you create your GPIO controller instance. This method will throw a RuntimeException if it is not able to enable non-privileged access.
A complete example source file is available here:
Enable via Environment Variable
An alternative to embedding this logic inside your Java code is to export the environment variable "WIRINGPI_GPIOMEM".
If you want this environment variable to be persisted you may want to append it to the end of your ~/.bashrc file. This is really an environment variable used by WiringPi directly. More details on this environment variable can bve found here: http://wiringpi.com/wiringpi-update-to-2-29/
Launching Your Non-Privileged Java Program
To launch your Java program with non-privileged GPIO access, simply omit the "sudo" instruction from your java command line:
java -classpath .:classes:'*':classes:/opt/pi4j/lib/'*' NonPrivilegedGpioExample
Or if you are using the "pi4j" script, then you don't have to do anything. We have removed to "sudo" instruction from the Java launch commands inside the pi4j script.
Please note non-privileged access is only supported on the Raspberry Pi platform at this time. The individual WiringPi library ports for BananaPi, BananaPro and Odroid would need to be updated to support this feature.