Cannot access /dev/gpiochip*; Operation not permitted

The gpio-control interface that snapd provides allows access to the sysfs interface for GPIO, that interface has been deprecated for a while (sysfs interface not snapd’s). In our case we are using libgpiod, which uses /dev/gpiochip* to control the GPIO pins. Clearly there is no snapd interface that allows access to that path. So I patched gpio_memory_control.go interface and added below line to it

/dev/gpiochip[0-9]* rw,

Previously when I was trying to access /dev/gpiochip0 I was getting “Permission denied” and dmesg logs would clearly show the reason. Now after patching snapd, I am still not able to access the /dev/gpiochip0 and get Operation not permitted instead.

It’s clear my patch to snapd made some changes, but why am I not able to access that path still. Outside snap environment I can access path but not from within. --devmode also works

Some details about the system: This is RaspberryPI CM4 based board.

Do note that patch works fine on a iMX8MP based board and the issue only happens with CM4 based board. Both systems are running Yocto. Seems like Snapd/Apparmor are doing something weird here ?

The earlier EACCESS was caused by apparmor. The EPEMR is coming from device cgroup contoller. Most likely you need to update the patch to tag the /dev/gpiochip* for a given snap. In short, you need to add a udev snippet that would match the device (eg by SUBSYSTEM="gpio", KERNEL="gpiochip*' or something similar) and add a TAG+="snap_<yoursnap>_<yourapp>. There should be a bunch of examples under insterfaces/builtin, eg the opengl interface.

1 Like

Awesome, thanks a lot. This seems to have worked :slight_smile:

I only added KERNEL="gpiochip*

Hi, I have tried a lot to get libgpiod library to work. @om26er @mborzecki1
But i keep getting error:

terminate called after throwing an instance of ‘std::system_error’ what(): cannot open GPIO device /dev/gpiochip0: Operation not permitted Aborted

This is the snapcraft file to turn on gpio.

  name: gpio-test
  version: 0.0.0
  summary: turn on gpio
  description: 'N/A

    '
  apps:
    gpio-test:
      command: ./gpiod-test
      plugs:
      - network
      - network-bind
      - hardware-observe
      - mount-observe
      - gpio-memory-control
      - home
      - gpiod
      - gpio-control
      - firewall-control
      - process-control
      environment:
        LD_LIBRARY_PATH: $SNAP/usr/lib/aarch64-linux-gnu:${LD_LIBRARY_PATH}
      command-chain:
      - snap/command-chain/snapcraft-runner
  architectures:
  - arm64
  assumes:
  - command-chain
  base: core20
  confinement: strict
  grade: stable
  plugs:
    gpiod:
      interface: system-files
      write:
      - /dev/gpiochip0
      - /dev/gpiochip1

This is the cpp file:

#include <gpiod.hpp>
#include <stdio.h>
#include <unistd.h>

using namespace std;

int main(int argc, char **argv)
{   
    gpiod::line m_gpio_line;
        gpiod::chip chip("/dev/gpiochip0");
    m_gpio_line = chip.get_line(27); 
    m_gpio_line.request({"gpio_consumer", gpiod::line_request::DIRECTION_OUTPUT, 0}, 1);
    m_gpio_line.set_value(0);
    m_gpio_line.release();
    return 0;
}

Could you please help me regarding this?

The only way to do this currently that I am aware of is to patch and build your own snapd and Ubuntu Core image.