mbr / gpio-rs

Rust GPIO library supporting bare metal and Linux.
MIT License
20 stars 3 forks source link

Setting GPIO output pin high sometimes doesn't work for unexported pins #9

Open mryall-mawson opened 6 months ago

mryall-mawson commented 6 months ago

Using gpio-rs to open an output GPIO pin and set it high, when it is not yet exported, sometimes doesn't update the pin state to high. I believe this is due to a race condition in the library.

If a pin is opened for output but is not yet exported, this library attempts to export it first, which results in two tasks running in parallel:

Because the udev file creation and the open_gpio() file creation run concurrently, the file that the library creates and grabs a handle to may not be the same as the one the sysfs subsystem ends up monitoring for changes.

We have fixed this in our code by replicating the logic from the library and adding 100ms sleeps after all the file system operations that touch anything in /sys/class/gpio. This is not ideal, but we haven't yet found a way to deterministically know when the udev updates from the export are complete.

Note: I realised sysfs GPIO ABI is deprecated, but we are stick with it on an old version of Linux in a legacy embedded system.

mryall-mawson commented 6 months ago

There are quite a few references to this race condition in exporting GPIO pins on Linux in other places on the internet, such as this question on StackOverflow, and this answer.

So this is not a unique bug in this library, but it is something which can't be worked around by a user, because the export logic is baked into the open code.