Ich habe dieses Beispiel implementiert, um mich mit der grundlegenden GPIO-Programmierung in C vertraut zu machen. Der Code zeigt, wie auf GPIO-Pins geschrieben wird, gibt jedoch nicht explizit an, wie der Status von Pins gelesen wird. Ich vermute, dass WiringPi letztendlich eine bessere Lösung sein wird, da ich irgendwann den Status eines Ausgangs-Pins lesen möchte , aber in der Zwischenzeit möchte ich meine Wanderung durch Dom und Gerts Code abschließen. Wie könnte ich dann den Wert eines Pins lesen?
8
Antworten:
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 levelread()
/write()
anstelle von verwendenecho
. 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: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
: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.quelle
read()
/write()
und die zugehörigen Funktionen auf der Basis von Dateideskriptoren (im Gegensatz zu Dateistreams ) sind eigentlich nicht Standard C, aber sie sind POSIX und Standard unter Linux. Hier gibt es eine Einführung: gnu.org/software/libc/manual/html_node/… Standarddateistreams funktionieren möglicherweise, aber meiner Erfahrung nach waren sie auch problematisch für WRT/sys
und/proc
; Die Verwendung der Deskriptoren der unteren Ebene ist ohnehin nicht mehr umständlich oder schwierig. Viel Glück!