Использование библиотеки libgpiod для управления GPIO
libgpiod — это набор инструментов, специально разработанный для работы с GPIO в системах Linux. Он не только имеет библиотеки низкого уровня для языка C, но также интерфейсы для языков высокого уровня, таких как Python, и поставляется с несколькими инструментами командной строки, что весьма удобно.
GPIO
Настройка BIOS
-
В системах с ядром Linux 6.1 необходимо убедиться, что система загружена в режиме 0 Orange Pi 6 plus (Device Tree).

-
Для систем с ядром Linux 6.6, использующих ACPI, убедитесь с помощью команды dmidecode, что версия BIOS - v1.0_for_opi6plus_linux
sudo dmidecode -s bios-versioЕсли это не так, то обратитесь к разделу Обновление BIOS на плате Orange Pi 6 plus, чтобы записать нужную версию BIOS
Установка libgpiod
Для установки библиотеки выполните в командной строке следующие команды:
sudo apt update
sudo apt install -y libgpiod-dev libgpiod2 gpiod libgpiod-doc
sudo apt install -y python3-libgpiod
Базовая концепция
GPIO chip: каждый контроллер GPIO рассматривается как чип GPIO, обычно представленный как /dev/gpiochipX (где X — номер в системе). GPIO Line: каждая микросхема GPIO имеет несколько линий (контактов) GPIO, каждая из которых имеет уникальный номер, начиная с 0.
Для Linux 6.1 cоответствие чипов, линий, GPIO и контактов приведено в таблице ниже:
| GPIO Line | GPIO chip | GPIO | Контакт | Контакт | GPIO | GPIO chip | GPIO Line |
|---|---|---|---|---|---|---|---|
| 3.3 В | 1 | 2 | 5 В | ||||
| 13 | gpiochip3 | GPIO 056 | 3 | 4 | 5 В | ||
| 12 | gpiochip3 | GPIO 055 | 5 | 6 | GND | ||
| 22 | gpiochip4 | GPIO 097 | 7 | 8 | GPIO 105 | gpiochip4 | 30 |
| GND | 9 | 10 | GPIO 106 | gpiochip4 | 31 | ||
| 0 | gpiochip1 | GPIO 015 | 11 | 12 | GPIO 017 | gpiochip1 | 2 |
| 1 | gpiochip1 | GPIO 016 | 13 | 14 | GND | ||
| 24 | gpiochip4 | GPIO 099 | 15 | 16 | GPIO 100 | gpiochip4 | 25 |
| 3.3 В | 17 | 18 | GPIO 018 | gpiochip1 | 3 | ||
| 17 | gpiochip0 | GPIO 028 | 19 | 20 | GND | ||
| 14 | gpiochip0 | GPIO 025 | 21 | 22 | GPIO 019 | gpiochip1 | 4 |
| 18 | gpiochip0 | GPIO 029 | 23 | 24 | GPIO 026 | gpiochip0 | 15 |
| GND | 25 | 26 | GPIO 027 | gpiochip0 | 16 | ||
| 5 | gpiochip3 | GPIO 048 | 27 | 28 | GPIO 047 | gpiochip3 | 4 |
| 5 | gpiochip1 | GPIO 020 | 29 | 30 | GND | ||
| 8 | gpiochip1 | GPIO 023 | 31 | 32 | GPIO 021 | gpiochip1 | 6 |
| 9 | gpiochip1 | GPIO 024 | 33 | 34 | GND | ||
| 14 | gpiochip3 | GPIO 057 | 35 | 36 | GPIO 022 | gpiochip1 | 7 |
| 17 | gpiochip3 | GPIO 060 | 37 | 38 | GPIO 061 | gpiochip3 | 18 |
| GND | 39 | 40 | GPIO 062 | gpiochip3 | 19 |
Таблица соответствия для Linux 6.6
| GPIO Line | GPIO chip | GPIO | Контакт | Контакт | GPIO | GPIO chip | GPIO Line |
|---|---|---|---|---|---|---|---|
| 3.3 В | 1 | 2 | 5 В | ||||
| 13 | gpiochip0 | GPIO 056 | 3 | 4 | 5 В | ||
| 12 | gpiochip0 | GPIO 055 | 5 | 6 | GND | ||
| 22 | gpiochip1 | GPIO 097 | 7 | 8 | GPIO 105 | gpiochip1 | 30 |
| GND | 9 | 10 | GPIO 106 | gpiochip1 | 31 | ||
| 0 | gpiochip6 | GPIO 015 | 11 | 12 | GPIO 017 | gpiochip6 | 2 |
| 1 | gpiochip6 | GPIO 016 | 13 | 14 | GND | ||
| 24 | gpiochip1 | GPIO 099 | 15 | 16 | GPIO 100 | gpiochip1 | 25 |
| 3.3 В | 17 | 18 | GPIO 018 | gpiochip6 | 3 | ||
| 17 | gpiochip4 | GPIO 028 | 19 | 20 | GND | ||
| 14 | gpiochip4 | GPIO 025 | 21 | 22 | GPIO 019 | gpiochip6 | 4 |
| 18 | gpiochip4 | GPIO 029 | 23 | 24 | GPIO 026 | gpiochip4 | 15 |
| GND | 25 | 26 | GPIO 027 | gpiochip4 | 16 | ||
| 5 | gpiochip0 | GPIO 048 | 27 | 28 | GPIO 047 | gpiochip0 | 4 |
| 5 | gpiochip6 | GPIO 020 | 29 | 30 | GND | ||
| 8 | gpiochip6 | GPIO 023 | 31 | 32 | GPIO 021 | gpiochip6 | 6 |
| 9 | gpiochip6 | GPIO 024 | 33 | 34 | GND | ||
| 14 | gpiochip0 | GPIO 057 | 35 | 36 | GPIO 022 | gpiochip6 | 7 |
| 17 | gpiochip0 | GPIO 060 | 37 | 38 | GPIO 061 | gpiochip0 | 18 |
| GND | 39 | 40 | GPIO 062 | gpiochip0 | 19 |
Инструменты командной строки
- Команда gpiodetect может вывести список всех GPIO контроллеров (chip).
sudo gpiodetect
- Команда gpioinfo выводит подробную информацию обо всех контроллерах GPIO.
sudo gpioinfo
- Команда gpioset может перевести контакты GPIO в режим вывода и одновременно установить высокий уровень или низкий уровень.
Пример
Задача: Установить высокий уровень на 3 контакте разъёма GPIO в системе с ядром Linux 6.6.
Решение: Взяв данные из соответствующей таблицы, получается, что 3 контакту разъёма соответсвуют gpiochip0 и линия GPIO - 13. Для установки можно использовать следующую команду: вывод GPIO на выход + высокий уровень.
sudo gpioset gpiochip0 13=1
После настройки проверьте при помощи мультиметра напряжение на контакте 3, и вы увидите, что напряжение составляет 3,3 В.
Для установки низкого уровня на контакте используйте следующую команду:
sudo gpioset gpiochip0 13=0
- Команда gpioget переводит контакты GPIO в режим ввода и считывает статус уровня контакта.
sudo gpioget gpiochip0 13
Возвращаемое значение 0 или 1
- Команда gpiomon используется для мониторинга событий изменения уровня (прерывания) контактов GPIO, таких как нажатие/отпускание кнопок, срабатывание датчиков и т. д. Она основана на механизме событий устройств GPIO ядра Linux, который более эффективен и надежен, чем опрос, и поддерживает такую информацию, как временные метки и типы границ.
sudo gpiomon gpiochip1 1
Пример
Задача Получать данные об уровне на контакте 3 в Linux 6.6
Решение
Возмите данные из таблицы и введите в командной строке следующую команду:
sudo gpiomon gpiochip0 13
Соедините 3 контакт на разъёме с контактом GND. На консоли должно появится сообщение:

Разомкните контакты и увидите следующее сообщение:

Использование языка C для работы с GPIO
Код написан для Linux 6.6. Если используется ядро Linux6.1, то gpiochip0 необходимо изменить в коде на gpiochip3.
Запустите редактирование файла gpio_set.c:
vim gpio_set.c
Добавьте следующий код:
#include <gpiod.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define CHIPNAME "gpiochip0"
#define GPIO_OFFSET 13 // Соответствует контакту 3 в 40-контактном разъеме.
int main(int argc, char *argv[])
{
struct gpiod_chip *chip;
struct gpiod_line *line;
int value, ret;
// Проверка параметров командной строки
if (argc != 2) {
fprintf(stderr, "Ошибка параметра команды: %s. Используйте 0 или 1\n", argv[0]);
return 1;
}
value = atoi(argv[1]);
if (value != 0 && value != 1) {
fprintf(stderr, "Ошибка: значение уровня должно быть 0 или 1\n");
return 1;
}
//Открываем чип GPIO
chip = gpiod_chip_open_by_name(CHIPNAME);
if (!chip) {
perror("Невозможно открыть чип GPIO");
return 1;
}
// Получаем инструкции
line = gpiod_chip_get_line(chip, GPIO_OFFSET);
if (!line) {
perror("Не удалось получить линию GPIO");
gpiod_chip_close(chip);
return 1;
}
// Запрос — режим вывода (имя потребителя — «gpio_set»)
ret = gpiod_line_request_output(line, «gpio_set», 0); // Первоначально установлено низкое значение
if (ret < 0) {
perror("Невозможно запросить режим вывода (может быть занято или нет разрешения)");
gpiod_chip_close(chip);
return 1;
}
// Установка уровня
ret = gpiod_line_set_value(line, value);
if (ret < 0) {
perror("Не удалось установить значение GPIO");
} else {
printf("Контакт %d GPIO %s установлен на %s\n", CHIPNAME, GPIO_OFFSET, value ? "Высокий уровень" : "Низкий уровень");
}
// Освободить ресурсы (необязятельно, ресурсы освободятся автоматически после закрытия программы)
gpiod_line_release(line);
gpiod_chip_close(chip);
return 0;
}
Команда для компиляции кода выглядит следующим образом:
gcc -o gpio_set gpio_set.c -lgpiod
Проверить, что программа скомпилирована можно следующей командой:
ls gpio_set
Следующая команда устанавливает высокий уровень на контакте 3 40-контактного разъёма
sudo ./gpio_set 1
Та же команда с параметром 0 установит низкий уровень
sudo ./gpio_set 0
Использование Python для управления GPIO
Откройте файл gpio_set.py для редактирования:
vim gpio_set.py
Добавьте следующий код:
#!/usr/bin/env python3
import sys
import gpiod
CHIPNAME = "gpiochip0"
GPIO_OFFSET = 13 # Соответствует 3 контакту 3 в 40-контактном разъёме.
def main():
if len(sys.argv) != 2:
print(f"Используйте: {sys.argv[0]} <0|1>", file=sys.stderr)
sys.exit(1)
try:
value = int(sys.argv[1])
assert value in (0, 1)
except (ValueError, AssertionError):
print("错误: 电平值必须是 0 或 1", file=sys.stderr)
sys.exit(1)
# Открываем чип
with gpiod.Chip(CHIPNAME) as chip:
# Получить номер линии
line = chip.get_line(GPIO_OFFSET)
# Запрос на переход в режим вывода
line.request(consumer="gpio_set_py", type=gpiod.LINE_REQ_DIR_OUT)
# Установить уровень
line.set_value(value)
print(f"GPIO {CHIPNAME} контакт {GPIO_OFFSET} установлен {'высокий' if value else 'низкий'} уровень")
if __name__ == "__main__":
main()
Следующая команда устанавливает высокий уровень на контакте 3.
sudo python3 gpio_set.py 1
Для низкого уровня используйте команду:
sudo python3 gpio_set.py 0
Больше информации по библиотеке libgpiod
Официальная документаци по библиотеке находится по адресу https://libgpiod.readthedocs.io/en/latest/index.html