Présentation:
libgpiod est une bibliothèque et un ensemble d’outils en mode utilisateur (userspace) pour interagir avec les GPIO (General Purpose Input/Output) sur les systèmes Linux, en particulier ceux utilisant l’interface GPIO character device (introduite avec le noyau Linux 4.8).
installation
sudo apt install gpiod libgpiod-dev libgpiod-doc
il faut appartenir au groupe gpio
sudo usermod -aG gpio $USER
Pourquoi libgpiod ?
Avant, les GPIO étaient souvent contrôlés via l’interface obsolète /sys/class/gpio (sysfs), qui avait plusieurs limitations :
- Pas de gestion propre des conflits d’accès.
- Pas de contrôle fin des événements (interruptions).
- Problèmes de performances et de sécurité.
libgpiod offre une alternative moderne et robuste, avec :
✅ Une API C bien définie (libgpiod).
✅ Des outils en ligne de commande (gpiodetect, gpioinfo, gpioget, gpioset, etc.).
✅ La prise en charge des interruptions GPIO (polling et événements).
✅ Une meilleure gestion des droits (via /dev/gpiochip*).
Outils principaux
gpiodetect: Liste les contrôleurs GPIO disponibles (/dev/gpiochip0,/dev/gpiochip1, etc.).gpioinfo: Affiche les lignes GPIO d’un contrôleur (numéros, directions, états).gpioget: Lit l’état d’une ou plusieurs GPIO.gpioset: Modifie l’état d’une GPIO (avec options de durée, mode push-pull/open-drain).gpiomon: Surveille les changements d’état (interruptions).
gpiodetect
bruno@rpi364:~/Works/gpiomonitor $ gpiodetect
gpiochip0 [pinctrl-bcm2835] (54 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)
il y a 2 puces pour les GPIO sur notre RPI
gpioinfo
va lister les états des GPIO et le détail par puce (chip)
on peut vérifier les lignes utilisées et les libres, par exemple 17 et 27 unused
gpioinfo
gpiochip0 - 54 lines:
line 0: "ID_SDA" unused input active-high
line 1: "ID_SCL" unused input active-high
line 2: "SDA1" unused input active-high
line 3: "SCL1" unused input active-high
line 4: "GPIO_GCLK" unused input active-high
line 5: "GPIO5" unused input active-high
line 6: "GPIO6" unused input active-high
line 7: "SPI_CE1_N" unused input active-high
line 8: "SPI_CE0_N" unused input active-high
line 9: "SPI_MISO" unused input active-high
line 10: "SPI_MOSI" unused input active-high
line 11: "SPI_SCLK" unused input active-high
line 12: "GPIO12" unused input active-high
line 13: "GPIO13" unused input active-high
line 14: "TXD1" "gpio-fan@0" output active-high [used]
line 15: "RXD1" unused input active-high
line 16: "GPIO16" unused input active-high
line 17: "GPIO17" unused output active-high
line 18: "GPIO18" unused input active-high
line 19: "GPIO19" unused input active-high
line 20: "GPIO20" unused input active-high
line 21: "GPIO21" unused input active-high
line 22: "GPIO22" unused input active-high
line 23: "GPIO23" unused input active-high
line 24: "GPIO24" unused input active-high
line 25: "GPIO25" unused input active-high
line 26: "GPIO26" unused input active-high
line 27: "GPIO27" unused input active-high
line 28: "HDMI_HPD_N" "hpd" input active-low [used]
line 29: "STATUS_LED_G" "ACT" output active-high [used]
line 30: "CTS0" unused input active-high
line 31: "RTS0" unused input active-high
line 32: "TXD0" unused input active-high
line 33: "RXD0" unused input active-high
line 34: "SD1_CLK" unused input active-high
line 35: "SD1_CMD" unused input active-high
line 36: "SD1_DATA0" unused input active-high
line 37: "SD1_DATA1" unused input active-high
line 38: "SD1_DATA2" unused input active-high
line 39: "SD1_DATA3" unused input active-high
line 40: "PWM0_OUT" unused input active-high
line 41: "PWM1_OUT" unused input active-high
line 42: "ETH_CLK" unused input active-high
line 43: "WIFI_CLK" unused input active-high
line 44: "SDA0" unused input active-high
line 45: "SCL0" unused input active-high
line 46: "SMPS_SCL" unused input active-high
line 47: "SMPS_SDA" unused output active-high
line 48: "SD_CLK_R" unused input active-high
line 49: "SD_CMD_R" unused input active-high
line 50: "SD_DATA0_R" unused input active-high
line 51: "SD_DATA1_R" unused input active-high
line 52: "SD_DATA2_R" unused input active-high
line 53: "SD_DATA3_R" unused input active-high
gpiochip1 - 8 lines:
line 0: "BT_ON" "shutdown" output active-high [used]
line 1: "WL_ON" unused output active-high
line 2: "PWR_LED_R" "PWR" output active-low [used]
line 3: "LAN_RUN" unused output active-high
line 4: "NC" unused input active-high
line 5: "CAM_GPIO0" "cam1_regulator" output active-high [used]
line 6: "CAM_GPIO1" unused output active-high
line 7: "NC" unused input active-high
gpioget
place en entrée et lit l’état des lignes demandées
bruno@rpi364:~/Works/gpiomonitor $ gpioget gpiochip0 17 27
0 0
gpioset
place en sortie les lignes demandées
bruno@rpi364:~/Works/gpiomonitor $ gpioset gpiochip0 17=1 27=0
gpiofind
bruno@rpi364:~/Works/gpiomonitor $ gpiofind "GPIO17"
gpiochip0 17
Utilisation du langage C
installation de la lib et de la doc
normalement déja fait
sudo apt install libgpiod-dev libgpiod-doc
Structure de Base d’un Programme c
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
int main() {
const char *chipname = "gpiochip0"; // Nom du contrôleur GPIO
struct gpiod_chip *chip;
struct gpiod_line *line;
int ret;
// Ouvrir le chip GPIO
chip = gpiod_chip_open_by_name(chipname);
if (!chip) {
perror("Erreur d'ouverture du chip");
return 1;
}
// Ici: Configuration des GPIO...
// Fermeture
gpiod_chip_close(chip);
return 0;
}
Contrôle des GPIO
Configurer une sortie (LED)
// Obtenir la ligne GPIO17
line = gpiod_chip_get_line(chip, 17);
if (!line) {
perror("Erreur ligne GPIO");
gpiod_chip_close(chip);
return 1;
}
// Configurer en sortie avec état initial LOW
ret = gpiod_line_request_output(line, "LED", 0);
if (ret < 0) {
perror("Erreur config sortie");
gpiod_line_release(line);
gpiod_chip_close(chip);
return 1;
}
// Allumer la LED
gpiod_line_set_value(line, 1);
sleep(1);
// Éteindre la LED
gpiod_line_set_value(line, 0);
// Libérer la ligne
gpiod_line_release(line);
Lire une entrée (Bouton/ILS)
line = gpiod_chip_get_line(chip, 27);
if (!line) {
perror("Erreur ligne GPIO");
gpiod_chip_close(chip);
return 1;
}
// Configurer en entrée avec pull-up
struct gpiod_line_request_config config = {
.consumer = "Bouton",
.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT,
.flags = GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP
};
ret = gpiod_line_request(line, &config, 0);
if (ret < 0) {
perror("Erreur config entrée");
gpiod_line_release(line);
gpiod_chip_close(chip);
return 1;
}
// Lire l'état
int val = gpiod_line_get_value(line);
printf("État: %d\n", val); // 0=pressé, 1=relâché (pull-up)
gpiod_line_release(line);
Exemple en C
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
int main() {
const char *chipname = "gpiochip0";
struct gpiod_chip *chip;
struct gpiod_line *line;
int ret;
// Ouvrir le chip GPIO
chip = gpiod_chip_open_by_name(chipname);
if (!chip) {
perror("Erreur d'ouverture du chip");
return 1;
}
// Obtenir une ligne GPIO (ex: ligne 17)
line = gpiod_chip_get_line(chip, 17);
if (!line) {
perror("Erreur d'accès à la ligne");
gpiod_chip_close(chip);
return 1;
}
// Configurer la ligne en sortie
ret = gpiod_line_request_output(line, "example", 0);
if (ret < 0) {
perror("Erreur de configuration");
gpiod_chip_close(chip);
return 1;
}
// Faire clignoter la LED
for (int i = 0; i < 5; i++) {
gpiod_line_set_value(line, 1);
sleep(1);
gpiod_line_set_value(line, 0);
sleep(1);
}
// Libérer les ressources
gpiod_chip_close(chip);
return 0;
}
Compiler le code c
gcc ton_programme.c -o ton_programme -lgpiod
