Home > Fedora, Linux, Software management, Video > Learn More About Linux’s New GPIO User Space Subsystem & Libgpiod

Learn More About Linux’s New GPIO User Space Subsystem & Libgpiod

Sysfs was used to control GPIOs on Linux system with the GPIOs defined in /sys/class/gpio, but starting with Linux 4.8, a new GPIO interface for user space was introduced, with gpiochip becoming char devices foudn in /dev/gpiochip0, dev/gpiochip1, etc.. , and sysfs allegedly become deprecated.

But a quick check in NanoPi Duo with Linux 4.11 shows both GPIO user space interfaces appear to be enabled:

Nevertheless overtime, sysfs will die out, and the new subsystem will likely be used by all systems, so it might be useful to learn more about it.

One way to do that is to watch Bartosz Golaszewski’s ELCE 2017 talk entitled “New GPIO Interface for User Space” with the video embedded below. But I first I’ll summarize some of the key points.

Now GPIO handling from user space becomes similar to other char driver with ioctl, poll and read functions, and beside assigning numbers to GPIOs you can assign names. The API (in linux/gpio.h) provides access to chip info, line info, line request for values, reading values, settings values, line request for events (rise/falling edges), polling for events, and reading events. Bartosz goes into details for each function in his talk.

Since the kernel API is a bit complicated to use, there’s also a C library called libgpiod, which comes with some tools like gpiodetect, gpioinfo, gpioset, gpioget, gpiofind & gpiomon. Further work includes C++ and Python bindings, as well as a GPIO daemon and client. Example code for libgpiod:

Some example of user space tools found in libgpiod:

The first command return the list of gpio chips, their names, and number of lines, the second set the 3rd pin of Chip 1 to high, the third return the values of 5 different pins, and the last one monitor a pin to detect an event and return the time when it happened.

You can check out the latest libgpiod source code, or download the latest stable release of the code as a tarball. libgpiod is already available in meta-openembedded & buildroot, and packaged in Fedora and Arch Linux.

You may also be interested in the slides.

  1. danman
    November 3rd, 2017 at 18:05 | #1

    I guess the speed will be much higher than using sysfs. Could you do some comparison?

  2. RK
    November 3rd, 2017 at 22:58 | #2


    There’s little point to benchmarking performance seeing how the previous interface was dropping events while context switching left and right.

    I just wish they could have used a more human-friendly protocol so we could script without having to use a C library or a user-space program.

  3. bob
    November 4th, 2017 at 02:34 | #3

    Cool improvement i like event triggering and call by name, C library well documented.
    But i didn’t see any interrupt on change

  4. November 4th, 2017 at 16:27 | #4

    I was in the room in Prague last week.

    He should really change the name of this package, it contains a library, but also userspace tools. This is really confusing.

    But this new char device could open the way to faster gpio access, like for JTAG-over-GPIO interfaces, which are now only available to Raspberrypi devices in openocd but this is specific to bcm2835 chips, not portable to allwinner or any other devices. Now let’s hope someone writes a proper driver for openocd for that purpose. Those Allwinner OrangePi zero are so cheap that it does not make sense bothering with FTDI dongles anymore. Urjtag and openocd also have sysfs cable support, but they are much slower.

  5. RK
    November 4th, 2017 at 18:34 | #5


    I think many JTAGs are timing sensitive so the scheduling (not real time) will still be a blocker for most.

  6. tkaiser
    November 4th, 2017 at 19:47 | #6

    If applying PREEMPT_RT patch is sufficient then it’s easy to use those inexpensive Allwinner thingies for this purpose: https://forum.armbian.com/topic/5576-fully-preemptible-kernels/

  7. RK
    November 5th, 2017 at 05:08 | #7


    Yeah the preempt patches combined with this should work better on 1:1 instructions-to-cycles cores like older ARMs and current MIPS. Though I suspect you’d still need to dedicate a core to the thread and run the system under a fairly embedded rootfs since many linux daemons tend to fork like crazy and real time scheduling means losing cycles like there’s no tomorrow over this.

    But hey, if people are using RasPi’s GPIOs to R\W EEPROMs, I’m sure there’s a lot of diagnostic jtags you can make due with.

  8. tkaiser
    November 5th, 2017 at 19:09 | #8

    FEL booting Allwinner devices via the USB OTG port works really nice. We added this to Armbian’s build system last year (FEL+NFS, everything set up automatically) and I do ‘full OS image’ testing since 18 months with zero delay and no SD cards harmed ๐Ÿ˜‰

  9. January 28th, 2018 at 01:03 | #9

    I’ve created a github project called libgpiod-extra that automates the build process on Armbian and generates Python bindings. Only a couple of distributions include this currently, so you have to build it. I also included instructions to built it manually, then you can generate the Python bindings. No need to wait for the official release!


  10. February 19th, 2018 at 01:44 | #10


    After a lot of work and testing I have produced the User Space IO project! It provides Python 3 and Java 8 bindings for Linux user space GPIO, SPI, I2C and Serial interfaces. This allows cross SBC and cross language development using a common API. I took two best of breed C APIs for Linux user space libgpiod and c-periphery and produced CFFI bindings for Python and JNA bindings for Java. Since all the bindings closely match the C API it’s easy to move from language to language. The side effect of using the Java library is that it should work with many different JVM based language. How about creating your programs in Kotlin or Scala for instance?

    GPIO access uses the new gpiod interface and not the deprecated sysfs interface using libgpiod v1.1 (head from git repo). GPIO, SPI, I2C and serial interfaces expose all the low level functionality, but I have added some helper methods for handling repetitive functions like building I2C messages, reading words from two registers, etc. You can of course go as low level as you need to. Please use Github to post any issues, pull requests, etc. I have tested Nano Pi Duo for 32 bit and NanoPi Neo +2 for 64 bit compatibility. I’ll test more SBCs as I have time. Also, I have deleted https://github.com/sgjava/libgpiod-extra since User Space IO supersedes it.

  1. No trackbacks yet.