Implementation of a user space interface for GPIO interrupts

Project description

FreeBSD already has support for interrupts implemented in the GPIO controller drivers of several SoCs, but there are no interfaces to take advantage of them out of user space yet. The goal of this project is to implement such an interface by providing descriptors which integrate with the common I/O system calls and multiplexing mechanisms.

Approach to solving the problem

Writing a kernel driver that sets the interrupts up and controls the interrupt related resources. Furthermore, the driver provides a handler function for the interrupts which serves the file descriptors. A user space API to create and configure those descriptors must also be implemented (ideally these functions would be integrated into libgpio and gpioctl). These API should allow the configuration of interrupt specific attributes like trigger-type. To conclude, some hardware tests shall be done on SoCs that support GPIO generated interrupts.

Upon suggestion of my mentors the major part of the kernel functionality was integrated in the already existing gpioc driver. This allows to use the already existing functions for interrupt configuration of libgpio to set and retrieve the configuration flags. The gpioctl utility was updated in order to be able to print the interrupt capabilities and flags.


Test Plan

Hardware tests should be done on the BeagleBone Black (TI Sitara AM3359) and RaspberryPi 3 (Broadcom BCM2837), because their SoCs support interrupts along with the gpiobus driver.

Initially it should be sufficient to wire simple push buttons to the GPIO pins, or to connect them to each other with a simple delay circuit. When everything works fine so far, I am planning to do some more advanced hardware tests e. g. by connecting a Microcontroller for automated long-term scenarios, or even by generating some stress on the pins.

The Code

The source code of the kernel driver can be found in my fork of the FreeBSD src tree on GitHub. The utilities for configuration and testing are located in this repository.



Usage of the code is quite simple. First of all, get a handle to the appropriate gpioc device via the gpio_open or gpio_open_device functions of gpio(3). After that set the configuration with an interrupt flag using gpio_pin_config on any pin(s) which should be monitored. The interrupt flags are declared in sys/gpio.h. Please note, that only pins configured as input can utilize interrupt capabilities and only one interrupt flag per pin can be set at once. After configuring the pin(s) with an interrupt flag, simply call read(2) or any other I/O multiplexing syscall on the handle. You can also take a look at gpioc_intr_test of the utilities repository.

Possible further improvements

Questions asked regarding this project

SummerOfCode2018Projects/UserSpaceGPIOinterrupts (last edited 2018-08-14T14:37:58+0000 by ChristianKraemer)