Cet exemple d'Elinux utilise des E / S mappées en mémoire . Le noyau exporte également une interface espace utilisateur via /sys/class/gpio
, 1 qui est également documentée sur elinux . En travaillant en C, vous utiliseriez de bas niveau read()
/ write()
au lieu de echo
, évidemment. N'utilisez pas de fonctions basées sur des flux de niveau supérieur.
Certains programmeurs deviennent un peu contrariés lorsqu'on leur dit d'utiliser une interface de fichier pour les choses qui, selon eux, devraient être effectuées avec les appels système. C'est purement une question de style - ils équivalent exactement à la même chose . Il n'y a pas de "surcharge d'E / S supplémentaire", etc., accéder à un fichier dans ce cas car ce n'est pas un vrai fichier, c'est une interface noyau. Exactement comme n'importe quel autre système ABI que vous ayez jamais utilisé, seulement différent. L'utilisation des nœuds /proc
et /sys
a été longtemps préférée par les développeurs du noyau, mais je vois toujours des gens déterminés à utiliser les appels système là où ils le peuvent - par exemple sysfs()
, malgré le fait qu'il le man 2 sysfs
dit clairement:
Cet appel système dérivé de System-V est obsolète; ne l'utilisez pas. Sur les systèmes avec / proc, les mêmes informations peuvent être obtenues via / proc / filesystems; utilisez plutôt cette interface.
Il s'agit d'une page de manuel de la bibliothèque C vous indiquant d' utiliser l' /proc
interface . Si ce n'est pas assez bon pour vous convaincre, rien ne l'est. /sys
c'est le même genre de chose. Ce qui est important: ce n'est pas parce que vous utilisez un nœud de fichier au lieu d'une API spécifique à C que vous ne faites pas de véritable programmation, ou que les performances en souffriront, etc. etc. Certaines personnes pourraient dire que c'est en fait une fonctionnalité intéressante . C'est également la méthode recommandée par les personnes qui ont écrit le noyau du système d'exploitation.
Une introduction rapide à l'interface GPIO se trouve dans [kernel-src]/Documentation/ABI/testing/sysfs-gpio
:
GPIOs are only made available to userspace by an explicit
"export" operation. If a given GPIO is not claimed for use by
kernel code, it may be exported by userspace (and unexported later).
Kernel code may export it for complete or partial access.
GPIOs are identified as they are inside the kernel, using integers in
the range 0..INT_MAX. See Documentation/gpio.txt for more information.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write: high, low
/edge ... r/w as: none, falling, rising, both
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
Il existe différents tutoriels et autres en ligne en plus de celui d'elinux. Je n'utilise que I2C, sinon je vous donnerais une réponse plus directe.
Si vous êtes intéressé à écrire du code d'espace noyau accédant à GPIO, vous pouvez jeter un œil ici , bien que je pense que ce n'est vraiment utile que si vous voulez écrire un pilote pour un périphérique spécifique et créer votre propre API d'espace utilisateur.
1. Étant donné que les E / S mappées mem doivent également utiliser la lecture / écriture, je ne sais pas si une méthode offre un avantage significatif par rapport à l'autre ici. L'utilisation de l' /sys
interface sera certainement plus portable, si vous recherchez du code qui fonctionnera sur autre chose qu'un Raspberry Pi.