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 (gpiodetectgpioinfogpiogetgpioset, 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