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

703 views
Skip to first unread message

Ken Shirriff

unread,
Dec 2, 2018, 9:42:30 PM12/2/18
to BeagleBoard
/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

Robert Nelson

unread,
Dec 2, 2018, 10:40:51 PM12/2/18
to Beagle Board

Ken Shirriff

unread,
Dec 3, 2018, 1:35:22 AM12/3/18
to BeagleBoard
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

Tarmo Kuuse

unread,
Dec 20, 2018, 1:04:17 PM12/20/18
to BeagleBoard
On Monday, 3 December 2018 08:35:22 UTC+2, Ken Shirriff wrote:
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.

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?

--
Kind regars,
Tarmo 

Tarmo Kuuse

unread,
Dec 20, 2018, 1:17:45 PM12/20/18
to BeagleBoard
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

--
Kind regards,
Tarmo Kuuse

Tarmo Kuuse

unread,
Jan 7, 2019, 4:39:46 AM1/7/19
to BeagleBoard
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.
Reply all
Reply to author
Forward
0 new messages