Open mryall-mawson opened 8 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.
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:
sysfs::export_gpio_if_unexported()
updates the/sys/class/gpio/export
file, which results in the kernel kicking off a udev rule in user-space to generate the files under/sys/class/gpio{pin}
, like/sys/class/gpio{pin}/value
sysfs::open_gpio()
for an output pin will create or truncate/sys/class/gpio{pin}/value
(usingfs::File::create
) so it has a filehandle to return in theSysFsGpio
struct.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.