libgpiod는 리눅스 유저 스페이스(Linux userspace)가 GPIO character device를 통해 GPIO 라인과 상호작용하게 하는 C 라이브러리, 언어 바인딩 및 명령줄 도구입니다.
이 글은 libgpiod 공식 문서와 Linux 커널 GPIO 문서를 2026-09-01 기준으로 정리한 일반 설명이며, 커널 및 라이브러리 버전에 따라 세부 동작은 달라질 수 있습니다.
libgpiod는 무엇인가?
한 줄 답: 이 프로젝트는 ioctl 기반 GPIO character device 접근을 C 라이브러리, 언어 바인딩, 명령줄 도구로 감싸며, 유저 스페이스의 기본 단위로 Chip과 Line Request를 사용합니다.
기존의 GPIO sysfs 인터페이스는 커널에서 deprecated된 이전 경로이며, GPIO character device는 Linux 커널 4.8에 도입된 더 유연하고 효율적인 경로입니다. 디바이스 파일 디스크립터를 닫으면 이 인터페이스가 할당한 자원이 안전하게 해제되며, 신뢰할 수 있는 이벤트 polling, 여러 값의 동시 읽기 및 설정, open-source와 open-drain GPIO 같은 고급 기능도 제공합니다.
커널 userspace API에서 Chip은 /dev/gpiochipX로 노출되는 GPIO 컨트롤러 객체입니다. 각 Chip은 chip.lines개의 라인을 가지며, 라인은 0부터 chip.lines - 1까지의 offset으로 식별합니다. 라인을 Chip에서 요청하면 Line Request가 만들어지고, 유저 스페이스는 그 요청을 통해 라인 값에 접근하거나 edge event를 감시합니다.
공식 문서에는 고수준 언어 바인딩, D-Bus 인터페이스, 테스트 항목도 포함되지만, 이 글의 주 경로는 C API와 명령줄 도구입니다. 이 프로젝트는 일반 명령줄 도구만으로 다루기 번거로운 ioctl 기반 커널-유저 스페이스 상호작용을 편의 함수와 불투명 자료구조로 깔끔하게 감쌉니다.
디바이스 트리는 핀을 설명하고, 이 라이브러리는 유저 스페이스에서 라인을 요청합니다. 관련 배경은 디바이스 트리에서 확인할 수 있습니다.
임베디드 시스템이란은 보드를 전용 컴퓨터로 보는 맥락만 연결하며, 이 글에서는 그 정의를 다시 다루지 않습니다.
sysfs GPIO와 무엇이 다른가?
한 줄 답: 신규 유저 스페이스 개발에는 전역 번호를 사용하는 obsolete sysfs보다 Chip과 offset을 사용하는 GPIO character device를 선택해야 합니다.
이전 sysfs 경로는 /sys/class/gpio/ 아래에서 export와 unexport를 사용하고, 개별 라인을 /sys/class/gpio/gpioN/과 전역 GPIO 번호로 표현했습니다. 반면 character device 경로는 /dev/gpiochipX라는 Chip과 그 안의 라인 offset을 함께 사용합니다.
커널 문서는 sysfs userspace API를 GPIO Character Device Userspace API로 대체된 obsolete 인터페이스로 설명합니다. 이전 경로는 마이그레이션 기간 동안 유지되지만 새 기능은 character device API에만 추가되며, 신규 개발은 새 API를 사용하고 기존 개발도 가능한 한 마이그레이션해야 합니다.
character device는 이벤트 polling, 여러 라인의 값을 한 번에 읽고 설정하는 기능, open-source·open-drain 같은 전기적 구성, 디바이스 파일 디스크립터를 닫을 때의 자원 정리를 제공합니다. 따라서 sysfs의 전역 번호와 파일별 상태 항목을 새 userspace 모델의 기준으로 삼아서는 안 됩니다.
Character Device v1도 obsolete userspace API에 포함되므로, 이 글에서 설명하는 현재 경로는 kernel userspace API v2입니다. v2는 Linux 커널 5.10에 처음 추가되었으며, 커널 driver API의 gpio_chip 내부 구현은 여기서 다루지 않습니다.
라인을 요청하고 읽고 쓰는 법은?
한 줄 답: gpiodetect와 gpioinfo로 대상을 확인한 뒤 라인을 요청하고, gpioget 또는 gpioset으로 읽거나 설정하며, 요청 수명 안에서만 제어 권한을 유지합니다.
gpiodetect는 시스템의 GPIO Chip, 이름, label, 라인 수를 나열합니다. gpioinfo는 Chip, offset, 라인 이름, direction을 보여 주고, 사용 중인 라인이라면 consumer와 active state, bias, drive, edge detection, debounce period 같은 구성 속성도 보여 줍니다. gpioget은 지정한 라인의 값을 읽고, gpioset은 지정한 라인의 값을 설정합니다.
라인은 이름으로 지정할 수 있고, Chip을 -c 또는 --chip으로 제한한 경우에는 offset으로도 지정할 수 있습니다. gpioget의 --numeric은 값을 비활성 0 또는 활성 1로 표시합니다. gpiomon과 gpionotify도 각각 edge event와 정보 변경을 기다리는 도구로 존재하지만, 기본 경로는 detect·info·get·set입니다.
gpioset은 프로세스가 종료되거나 중단될 때까지 요청한 라인을 잡고 값을 유지합니다. 프로세스가 종료되면 요청한 라인은 자동으로 해제되고 커널이나 다른 프로세스가 상태를 바꿀 수 있으므로, 종료 뒤에도 값이 유지된다고 가정할 수 없습니다. 요청한 값을 보장하기 위해 기본적으로 종료하지 않는 동작을 사용합니다.
다음은 공식 문서에 제시된 명령 예입니다. 문서의 예시에는 Raspberry Pi 4B가 언급되지만, 이 글의 보드 실측이나 보편적인 핀맵을 뜻하지 않습니다.
$ gpioget -c 0 15
$ gpioset GPIO23=1
C API에서는 gpiod_chip_open(path)으로 Chip을 열고 gpiod_chip_close(chip)으로 닫습니다. gpiod_chip_request_lines(chip, req_cfg, line_cfg)은 라인 묶음의 배타적 사용을 요청하며, req_cfg는 기본 설정을 위해 NULL일 수 있지만 line_cfg는 필요합니다. 반환된 Line Request는 gpiod_line_request_release(request)로 해제해야 합니다.
요청을 얻은 뒤 gpiod_line_request_get_value(request, offset)은 단일 라인 값을 성공 시 1 또는 0으로 반환하고 오류 시 -1을 반환합니다. gpiod_line_request_set_value(request, offset, value)는 성공 시 0, 실패 시 -1을 반환하며, 모든 요청 라인의 값을 다루는 gpiod_line_request_get_values와 gpiod_line_request_set_values도 제공됩니다.
커널 수준에서는 GPIO_V2_GET_LINE_IOCTL이 Line Request를 만들고, 그 요청 파일 디스크립터에서 라인 값을 읽고 설정하는 방식으로 대응합니다. 적절한 커널 드라이버가 있는 하드웨어는 userspace API로 직접 제어하지 않아야 합니다.
칩과 라인은 어떻게 고르나?
한 줄 답: Chip은 번호, 이름, 장치 경로로 식별하고, 선택한 Chip 안의 라인은 이름을 우선 확인한 뒤 필요하면 해당 Chip의 offset으로 지정합니다.
GPIO Chip은 번호, 이름, 경로로 식별할 수 있습니다. 예를 들어 0, gpiochip0, /dev/gpiochip0은 같은 Chip을 가리킬 수 있습니다. gpiodetect는 Chip의 label과 라인 수를 출력하고, 인자를 지정하지 않으면 시스템의 모든 Chip을 나열합니다.
gpioinfo는 라인의 Chip, offset, name, direction을 확인하는 데 사용하며, 사용 중이면 consumer와 active state, bias, drive, edge detection, debounce period 같은 속성도 표시합니다. 라인 이름을 지정하는 방식이 읽기 쉽고, 특정 Chip을 --chip으로 제한한 명령에서는 offset을 사용할 수 있습니다.
라인 offset의 유효 범위는 0부터 chip.lines - 1까지입니다. C helper인 gpiod_chip_get_line_offset_from_name(chip, name)은 라인 이름을 offset으로 매핑하며, 이름을 찾지 못하면 -1을 반환하고 errno를 ENOENT로 설정합니다.
다음 출력은 공식 문서의 Raspberry Pi 4B 작성 예시입니다. pinctrl-bcm2711이나 raspberrypi-exp-gpio를 모든 보드에서 쓰는 Chip 이름으로 해석해서는 안 됩니다.
$ gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)
FAQ
한 줄 답: 권장 userspace 인터페이스, sysfs의 상태, Chip 선택 방식, gpioset 종료 뒤의 수명을 구분하면 기본 사용 경로를 판단할 수 있습니다.
리눅스 유저 스페이스에서 GPIO 라인을 다루려면 무엇을 사용합니까?
GPIO character device와 이 라이브러리의 C API 또는 명령줄 도구를 사용합니다. Chip을 확인하고 라인을 요청한 뒤 값을 읽거나 설정하는 흐름입니다.
sysfs /sys/class/gpio는 아직 사용합니까?
마이그레이션 기간에는 유지되지만 obsolete 인터페이스입니다. 신규 개발은 GPIO character device userspace API를 사용해야 합니다.
Chip은 어떻게 고릅니까?
번호, 이름, 경로 중 하나로 고를 수 있으며, 0, gpiochip0, /dev/gpiochip0처럼 같은 Chip을 서로 다른 표기로 지정할 수 있습니다.
gpioset을 종료하면 라인 값이 유지됩니까?
보장되지 않습니다. 프로세스가 종료되면 요청한 라인이 자동으로 해제되어 커널이나 다른 프로세스가 상태를 변경할 수 있습니다.
출처
한 줄 답: 본문은 2026-09-01 기준으로 확인한 프로젝트 공식 문서와 Linux 커널 GPIO 문서만 근거로 사용합니다.
- 프로젝트 개요 — C 라이브러리, 언어 바인딩, 명령줄 도구의 범위, sysfs 대체, character device의 목적과 특성을 설명합니다.
- Command-line tools, gpiodetect, gpioinfo, gpioget, gpioset — 도구 역할과 공식 명령 예를 확인할 수 있습니다.
- Core chips API, Line request API — Chip 열기, 라인 요청, 값 읽기, 쓰기 및 해제를 설명합니다.
- GPIO character device, Sysfs Interface, Obsolete GPIO interfaces, GPIO driver API hub — kernel userspace 경로와 obsolete 상태를 확인할 수 있습니다.
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.
'임베디드' 카테고리의 다른 글
| journalctl 사용법, 서비스 로그를 어떻게 필터하나 (0) | 2026.09.20 |
|---|---|
| Linux perf, 핫스팟을 프로파일하는 법 (1) | 2026.09.19 |
| Kconfig, 커널 옵션을 메뉴에서 고르는 법 (0) | 2026.09.16 |
| UUU 명령 하나로 eMMC 파형과 드라이버 코드까지 연결해 보기 (0) | 2026.09.14 |
| Device Tree와 Linux 플랫폼 드라이버 작성 입문 (0) | 2026.09.14 |
