The test app (and the actual service) can't access the GPIO in confinement on Ubuntu Core:
$ sudo matter-pi-gpio-commander.test-blink
WiringPi pin: 8
wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: Permission denied.
Aborting your program because if it can not access the GPIO
hardware then it most certianly won't work
Try running with sudo?
This is a confinement issue because on Ubuntu Core and other distros, the app and service can access the GPIO when installing the snap in developer mode (--devmode flag). Here is the output of snappy-debug:
The currently used setup functionwiringPiSetupGpio(void) uses the low-level gpiomem interface, rather than sysfs. The wiringPiSetupSys(void) function setup function uses the sysfs (/sys/class/gpio), however it has the following limitations:
It does not export the gpio
The GPIO direction setting functions will have no effect
The gpio snap interface exports the GPIO on connection but the direction isn't set. The direction needs to be set manually:
If the direction is left as in, the application neither shows errors nor performs the expected GPIO value change. A GPIO connect hook (connect-plug-gpio) may be used to set the direction upon connection.
Relevant snippet from the WiringPi documentation, supporting these findings:
wiringPiSetupSys (void) ;
This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using the gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers – the same as wiringPiSetupGpio() above, so be aware of the differences between Rev 1 and Rev 2 boards.
Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program. You can do this in a separate shell-script, or by using the system() function from inside your program to call the gpio program.
Also note that some functions have no effect when using this mode as they’re not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed)
Given that the gpio snap interface is missing by default from Ubuntu Server and other confined distros, it makes sense to use the gpiomem interface and grant that access via the snap's gpio-memory-control interface. This is less secure than the gpio interface because it gives access to all GPIO memory. However this is an acceptable compromise for the sake of usability. The gpio-memory-control interface is available on both Ubuntu Core and classic Ubuntu so we no longer need to install the snap in developer mode on classic.
As such, this PR makes the following changes:
Replace the unused gpio snap interface plug with gpio-memory-control. The gpio interface is useful only when using the wiringPiSetupSys(void) WiringPi setup function.
Remove obsolete gpio snap interface related instructions
Remove the instructions related to the need for installing the snap in developer mode.
Test
$ sudo snap install matter-pi-gpio-commander --channel=edge/gpiomem
matter-pi-gpio-commander (edge/gpiomem) 0.3.0 from Farshid Tavakolizadeh (farshidtz) installed
$ sudo snap set matter-pi-gpio-commander gpio=4
$ sudo matter-pi-gpio-commander.test-blink
GPIO: 4
wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: Permission denied.
Aborting your program because if it can not access the GPIO
hardware then it most certianly won't work
Try running with sudo?
$ sudo snap connect matter-pi-gpio-commander:gpio-memory-control
$ sudo matter-pi-gpio-commander.test-blink
GPIO: 4
On
Off
On
^C
The test app (and the actual service) can't access the GPIO in confinement on Ubuntu Core:
This is a confinement issue because on Ubuntu Core and other distros, the app and service can access the GPIO when installing the snap in developer mode (
--devmode
flag). Here is the output ofsnappy-debug
:The currently used setup function
wiringPiSetupGpio(void)
uses the low-level gpiomem interface, rather than sysfs. ThewiringPiSetupSys(void)
function setup function uses the sysfs (/sys/class/gpio), however it has the following limitations:The gpio snap interface exports the GPIO on connection but the direction isn't set. The direction needs to be set manually:
If the direction is left as
in
, the application neither shows errors nor performs the expected GPIO value change. A GPIO connect hook (connect-plug-gpio) may be used to set the direction upon connection.Relevant snippet from the WiringPi documentation, supporting these findings:
Given that the
gpio
snap interface is missing by default from Ubuntu Server and other confined distros, it makes sense to use the gpiomem interface and grant that access via the snap's gpio-memory-control interface. This is less secure than thegpio
interface because it gives access to all GPIO memory. However this is an acceptable compromise for the sake of usability. Thegpio-memory-control
interface is available on both Ubuntu Core and classic Ubuntu so we no longer need to install the snap in developer mode on classic.As such, this PR makes the following changes:
gpio
snap interface plug withgpio-memory-control
. Thegpio
interface is useful only when using thewiringPiSetupSys(void)
WiringPi setup function.gpio
snap interface related instructionsTest