Das Beispiel aus elinux verwendet Memory-Mapped IO . Der Kernel exportiert auch eine Userspace - Schnittstelle über /sys/class/gpio
, 1 , die ebenfalls auf elinux dokumentiert . Wenn Sie in C arbeiten, würden Sie natürlich low level read()
/ write()
anstelle von verwenden echo
. Verwenden Sie keine Stream-basierten Funktionen auf höherer Ebene.
Einige Programmierer sind etwas verärgert, wenn sie aufgefordert werden, eine Dateischnittstelle für Dinge zu verwenden, von denen sie glauben, dass sie mit Systemaufrufen erledigt werden sollten. Dies ist nur eine Frage des Stils - sie sind genau dasselbe . In diesem Fall gibt es keinen "zusätzlichen E / A-Overhead" usw., der auf eine Datei zugreift, da es sich nicht um eine echte Datei handelt, sondern um eine Kernelschnittstelle. Genau wie jedes andere System-ABI, das Sie jemals verwendet haben, nur anders. Die Verwendung von /proc
und /sys
Knoten wurde von den Kernel-Entwicklern seit langem bevorzugt, aber ich sehe immer noch Leute, die entschlossen sind, Systemaufrufe zu verwenden, wo sie können - z. B. sysfs()
trotz der Tatsache, man 2 sysfs
dass klar gesagt wird:
Dieser von System V abgeleitete Systemaufruf ist veraltet. benutze es nicht. Auf Systemen mit / proc können dieselben Informationen über / proc / filesystems abgerufen werden. Verwenden Sie stattdessen diese Schnittstelle.
Dies ist eine Manpage der C-Bibliothek, in der Sie aufgefordert werden , die /proc
Benutzeroberfläche zu verwenden . Wenn das nicht gut genug ist, um Sie zu überzeugen, ist nichts. /sys
ist das Gleiche. Der Punkt ist: Nur weil Sie einen Dateiknoten anstelle einer C-spezifischen API verwenden, heißt das nicht, dass Sie keine echte Programmierung durchführen oder dass die Leistung darunter leidet usw. usw. Einige Leute könnten sagen, dass dies tatsächlich eine nette Funktion ist. Dies ist auch die Methode, die von den Leuten empfohlen wird, die den Betriebssystemkern geschrieben haben.
Eine kurze Einführung in die GPIO-Schnittstelle finden Sie in [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)
Es scheinen verschiedene Tutorials und solche online neben dem elinux zu sein. Ich habe nur I2C verwendet, sonst würde ich Ihnen eine direktere Antwort geben.
Wenn Sie daran interessiert sind, Kernel-Space-Code zu schreiben, der auf GPIO zugreift, können Sie hier einen Blick darauf werfen , obwohl ich denke, dass dies nur dann wirklich nützlich ist, wenn Sie einen Treiber für ein bestimmtes Gerät schreiben und Ihre eigene User-Space-API erstellen möchten.
1. Da mem-mapped IO auch Lesen / Schreiben verwenden muss, bin ich mir nicht sicher, ob eine Methode hier einen signifikanten Vorteil gegenüber der anderen bietet. Die Verwendung der /sys
Benutzeroberfläche ist sicherlich portabler, wenn Sie nach Code suchen, der auf anderen Dingen als einem Himbeer-Pi ausgeführt werden kann.