Updated with rpi-lgpio instructions
This is a follow-on from the prior post about the ever so slightly dodgy state of userspace GPIO on the Raspberry Pi. If you want the full detail, I’d strongly recommend going and reading that article first. However, it’s in my typically waffley style, so here’s a quick-ish TL;DR for those that don’t want to wade through my excessive verbiage:
GPIO handling on Pi can be roughly split into “traditional” libraries and “new” style libraries.
“Traditional” libraries bang directly on the GPIO registers for most stuff, by-passing the kernel and hoping not to tread on other GPIO users’ toes. They also use the (long deprecated) sysfs GPIO controls for some things (usually edge-detection). “Traditional” libraries include the extremely popular RPi.GPIO, WiringPi, pigpio, the legacy RPIO, and a few others.
“New” style libraries (which include libgpiod, and the excellent lgpio) operate the GPIO pins via the kernel’s gpiochip devices (/dev/gpiochip*). This is a bit more cumbersome as applications must “reserve” the pins they want to use, and it’s slightly slower than banging on the hardware registers directly. However, it guarantees two applications can’t tread on each others toes by using the same GPIO; GPIO resources are automatically cleaned up on process termination (because the kernel knows which process is using which GPIO), and at least until now it’s also backwards compatible with the sysfs GPIO interface.
Oh, and it’s not deprecated and scheduled for removal…
The Bell Tolls
Actually, it’s been tolling for a couple of years now, but I don’t think most of the people that’ll be directly affected have actually noticed. Take a look at the section on sysfs-gpio under ABI obsolete symbols in the Linux kernel documentation and you’ll find the following:
This ABI is deprecated and will be removed after 2020. It is replaced with the GPIO character device.
Just to hammer the message home, the top of the GPIO Sysfs Interface for Userspace documentation has the following SHOUTY WARNING:
THIS ABI IS DEPRECATED, THE ABI DOCUMENTATION HAS BEEN MOVED TO Documentation/ABI/obsolete/sysfs-gpio AND NEW USERSPACE CONSUMERS ARE SUPPOSED TO USE THE CHARACTER DEVICE ABI. THIS OLD SYSFS ABI WILL NOT BE DEVELOPED (NO NEW FEATURES), IT WILL JUST BE MAINTAINED.
Though as noted above, it won’t be maintained and will be removed … erm … at some point after two years ago. As you’ve no doubt guessed it hasn’t been removed yet (because things like RPi.GPIO still operate happily), but it is nonetheless “living on borrowed time”.
Playing the Piper
As I mentioned in LP: #1918583, I didn’t think it was a good idea to go actively breaking stuff before an LTS release (Jammy, 22.04). However, now we’re coming up to the first interim release (Kinetic, 22.10) and I’m keen to see just how much pain we’re in for in the future.
To that end, the kernel team are going to disable the GPIO sysfs interface for the forthcoming 5.19 kernel. To be absolutely clear:
- This will not affect prior releases; all currently working GPIO libraries will continue to work in Jammy (22.04) and all releases before that
- This will not affect Ubuntu Core; it only uses kernels from LTS releases so again, no change (yet)
- This will break the traditional libraries (RPi.GPIO, WiringPi, et al) under Kinetic (22.10)
- This should not break gpiozero because that already uses one of the new-style libraries (specifically lgpio) by default on Ubuntu (although it falls back to RPi.GPIO if it can’t find lgpio, or if it’s been told explicitly to use another backend)
Something Must Be Done
What if it’s all a disaster, and so many things break that Something Must Be Done? There’s obvious and slightly less obvious “somethings” that we can turn to in that case:
The most obvious is “undo it”. This is just a configuration option in the kernel, and as it’s still there we could just flip it back on for 23.04 and carry on our merry way. However, that’s likely not a long term option…
Slightly less obvious: make compatibility shims. For example, if most breakage turns out to be in applications relying on RPi.GPIO, make a library with the RPi.GPIO interface which uses lgpio or libgpiod underneath.
The issue here is we need to know which libraries to shim (RPi.GPIO? WiringPi? pigpio? All of the above?), and that the shim will never be 100% perfect (if two processes rely on accessing the same GPIO, their assumptions will still be broken, and they will not work with the shim).
Even less obvious: fix the applications. If only a minority of applications break (or all that break use different pin libraries) it may be better to simply migrate those applications to a new-style library. GPIO handling is usually a minority of most applications that use it, so the patches shouldn’t be too long / hard to generate.
Obviously it’s premature to jump into some of these options, and the end result may well be a combination of some of them.
Still, I am anticipating that RPi.GPIO is likely to be one of the major sources of breakage. To that end, I’ve already worked on a simplistic shim which transforms the lgpio library into a compatible interface. It’s called rpi-lgpio and will be landing in Kinetic as the python3-rpi-lgpio package:
$ sudo apt install python3-rpi-lgpio Reading package lists... Done Building dependency tree... Done Reading state information... Done The following package was automatically installed and is no longer required: rpi.gpio-common Use 'sudo apt autoremove' to remove it. The following additional packages will be installed: liblgpio1 python3-lgpio The following packages will be REMOVED: python3-rpi.gpio The following NEW packages will be installed: liblgpio1 python3-lgpio python3-rpi-lgpio 0 upgraded, 3 newly installed, 1 to remove and 0 not upgraded. Need to get 108 kB of archives. After this operation, 365 kB of additional disk space will be used. Do you want to continue? [Y/n]
Installing this package will remove the python3-rpi.gpio package (because both define an RPi.GPIO module and so cannot co-exist) but should permit most existing applications that rely on RPi.GPIO to continue operating normally. The python3-rpi-lgpio package also “provides” (in apt parlance) python3-rpi.gpio so it can satisfy any package that “depends” on python3-rpi.gpio.
This Is Something
In the meantime, what can you do? If you’re relying on GPIO connected devices on your Pi, I would caution you not to upgrade production systems to Kinetic (22.10) when it’s released without testing them first. The simplest way to test a Raspberry Pi based setup is simply to clone the SD card and try upgrading the backup:
- Shut down your Pi
- Duplicate the SD card to another one of equal / greater size:
- Assuming you have a single SD card reader at your disposal, with the device name /dev/mmcblk0, place the “production” card in the reader
- Run sudo umount /dev/mmcblk0p1 and sudo umount /dev/mmcblk0p2 to unmount any auto-mounted partitions
- Run sudo dd if=/dev/mmcblk0 of=backup.img bs=16M status=progress
- Remove the production card
- Insert the blank card
- Run sudo dd if=backup.img of=/dev/mmcblk0 bs=16M status=progress
- Run sudo sync just to make sure and remove the cloned card
- Plug the duplicated SD card back into your Pi and boot it up
- Run through the upgrade to Kinetic: sudo do-release-upgrade --devel
- See what breaks!
- If nothing breaks, great!
- If something breaks, file bugs!
- File against the application itself if it’s from an Ubuntu package
- File against the GPIO library (e.g. file a bug against RPi.GPIO on Ubuntu) it’s using if the application isn’t from an Ubuntu package, and you happen to know which GPIO library is being used
- File against Ubuntu generally if the application isn’t from an Ubuntu package, and you’ve no idea which GPIO library is being used
- In any of the cases above, tag the bug raspi-image and it should get my attention
In the meantime, I’m keen to hear thoughts and/or suggestions about the forthcoming GPIO apocalypse changes.