This chapter examines GPIO driver access using the Raspbian Linux sysfs pseudo file system. Using the Raspbian driver allows even a shell script to configure, read, or write to GPIO pins.
The C/C++ programmer might be quick to dismiss this approach as too slow. But the driver does provide reasonable edge detection that is not possible with the direct register access approach. The driver has the advantage of receiving interrupts about GPIO state changes. This information can be passed onto the program using system calls such as poll(2).
/sys/class/gpio
export
unexport
Normally, the kernel manages the use of GPIO pins, especially for peripherals like the UART that need them. The purpose of the export pseudo file is to allow the user to reserve it for use, much like opening a file. The unexport pseudo file is used to return the resource back to the Raspbian kernel's care.
Exporting a GPIO
Configuring GPIO
direction: To set I/O direction
value: To read or write a GPIO value
active_low: To alter the sense of logic
edge: To detect interrupt driven changes
gpioX/direction:
The Values for the gpiox/direction file
Value | Meaning |
|---|---|
in | The GPIO port is an input. |
out | The GPIO port is an output. |
high | Configure as output and output a high to the port. |
low | Configure as output and output a low to the port. |
The cat command that follows is not necessary but verifies that we have configured gpio17 as an output.
gpioX/value
Legal values are simply are simply 1 or 0. When reading inputs, the value 1 or 0 is returned.

Raspberry Pi 3 B+ using Pi Cobbler to breadboard, with red LED wired to GPIO17 in active high configuration
gpioX/active_low
The sense of the logic has been inverted. If you change the wiring of the LED so that it corresponds to Figure 11-4 (B), writing a zero will turn on the LED. In this scenario, the sense of the logic matches the sense of the wiring.
gpioX/edge and gpioX/uevent
Some applications require the detection of changes of a GPIO. Since a user mode program does not receive interrupts, its only option is to continually poll a GPIO for a change in state. This wastes CPU resources and is like kids in the back seat of the car asking, “Are we there yet? Are we there yet?” The driver provides an indirect way for a program to receive a notification of the change.
Acceptable Values for Pseudo File Edge
Value | Meaning |
|---|---|
none | No edge detection. |
rising | Detect a rising signal change. |
falling | Detect a falling signal change. |
both | Detect a rising or falling signal change. |
Once configured, it is possible to use the uevent pseudo file to check for changes. This must be done using a C/C++ program that can use poll(2) or selectl(2) to get notifications. When using poll(2), request events POLLPRI and POLLERR. When using select(2), the file descriptor should be placed into the exception set. The uevent file is no help to the shell programmer unfortunately.
GPIO Test Script
The ~/RPi/scripts/gp test script
GPIO Input Test
- 1.
Input GPIO number (defaults to 25)
- 2.
Output GPIO number (defaults to 24)
- 3.
Active sense: 0=active high, 1=active low (default 0)
The ~/RPi/scripts/input script
Summary
This chapter has shown how to apply the sysfs driver interface to GPIO ports. While it may seem that this interface is primarily for use with shell scripts, the uevent pseudo file requires a C/C++ program to take advantage of it. These pseudo files otherwise provide a command-line interface, allowing different GPIO actions.
The next chapter will examine program access to the uevent file and explore direct access to the GPIO registers themselves.