/sys/class/gpio/export not idempotent, unexports gpios

/sys/class/gpio/export will unexport a pin if accessed twice. Is this a bug?

$ echo 13 > /sys/class/gpio/export

$ ls /sys/class/gpio/gpio13

active_low device direction edge label power subsystem uevent value
$ echo 13 > /sys/class/gpio/export
-bash: echo: write error: Operation not permitted
$ ls /sys/class/gpio/gpio13
ls: cannot access ‘/sys/class/gpio/gpio13’: No such file or directory

Expected behavior: gpio13 should still be there after the second export.
Observed behavior: gpio13 disappears after the second export.

This is with the latest Debian kernel (4.14.71-ti-r80).

Is there a recommended way to export a gpio pin if it may already exist? I want to write a script to set up the pins. I could check if each pin already exists, but that’s a recipe for race conditions as well as being inconvenient.

Ken

Don’t use that interface…

https://blog.adafruit.com/2018/12/02/update-new-gpio-interface-for-linux-user-space-gpio-character-device-api-and-libgpiod-linuxpiter/

Regards,

libgpiod looks like a nice API. I tried it out, but I’m rather baffled by the behavior. If I try to set a pin with gpioset, it turns the pin off and unexports it.

$ config-pin P8_44 1 # This turns P8_44 on as expected

$ gpioset gpiochip2 9=1 # Should turn on gpio2[9], i.e. P8_44, but turns it off.
$ config-pin P8_44 1# Now config-pin can’t access the pin???
WARNING: GPIO pin not exported, cannot set direction or value!

So why does gpioset turn the pin off instead of on? This isn’t specific to P8_44; for instance “gpioset gpiochip2 7=1” will mess up P8_46 (gpio2[7]). This also happens even if I don’t use config-pin, so it’s not config-pin messing things up.

Ken

I’m also having problems with libgpiod - it simply does not work on a BBB with kernel 4.14.71-ti-r80. Cape universal is disabled, relevant pins are not exported via sysfs gpio interface.

Example: I’m trying to set P9.23 a.k.a. gpio number 49 (gpiochip 1, pin 17) and absolutely nothing happens. The pin stays in some high-z state, measuring 0.6 volts:
$ sudo gpioset gpiochip1 17=0

$ sudo gpioset gpiochip1 17=1

Running “gpioinfo gpiochip1” shows my pin as output, while it’s definitely not that:

line 17: “GPMC_A1” unused output active-high

Also tried to control each of the user LEDs on pins 21-24 on the same port with very strange results. I managed to switch on usr1 or usr2 and no further changes are possible - the one LED won’t turn off and the others won’t turn on. Also wrote a small C program which uses the “linux/gpio.h” API - doesn’t do anything useful to any of the pins.

Am I missing something here?

And the usual sysfs interface on the same works just fine. Verified with a multimeter.

echo 49 > /sys/class/gpio/export

echo low > /sys/class/gpio/gpio49/direction

echo high > /sys/class/gpio/gpio49/direction

For the interested - the explanation to libgpiod “misbehaving”.
https://github.com/brgl/libgpiod/issues/32#issuecomment-444802563

This is according to design - a program can control the GPIO pin as long as it keeps the ioctl socket open. The kernel kindly resets the GPIO configuration to default value when the socket is closed.

Apparently there is a daemon planned which would persist and handle requests for GPIO operations. Hmm.

While libgpiod may be a good solution in many cases, I can see a few where I’d really prefer my GPIO state to persist without keeping the ioctl socket open or running a (yet to be written) daemon dedicated to it. This makes me really sad to hear of the old sysfs interface being deprecated - I’d have to revert to poking GPIO registers directly.