pi4j-v2 icon indicating copy to clipboard operation
pi4j-v2 copied to clipboard

The big sudo challenge: how can we fix the need to run PiGpio provider applications as sudo?

Open FDelporte opened this issue 2 years ago • 13 comments

As the native PiGpio integration requires sudo-privileges, a lot of users have problems or don't know if this requirement although it is mentioned in the documentation.

Relateded issues

  • https://github.com/Pi4J/pi4j-v2/issues/211
  • https://github.com/Pi4J/pi4j-v2/issues/117

FDelporte avatar Apr 18 '22 18:04 FDelporte

This is not just a documentation issue. This is a real deal-breaker and makes using Pi4J utterly unusable in any program that requires network listeners or similar permission sensitive services. Node and python both have ways of doing GPIO and SPI without sudo privileges and appear to do so without yet another daemon and yet another slow socket interface. Are there any supported alternatives to pigpio please?

sgparry avatar Apr 25 '22 11:04 sgparry

The sudo requirement can be mitigated for select functions including GPIO, I2C, SPI, SERIAL with the implementation of Linux file system I/O providers opposed to the PiGpio implementation. This is on my list of things TODO.

Accessing GPIO via the Linux (user) file system drivers does add some latency but likely not as much as a socket daemon.

I'm not sure if PWM functions or other supported I/O capabilities have been exposed via the Linux FS yet or not.

Additional details when this was implemented in the previous generation of Pi4J are included here: http://www.savagehomeautomation.com/pi4j-nonprivileged

REF: https://github.com/Pi4J/pi4j-v2/issues/117

savageautomate avatar Apr 25 '22 13:04 savageautomate

Hi @savageautomate, would be great if you could get me started on this LinuxFS or if we could work together on it... See https://github.com/Pi4J/pi4j-v2/issues/117

FDelporte avatar Apr 25 '22 13:04 FDelporte

An interesting (and faster) alternative is to consider using /dev/gpiomem. It's there for exactly this purpose.

hackerjimbo avatar Apr 25 '22 17:04 hackerjimbo

@hackerjimbo sounds promising :-) you have some more info or example implementations of this approach?

FDelporte avatar Apr 25 '22 18:04 FDelporte

The GPIO library used by the v1 version used it.

hackerjimbo avatar Apr 25 '22 18:04 hackerjimbo

Essentially it's like /dev/mem but limited to the GPIO area.

hackerjimbo avatar Apr 25 '22 18:04 hackerjimbo

So why did later versions switch to things like Wiring and now pigpio, which themselves both seem to have very limited / sporadic support?

sgparry avatar Apr 25 '22 18:04 sgparry

Because the original one wasn't maintained.

hackerjimbo avatar Apr 25 '22 18:04 hackerjimbo

indeed WiringPi got deprecated in 2019. That's why Pi4J V2 switched to PiGpio. These native libraries are the "gateway" between Java and the GPIOs.

FDelporte avatar Apr 25 '22 18:04 FDelporte

Problem seems to be that these gateways all to often become unhinged. pigpio not only requires root privileges but also seems to block other programs from accessing unrelated gpio pins and does not release that control even when you terminate the daemon.

sgparry avatar Apr 26 '22 14:04 sgparry

@sgparry

I have been working on the LinuxFS implementation of a GPIO provider based on the older Linux Filesystem GPIO driver via the /sys/class/gpio file. You user account must have the gpio group assigned to it to use this without sudo.

You can see this changes and build from this branch if you would like to test them out. https://github.com/Pi4J/pi4j-v2/commits/issues/%23117

Here are some basic examples I used to test with for Linux FS Digital Input, Digital Output, and PWM: https://github.com/savageautomate/pi4j-remote-test/tree/main/src/main/java/com/pi4j/remote

Note, I did not get PWM working on my system without sudo; however, this may just be a configuration or overlay issue. I need to update to the latest OS version and try again.

savageautomate avatar May 04 '22 16:05 savageautomate

@hackerjimbo

An interesting (and faster) alternative is to consider using /dev/gpiomem. It's there for exactly this purpose.

Yes, that would be something we could look into. However, to start with I'm trying to target the generic Linux kernel defined GPIO APIs so that the implementation may potentially be useful for other SoCs in the future.

If we implement any RaspberryPi specific code, we would do that in the RaspberryPi I/O providers (which are currently just stubs and not implemented.).

Currently, I'm prototyping the native code to allow Pi4J to use the newer /dev/gpiochip* character Linux device driver opposed to the older proc FS (/sys/class/gpio) driver which apparently is getting deprecated. (More info: https://elixir.bootlin.com/linux/v5.15/source/include/uapi/linux/gpio.h). If I target the 5.15 kernel in the latest Raspbian OS release we may be able to include things like PULL UP/DOWN bias which was not previously supported via the Linux filesystem drivers. I still need to test this out and see if it works but I have been able to get the basic input and output working in native code. This still may not be as efficient as the /dev/gpiomem approach but it would at least adhere to the generic Linux APIs for GPIO access.

savageautomate avatar May 04 '22 16:05 savageautomate