Changes between Version 15 and Version 16 of gpio

08/23/2019 06:04:46 PM (3 years ago)
Tim Harvey

add details about Linux gpio character device


  • gpio

    v15 v16  
    58 = Linux GPIO =
     59= Linux GPIO
    6060[ Click here for an in depth introduction to Linux GPIO]
    62 [=#gpiolib]
    63 == gpiolib and gpio class ==
     63== chardev GPIO
     64The GPIO character device ABI (Application Binary Interface) was introduced in Linux 4.8 (which subsequently marked the User-mode sysfsgpio method deprecated). This is a 'descriptor-based' character device exposed as {{{/dev/gpiochipN}}} or {{{/sys/bus/gpiochipN}}} where N is the chip number.
     66The main feature of this new interface is a discovery mechanism which aids in having to figure out where a particular GPIO was mapped. It also supports open-drain I/O support and the ability to read and set multiple I/O lines at once. The downside to this interface is that it prevents manipulating GPIO with standard command line tools such as echo and cat.
     68Fortunately the kernel is distributed with three basic user-mode tools written for testing the interface which also show examples of the API. These can be found in the kernel source [ tools/gpio]:
     69 * lsgpio - example showing how to list the GPIO lines on a system
     70 * gpio-event-mon - example showing how to monitor GPIO line events from userspace
     71 * gpio-hammer - example swiss army knife to wiggle GPIO lines
     73Additionally [ libgpiod] provides both API calls for use in your own programs and the following user-mode apps to manipulate GPIO lines:
     74 - **gpiodetect** - list all gpiochips present on the system, their names, labels and number of GPIO lines
     75 - **gpioinfo** - list all lines of specified gpiochips, their names, consumers, direction, active state and additional flags
     76 - **gpioget** - read values of specified GPIO lines
     77 - **gpioset** - set values of specified GPIO lines, potentially keep the lines exported and wait until timeout, user input or signal
     78 - **gpiofind** - find the gpiochip name and line offset given the line name
     79 - **gpiomon** - wait for events on GPIO lines, specify which events to watch, how many events to process before exiting or if the events should be reported to the console
     81On Ubuntu {{{libgpiod}}} and its apps can be isntalled via the {{{gpiod}}} package:
     83apt install gpiod
     87 - Newport
     89root@bionic-newport:~# apt install gpiod
     91root@bionic-newport:~# gpiodetect
     92gpiochip0 [gpio_thunderx] (48 lines)
     93gpiochip1 [pca9555] (16 lines)
     94root@bionic-newport:~# gpioinfo gpio_thunderx
     95gpiochip0 - 48 lines:
     96        line   0:      unnamed       unused   input  active-high
     97        line   1:      unnamed       unused   input  active-high
     98        line   2:      unnamed       unused   input  active-high
     99        line   3:      unnamed       unused   input  active-high
     100        line   4:      unnamed  "interrupt"   input  active-high [used]
     101        line   5:      unnamed       unused   input  active-high
     102        line   6:      unnamed       unused   input  active-high
     103        line   7:      unnamed       unused   input  active-high
     104        line   8:      unnamed "mmc_supply_3v3" output active-high [used]
     105        line   9:      unnamed       unused   input  active-high
     106        line  10:      unnamed       unused  output  active-high
     107        line  11:      unnamed       unused   input  active-high
     108        line  12:      unnamed       unused   input  active-high
     109        line  13:      unnamed       unused   input  active-high
     110        line  14:      unnamed      "user2"  output  active-high [used]
     111        line  15:      unnamed       unused  output  active-high
     112        line  16:      unnamed       unused  output  active-high
     113        line  17:      unnamed       unused  output  active-high
     114        line  18:      unnamed       unused  output  active-high
     115        line  19:      unnamed       unused  output  active-high
     116        line  20:      unnamed       unused   input  active-high
     117        line  21:      unnamed       unused   input  active-high
     118        line  22:      unnamed       unused   input  active-high
     119        line  23:      unnamed       unused  output  active-high
     120        line  24:      unnamed       unused   input  active-high
     121        line  25:      unnamed       unused   input  active-high
     122        line  26:      unnamed       unused   input  active-high
     123        line  27:      unnamed       unused   input  active-high
     124        line  28:      unnamed       unused  output  active-high
     125        line  29:      unnamed       unused   input  active-high
     126        line  30:      unnamed   "pps-gpio"   input  active-high [used]
     127        line  31:      unnamed      "user1"  output  active-high [used]
     128        line  32:      unnamed       unused   input  active-high
     129        line  33:      unnamed       unused   input  active-high
     130        line  34:      unnamed       unused   input  active-high
     131        line  35:      unnamed       unused   input  active-high
     132        line  36:      unnamed       unused   input  active-high
     133        line  37:      unnamed       unused   input  active-high
     134        line  38:      unnamed       unused   input  active-high
     135        line  39:      unnamed       unused   input  active-high
     136        line  40:      unnamed       unused   input  active-high
     137        line  41:      unnamed       unused   input  active-high
     138        line  42:      unnamed       unused   input  active-high
     139        line  43:      unnamed       unused   input  active-high
     140        line  44:      unnamed       unused   input  active-high
     141        line  45:      unnamed       unused   input  active-high
     142        line  46:      unnamed       unused   input  active-high
     143        line  47:      unnamed       unused   input  active-high
     144root@bionic-newport:~# gpioget gpio_thunderx 24 # read gpio24 (DIO0)
     146root@bionic-newport:~# gpioset gpio_thunderx 24=0 # drive low gpio24 (DIO0)
     150 *
     153== User-mode GPIO class
    64154The Linux kernel can provide gpio functionality to userspace via a gpio class accessed via sysfs (/sys/class/gpio/) implemented through gpiolib (CONFIG_GPIOLIB, drivers/gpio/gpiolib*). For userspace access this requires sysfs kernel support (CONFIG_SYSFS) and the sysfs filesystem mounted which is standard for most linux systems including the Gateworks BSP's. This framework allows boards to define GPIO configuration (direction, direction-changeable, user-friendly name, state, and userspace configurable).
     156**Note that the 'sysfsgpio' API has been marked deprecated in Linux 4.8 as the new preferred API is the
    66158Note that any gpio that is registered for use by a driver is not available for exporting for userspace control. You can cat /sys/kernel/debug/gpio to see what gpio's are current registered with the kernel.
    234 == catching a GPIO change from userspace without polling using an interrupt ==
     326== Detecting GPIO changes efficiently using interrupts
     327It is extremely inefficient to have an user-mode application that continually checks a GPIO to see if it has changed value as this chews up CPU resources and increases the latency in acting on a GPIO.
     329Fortunately it is easy to write applications that utilize interrupts as long as the GPIO has an interrupt controller and handler.
     331=== chardev GPIO
     332The GPIO character device API (Application Programming Interface) introduced in Linux 4.8 provides a method of efficiently monitor for interrupt based GPIO changes. This is showing in a couple of readily available examples:
     335 * [ tools/gpio/gpio-event-mon.c gpio-event-mon.c]
     336 * [ libgpiod gpiomon]
     338=== sysfsgpio
     339**Note that the {{{sysfsgpio}}} ABI is deprecated as of Linux 4.8 and it is recommended you using the chardev based GPIO ABI instead**
    235341A gpio that has an interrupt associated with it (which depends on the gpio controller and how its hooked up to the processor) can be used with a blocking poll system call. This may seem non-intuitive that you use a 'poll' call to block until an interrupt has occurred, but that is exactly what will happen when you use poll on the sysfs 'value' file representing the value of the gpio in question. Note that even if you are not interested in the value files contents (e.g. counting the total number of interrupts caused by a gpio) you must use both an lseek and a read after poll to consume the interrupt. Otherwise the previous interrupt will cause future poll calls to immediately return.