GPIOD Usage

GPIOD Introduction

Since Linux 4.8, the GPIO sysfs interface has been deprecated. User space should use libgpiod to interact with GPIO character devices instead.

libgpiod is a C library and toolset for Linux GPIO character devices (/dev/gpiochipX), providing a modern GPIO operation interface.

Main Features

  • Simple and Easy to Use: libgpiod provides a concise API that makes controlling and operating GPIO devices simple and understandable. Developers only need to understand basic GPIO concepts and function interfaces to use it.
  • Independence: libgpiod is an independent user-space library that does not depend on any specific hardware platform or chip. It is suitable for various embedded platforms that support GPIO control, such as Radxa ROCK series, Raspberry Pi, BeagleBone, etc.
  • Support for Multiple Programming Languages: libgpiod natively supports C language, and also provides Python bindings (python3-libgpiod) and wrappers for other languages, making it convenient to use in different programming languages.
  • Efficient Event Monitoring: libgpiod provides functions for asynchronous event monitoring, such as waiting for GPIO state changes. This allows developers to implement efficient event-driven applications.
  • GPIO Specification Support: libgpiod provides support for different GPIO specifications and numbering methods, including both GPIO number-based and physical pin number-based approaches.

Installing libgpiod

Install Command Line Tools

sudo apt update
sudo apt install gpiod -y

Install Development Library (for C Programming)

sudo apt install libgpiod-dev -y

Install Python Bindings

sudo apt install python3-libgpiod -y

Verify Installation

# Check version (Quectel Pi H1 uses 2.2.1)
apt list --installed | grep gpiod

# View available GPIO chips
gpiodetect

Note: Quectel Pi H1 uses libgpiod 2.2.1, which is not compatible with version 1.x syntax.

Command Line Tools

libgpiod provides command line tools for viewing and controlling GPIO devices.

Prerequisites: Ensure that the gpiod toolkit is installed (sudo apt install gpiod -y)

gpiodetect

List all GPIO controllers in the system:

gpiodetect

Example Output:

gpiochip0 [gpio0] (32 lines)
gpiochip1 [gpio1] (32 lines)
gpiochip2 [gpio2] (32 lines)
gpiochip3 [gpio3] (32 lines)
gpiochip4 [gpio4] (128 lines)

Tip: Quectel Pi H1 primarily uses gpiochip4.

gpioinfo

Display GPIO device information:

# View information for all GPIO chips
gpioinfo

# View information for a specific chip (using grep filter)
# Note: Quectel Pi H1's gpiochip4 has 176 lines, adjust the number as needed
gpioinfo | grep -A 180 "gpiochip4"

libgpiod Version Differences:

  • Version 1.x: Supports gpioinfo /dev/gpiochip4 syntax
  • Version 2.x: Only supports gpioinfo to view all, need to use grep to filter specific chips

Example Output (Quectel Pi H1 actual output):

gpiochip4 - 176 lines:
        line   0:       unnamed                 input
        line   1:       unnamed                 input
        line   2:       unnamed                 output active-low consumer=perst
        ...
        line  36:       unnamed                 output
        line  37:       unnamed                 input
        ...
        line  77:       unnamed                 input
        ...
        line  91:       unnamed                 input active-low consumer=cd
        ...

Field Descriptions:

  • unnamed: Pin is unnamed (default state for Quectel Pi H1)
  • input/output: Pin direction
  • consumer=xxx: Pin is occupied by some function (such as consumer=perst, consumer=cd)
  • active-low: Active low

Note:

  • GPIO pins on Quectel Pi H1 default to unnamed (unnamed)
  • Pins marked with consumer= are being used by other functions and cannot be directly used as GPIO
  • gpiochip4 has 176 lines

gpiofind (Removed)

Important Note: The gpiofind command has been removed in libgpiod 2.x versions.

Quectel Pi H1 uses libgpiod 2.x, and all GPIO pins default to unnamed (unnamed). You need to directly use the chip name and pin number for operations.

View Pin Information:

# View detailed information for a specific pin
gpioinfo | grep "line  77"

# View pins in a range
gpioinfo | grep -E "line  (77|78|79)"

gpioget

Read GPIO input:

# Read pin 77 of gpiochip4 (must use -c option to specify chip)
gpioget -c gpiochip4 77

# Can also use chip number
gpioget -c 4 77

# Or use full path
gpioget -c /dev/gpiochip4 77

Example Output (libgpiod 2.x):

"77"=inactive
  • inactive indicates low level (0)
  • active indicates high level (1)

If numeric format output is needed:

# Use --numeric option to output 0/1
gpioget -c gpiochip4 --numeric 77

gpioset

Set GPIO output:

Important Note (libgpiod 2.x):

  • By default, gpioset will continuously maintain the set level until the program is terminated (Ctrl+C)
  • After the program exits, the GPIO state is determined by hardware and is not guaranteed to be maintained
  • Must use -c option to specify chip

Basic Usage (Continuous State):

# Set GPIO77 to high level (continuously maintained, press Ctrl+C to stop)
gpioset -c gpiochip4 77=1

# Set to low level
gpioset -c gpiochip4 77=0

# Can also use active/inactive
gpioset -c gpiochip4 77=active
gpioset -c gpiochip4 77=inactive

# Or use on/off
gpioset -c gpiochip4 77=on
gpioset -c gpiochip4 77=off

Set Multiple Pins:

# Set multiple pins simultaneously
gpioset -c gpiochip4 16=1 17=0

Set and Exit After Delay:

# Set high level and maintain for 5 seconds then exit
gpioset -c gpiochip4 -p 5s 77=1

# Maintain for 100 milliseconds then exit
gpioset -c gpiochip4 -p 100ms 77=1

Background Running (Daemon Mode):

# Set and run in background
gpioset -c gpiochip4 -z 77=1

gpiomon

Monitor GPIO events:

# Basic usage: Monitor GPIO77 state changes (default monitors both edges)
gpiomon -c gpiochip4 77

# Specify edge type to monitor
gpiomon -c gpiochip4 -e rising 77     # Only monitor rising edge
gpiomon -c gpiochip4 -e falling 77    # Only monitor falling edge
gpiomon -c gpiochip4 -e both 77       # Monitor both edges (default)

# Display banner information
gpiomon -c gpiochip4 --banner 77

# Limit number of events (exit after monitoring 10 events)
gpiomon -c gpiochip4 -n 10 77

# Set idle timeout (exit if no events within 5 seconds)
gpiomon -c gpiochip4 --idle-timeout 5s 77

# Add debounce (10ms debounce period)
gpiomon -c gpiochip4 -p 10ms 77

Usage Example:

  1. Run gpiomon -c gpiochip4 77
  2. Connect Pin7 (GPIO77) to GND or 3.3V with a jumper wire
  3. Observe event information output in the terminal
  4. Press Ctrl+C to stop monitoring

Example Output (libgpiod 2.x):

event:  RISING EDGE offset: 77 timestamp: [    1234.567890123]
event: FALLING EDGE offset: 77 timestamp: [    1234.678901234]

Custom Output Format:

# Use formatted output
gpiomon -c gpiochip4 --format "Line %o: %E edge at %S" 77

# Example output:
# Line 77: rising edge at 1234.567890123
# Line 77: falling edge at 1234.678901234

GPIO Pin Mapping

Quectel Pi H1 primarily uses /dev/gpiochip4 for GPIO control.

40Pin Common Pin Mapping

Physical Pin Pin Name GPIO Number GPIO Chip libgpiod Usage Default Function
Pin3 NFC_I2C_SDA GPIO36 gpiochip4 gpiochip4 36 I2C09_SDA
Pin5 NFC_I2C_SCL GPIO37 gpiochip4 gpiochip4 37 I2C09_SCL
Pin7 CAM2_RST GPIO77 gpiochip4 gpiochip4 77 GPIO
Pin11 GPIO_16 GPIO16 gpiochip4 gpiochip4 16 GPIO/SPI/UART/I2C
Pin13 GPIO_17 GPIO17 gpiochip4 gpiochip4 17 GPIO/SPI/UART/I2C

Note: Pin3 and Pin5 are configured as I2C9 interface by default. If you need to use them as GPIO, please ensure no other devices are occupying them.

For complete pin mapping, please refer to: 40Pin Function Testing

View Pin Status

Use gpioinfo to view the current status of pins:

# View all pins of gpiochip4 (using grep filter)
gpioinfo | grep -A 180 "gpiochip4"

# View specific pin (e.g., GPIO77)
gpioinfo | grep "line  77"

# View all occupied pins
gpioinfo | grep "consumer="

Common Issues

Command Not Found

Issue: bash: gpiodetect: command not found

Cause:
libgpiod toolkit is not installed

Solution:

# Install gpiod toolkit
sudo apt update
sudo apt install gpiod -y

# Verify installation
gpiodetect

Note: There is no gpiofind command in libgpiod 2.x version, this is normal.

Permission Issues

Issue: Permission denied

error: unable to request line 77: Permission denied

Solution:

Run commands with sudo:

sudo gpioget -c gpiochip4 77
sudo gpioset -c gpiochip4 77=1

Pin Occupied Issue

Issue: Device or resource busy

error: unable to request line 36: Device or resource busy

Cause:

  • Pin is occupied by other processes (such as I2C, SPI, etc.)
  • Pin is already being used by system functions

Solution:

  1. Check pin status:
gpioinfo | grep "line  36"
  1. If the pin is occupied, the output will show consumer= occupier information:
line  36:       unnamed                 output consumer=i2c-9
  1. Select an unoccupied pin (shown as unused in the output)

Pin Number Error

Issue: cannot find line

gpioget: cannot find line '200'

Cause:
Pin number is out of range or pin does not exist

Solution:

Confirm the pin range for Quectel Pi H1:

  • gpiochip4: 0-175 (176 lines total)
  • Use gpioinfo to view: gpioinfo | grep -A 180 "gpiochip4"

libgpiod Version Issues

Issue: API and command line tool differences between versions

libgpiod has significant changes between different versions. Quectel Pi H1 uses libgpiod 2.2.1.

Check Version:

apt list --installed | grep gpiod
# or
gpiodetect --version

Main Version Differences:

Feature libgpiod 1.x libgpiod 2.x (Quectel Pi H1)
Basic Syntax gpioget gpiochip4 77 gpioget -c gpiochip4 77
Chip Specification Positional argument Must use -c option
gpioinfo gpioinfo /dev/gpiochip4 gpioinfo | grep -A 180 "gpiochip4"
gpioset Default Behavior Exit immediately Continuously maintain (requires Ctrl+C)
gpioset Persistent Mode gpioset -m signal Default persistent (no parameter needed)
Output Format 0 / 1 "77"=inactive / "77"=active
gpiofind Supported Removed
gpiochip4 Line Count 128 (example) 176 (Quectel Pi H1)
GPIO Naming May be named Quectel Pi H1 all unnamed
C API Old API New API (incompatible)
Python API Old API New API (incompatible)

Key Changes Summary:

  • ✅ All commands must use -c <chip> option to specify chip
  • gpioset defaults to continuously maintain state, no longer exits immediately
  • ✅ Output format changed to "line"=active/inactive
  • gpiofind command has been removed
  • ❌ No longer supports positional argument method to specify chip

Debugging Tips

Common Debugging Commands

# 1. View all GPIO chips
gpiodetect

# 2. View all pin information for gpiochip4
gpioinfo | grep -A 180 "gpiochip4"

# 3. View occupied pins
gpioinfo | grep "consumer="

# 4. View specific pin status
gpioinfo | grep "line  77"

# 5. Read pin value
gpioget -c gpiochip4 77

# 6. Set pin value (continuously maintain)
gpioset -c gpiochip4 77=1

# 7. Monitor pin events
gpiomon -c gpiochip4 77

Comparison with sysfs

Feature sysfs (Deprecated) libgpiod
Interface Path /sys/class/gpio/ /dev/gpiochipX
Export Pin Manual export required Automatic management
Resource Management Manual unexport Automatic release
Concurrent Access Prone to conflicts Better resource management
Performance Slower (file operations) Faster (ioctl)
Event Monitoring Supported Better support
Maintenance Status Deprecated Actively maintained

Recommendation: New projects should use libgpiod instead of the deprecated sysfs interface.

Reference Resources