libgpiod
libgpiod provides the userspace C library, language bindings, and command-line tools for interacting with GPIO lines through Linux’s GPIO character device.
This article summarizes the official libgpiod documentation and Linux kernel GPIO pages as of 2026-09-01; details may differ by kernel and library version.
What role does the library play in Linux GPIO access?
One-line answer: The project wraps ioctl-based character-device access in a C library, language bindings, and command-line tools, with a chip and a line request forming the basic userspace model.
The older GPIO sysfs interface is deprecated in the kernel. The GPIO character device, introduced in Linux 4.8, provides a more flexible and efficient route; closing its device-file descriptor safely frees the resources allocated through that interface. It also supports reliable event polling, multi-line reads and writes, and configurations such as open-source and open-drain GPIOs.
In the kernel userspace model, a Chip is exposed as /dev/gpiochipX. Each Chip has chip.lines GPIO lines, identified by offsets from 0 through chip.lines - 1. Requesting lines from a Chip creates a Line Request, which then provides access to the requested values or to edge-event monitoring.
The official project documentation also lists high-level language bindings, a D-Bus interface, testing, and other project areas. This article focuses primarily on the C API and command-line tools, which hide the cumbersome ioctl-based kernel-to-userspace interaction behind convenient functions and opaque data structures.
Device Tree describes pins, whereas this interface requests lines from userspace; further context is available in Device Tree.
The broader embedded-systems context is covered by What is an embedded system?, where a board is treated as a dedicated computer.
Why is the character device preferred over sysfs GPIO?
One-line answer: New userspace development should use the chip-and-offset character-device model instead of the obsolete sysfs interface, which is based on global GPIO numbers.
The former sysfs layout used /sys/class/gpio/, write-only export and unexport files, and per-line paths such as /sys/class/gpio/gpioN/. The character-device layout instead combines a Chip such as /dev/gpiochipX with an offset belonging to that Chip.
The kernel documentation marks the sysfs userspace API as obsoleted by the GPIO Character Device Userspace API. It remains maintained during migration, but new features are added only to the newer API; new work should adopt it, and existing work is encouraged to migrate because the old interface is scheduled for removal.
The character device adds reliable event polling, simultaneous access to multiple line values, open-source and open-drain modes, and resource cleanup tied to closing the device descriptor. These are differences in the userspace interface, not a reason to reproduce the old export procedure.
Character Device v1 is obsolete as well. The current kernel userspace path discussed here is kernel userspace API v2, first added in Linux 5.10; kernel-side driver structures are outside the scope of this article.
What is the request-to-value workflow?
One-line answer: Discover the Chip, inspect its lines, make a request, read or set values through that request, and release it when the owning operation ends.
gpiodetect lists the GPIO Chips present, including their names, labels, and line counts. gpioinfo reports each line’s Chip, offset, name, and direction, plus the consumer and attributes such as active state, bias, drive, edge detection, and debounce period when relevant. gpioget reads specified line values, while gpioset assigns them.
Lines may be named directly; an offset may be used when the command is restricted to a Chip with -c or --chip. The --numeric option for gpioget renders inactive and active values as 0 and 1. gpiomon and gpionotify are also available for waiting on edge events and information changes, but detect, info, get, and set are the main tools discussed here.
gpioset holds its line request while the process runs. Once the process exits, its requested lines are released automatically, and the kernel or another process may change their state. The value, therefore, is not guaranteed after exit; by default, the tool does not exit so that the requested value can be maintained while it owns the line.
The following commands are examples from the official documentation. The page notes that its examples were created using a Raspberry Pi 4B; they are documentation examples, not measurements or a universal board pin map for this article.
$ gpioget -c 0 15
$ gpioset GPIO23=1
In the C API, gpiod_chip_open(path) opens a Chip and gpiod_chip_close(chip) closes it. gpiod_chip_request_lines(chip, req_cfg, line_cfg) requests a set of lines for exclusive use; req_cfg may be NULL for defaults, while line_cfg is required. The returned Line Request must be released with gpiod_line_request_release(request).
gpiod_line_request_get_value(request, offset) returns 1 or 0 on success and -1 on error. gpiod_line_request_set_value(request, offset, value) returns 0 on success and -1 on failure. The corresponding gpiod_line_request_get_values and gpiod_line_request_set_values functions handle all requested lines together.
At the kernel boundary, GPIO_V2_GET_LINE_IOCTL creates the Line Request, and the request file descriptor is then used to get or set line values. Hardware that already has an appropriate kernel driver should not be controlled directly through a userspace GPIO API.
How do chip identity and line names fit together?
One-line answer: Select a Chip by number, name, or device path, then identify one of its lines by name or by an offset within that Chip.
A GPIO Chip can be written as a number, a name, or a path. For example, 0, gpiochip0, and /dev/gpiochip0 can all refer to the same Chip. With no Chip argument, gpiodetect lists every available Chip and prints its label and line count.
Use gpioinfo to inspect the Chip, offset, name, direction, consumer, and configured attributes for its lines. A line name is usually the clearest identifier; an offset is available when a particular Chip is selected with --chip.
Valid offsets run from 0 through chip.lines - 1. The C helper gpiod_chip_get_line_offset_from_name(chip, name) maps a line name to its offset and returns -1 and sets errno to ENOENT when the name cannot be found.
The output below is an official documentation example created using a Raspberry Pi 4B. Names such as pinctrl-bcm2711 and raspberrypi-exp-gpio must not be treated as universal Chip names.
$ gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)
FAQ
One-line answer: The practical decisions are which userspace interface to use, how sysfs is classified, how a Chip is named, and what happens when a setting process ends.
What should be used in userspace to work with GPIO lines?
Use the GPIO character device together with the library’s C API or command-line tools: discover a Chip, request lines, and then read or set their values.
Is /sys/class/gpio still the recommended interface?
No. It remains available during migration but is obsolete, so new development should use the GPIO Character Device Userspace API.
How can a GPIO Chip be selected?
Use its number, name, or path. The forms 0, gpiochip0, and /dev/gpiochip0 can identify the same Chip.
Does a line keep its value after gpioset exits?
It is not guaranteed. Process exit releases the requested line, after which the kernel or another process may change its state.
Sources
One-line answer: The article relies only on the official project documentation and Linux kernel GPIO pages verified as of 2026-09-01.
- Project overview — Covers project scope, the sysfs transition, and the purpose and features of the character-device path.
- Command-line tools, gpiodetect, gpioinfo, gpioget, and gpioset — Provides tool roles and documented command examples.
- Core chips API and Line request API — Explain opening Chips, making requests, reading and setting values, and releasing resources.
- GPIO character device, Sysfs Interface, Obsolete GPIO interfaces, and GPIO driver API hub — Detail the kernel userspace path and obsolete status.