Raspberry-Pi & Linux : SysFS est mort, longue vie à libgpiod

Libgpiod est une information importante pour les amateurs de prototypage électronique sur plateforme Linux (comme sur Raspberry-Pi).


Bien que bon nombre d'utilisateurs passent par une bibliothèque (Python, C, ...) et que celle-ci absorbera le changement, il est important de savoir ce qui va changer dans le système... juste pour identifier plus facilement la source de problèmes pouvant survenir.

Arrivé de libgpiod
La mainline du noyau Linux accueille un nouveau venu sous le nom de libgpiod présenté lors du Fosdem 2018. Egalement appelé "GPIO character device", libgpiod est maintenant la nouvelle méthode recommandée pour interagir avec les GPIO.

  • Libgpiod est un module intégré au noyau, il sera donc rapide.
  • Libgpiod permet de dépasser les limitations de systèmes actuellement en disponibles et permettant de manipuler les GPIOs... mais nous y reviendrons plus tard.
  • Libgpiod est conçu avec l'idée de rester simple et abordable (pour faciliter la mise en oeuvre)
  • libgpiod dispose d'un support Python (Adafruit l'a déjà intégré)

Les anciennes méthodes de manipulation de GPIO
Jusque maintenant, deux méthodes étaient disponibles pour manipuler les GPIOs.
  • sysfs
  • devmem
sysfs : Permet de manipuler les gpios par l'intermédiaire du système de fichier /sys.
Par exemple, /sys/class/gpio/gpio10 correspond à la broche n° 10. Il est possible de manipuler sysfs avec de simples opérations de fichier, donc depuis le shell, python, c et n'importe quel langage capable de manipuler des fichiers.
Grâce à cela, il est possible de modifier la direction de la broche (entrée/sortie) et l'état de la broche (haut/bas).
L'avantage de cette méthode, c'est qu'elle est très simple à exploiter.
L'inconvénient, c'est qu'elle est aussi relativement lente puisqu'elle s'appuie sur la manipulation de fichiers (en effet, il faut souvent manipuler plusieurs entrées sysfs --comme value, direction, active_low, edge-- , donc des fichiers, pour manipuler un gpio.).

devmem :
Devmem  permet d'accéder au contenu de la mémoire... et les gpios sont également accessible par des entrées particulière dans cette mémoire.
Il est également possible de manipuler /dev/mem à l'aide d'opération fichier mais cela n'est vraiment pas conseiller.
En principe, il ne faut pas écrire n'importe quoi, n'importe où sinon cela corrompra le fonctionnement du le système d'exploitation de façon non prévisible (youtube).
En faisant des opérations d'écritures à des adresses précises (donc offset préçis dans le fichier) avec des valeurs bien déterminées, il est possible de manipuler des éléments matériels, y compris les GPIOs.
L'avantage de la méthode devmem, accès simple et direct au niveau système même s'il est nécessaire de disposer d'un accès root (super utilisateur).
Inconvénient de devmem, très-très-très sensible au bug et particulièrement difficile à déboguer (puisque la moindre erreur peut potentiellement déboucher sur un plantage système.

Les apports de libgpiod
Le fait d'avoir les GPIO gérés au niveau du noyaux permet d'offrir les fonctionnalités (avantages) suivants:
  • Possible d'utiliser un modèle de type "consumer".
  • Permet d'utiliser des "GPIO descriptor" pour identifier les broches. En effet, ces GPIOs peuvent êtres attachés au SoC (comme le Raspberry-Pi) mais également à des sous composants matériels (comme par exemple un MCP23017). Voir 1*
  • Supporte toujours les numéros de GPIO "GPIO Number" même si cela n'est pas recommandé.
  • Pilotes GPIO disponibles.
    Cela permet de piloter les gpios d'un contrôleur gpio (ex:mcp23017) par l'intermédiaire du kernel puisque celui-ci l'a pris en charge. Les GPIO deviennent disponible par l'intermédiaire de /dev/gpiopuce1, /dev/gpiopuce2/, ... . Cela permet de commander tous les GPIOs de la puce en un seul accès :-)
    Cette approche autorise toujours l'accès par l'intermédiaire de manipulation de fichier.
  • Le fait d'utiliser des pilotes facilite également l'exploitation des GPIO dans de nombreux logiciels.
  • Possibilité de manipuler/lire plusieurs lignes GPIOs (jusqu'à 64) en une seule opération.
  • Permet d'offrir une méthode de "polling" plus fiable que via sysfs.
1*) pouvoir retrouver un GPIO par le nom du composant et n° de GPIO sur le composant présente un réel avantage. Il est donc possible de manipuler des GPIO par leur nom :-)

libgpiod - character device 
L'API utilisateur de libgpiod (linux/gpio.h) offre l'accès à différentes ressources et permet de dialoguer avec le noyaux.
Il est ainsi possible d'interroger le noyaux:
  • Pour obtenir des infos sur un composant GPIO (nommé Chip).
  • Pour obtenir des infos sur un GPIO (nommé Line du Chip, bien entendu).
  • Obtenir des valeurs pour une Line
  • Lecture/Ecriture de valeur
  • Introduire une requête pour des événements (events)
  • Faire un polling des events
  • Faire une lecture des events 
Ainsi, obtenir les informations à propos d'un composant GPIO (dit Chip), le code se résume à:

struct gpiochip_info {
    char name[32];
    char label[32];
    __u32 lines; // unsigned integer 32bits
}

void get_chip_info(void) {
    struct gpiochip_info info;
    int fd, rv; // file descriptor & result value
  
    fd = open( "/dev/gpiochip0", O_RDWR ); // open in read/write mode
    rv = ioctl( fd, GPIO_GET_CHIPINFO_IOCTL, info );
}

il est ensuite possible d'obtenir les informations à propos d'un GPIO avec le code suivant:

struct gpioline_info {
    __u32 line_offset; // indicate the gpio line. Unsigned integer 32 bits
    __u32 flags;       // informations about the GPIO
    char name[32];
    char consumer[32];
};

#defined GPIOLINE_FLAG_KERNEL      (1UL << 0)
#defined GPIOLINE_FLAG_IS_OUT      (1UL << 1)
#defined GPIOLINE_FLAG_ACTIVE_LOW  (1UL << 2)
#defined GPIOLINE_FLAG_OPEN_DRAIN  (1UL << 3)
#defined GPIOLINE_FLAG_OPEN_SOURCE (1UL << 4)

void get_line_info( void ) {
    struct gpioline_info info;
    int rv; 

    // reset the structure content
    memset( &info, 0, sizeof(info) );
    info.line_offset = 3; // GPIO of interest

    rv = ioctl( fd, GPIO_GET_LINEINFO_IOCTL, &info ); 
}


Bon, c'est du C, c'est pas forcément marrant pour tout le monde mais cela reste abordable.
Pour le moment, nous n'avons que les informations à propos des lignes et valeurs. Cette information se trouve dans la présentation au Fosdem 2018.

libgpiod - utilitaires
Libgpiod apporte de nouveaux utilitaires (gpiodetect, gpioinfo, gpioset, gpioget, gpiofind, gpiomon) permettant de détecter les Chips et les Lines....donc les GPIOs disponibles :-)
Utilitaires pour libgpiod


Ressources

Aucun commentaire