Startseite>Tricks zum Programmieren der GPIO-Schnittstelle
Aus Raspberry Pi Geek 05/2013

Tricks zum Programmieren der GPIO-Schnittstelle

© vska, 123RF

Rein und raus

Richard Ryniker

Sobald Sie komplexere Aufgaben anpeilen, brauchen Sie auch ein erweitertes Repertoire an Programmiertechniken für den Zugriff auf die GPIO-Pins des Raspberry Pi, wie zum Beispiel die Verarbeitung von Interrupts.

Das Kürzel GPIO steht für General Purpose Input/Output, was sich in etwa als Mehrzweck-Ein/Ausgabe ins Deutsche übersetzen lässt. Damit bezeichnet man im Allgemeinen einen Kontakt, dessen Verhalten als Eingabe- respektive Ausgabeschnittstelle sich über einen dahinter hängenden integrierten Schaltkreis beliebig programmieren lässt. Der Raspberry Pi verfügt über ein GPIO-Interface mit insgesamt 26 Pins mit, von denen sich 17 wahlweise als Ein- oder Ausgang ansteuern lassen (Abbildung 1).

Abbildung 1: Das GPIO-Interface des Raspberry Pi. Die grün gekennzeichneten Pins lassen sich wahlweise als Ein- oder Ausgänge ansteuern. Dazu gehört beispielsweise auch der Port »GPIO23« auf Pin 16 der Schnittstelle.

Abbildung 1: Das GPIO-Interface des Raspberry Pi. Die grün gekennzeichneten Pins lassen sich wahlweise als Ein- oder Ausgänge ansteuern. Dazu gehört beispielsweise auch der Port »GPIO23« auf Pin 16 der Schnittstelle.

Linux bringt ein eigenes GPIO-Subsystem als Schnittstelle für Anwendungen mit, schützt die durch Treiber wie I2C oder SPI verwendeten Ressourcen und stellt einen Pin-genauen Zugriff sicher, sodass sich kein Programm darum zu kümmern braucht, was andere Software gerade mit anderen GPIO-Kontakten anstellt. Dies bietet den angenehmen Vorteil, dass man sich bei der Programmierung keine Gedanken um sogenannte Race Conditions zu machen braucht, bei der ein Programm das andere beim Zugriff auf die Pins blockiert. Auch komplizierte Softwaremechanismen wie Locks oder ein Interrupt-Management können dadurch entfallen.

Das GPIO-System von Linux legt seine Dateien im Verzeichnis /sys/class/gpio/ ab. Wie bei vielen Konfigurations- und Kontrolldateien erhält nur Root hier Zugriff. Die Anwendungen auf dem Raspberry Pi kommunizieren mit dem GPIO-System mittels dieser Dateien, über die das System Informationen zwischen Hard- und Software übermittelt.

Dabei kommt oft das Kommando echo der Shell zum Einsatz. Normalerweise benutzt man es, um Texte auf die Standard-Ausgabe (in der Regel der Bildschirm) zu schreiben, etwa mit echo "Hallo!". Zusammen mit einer Ausgabeumleitung kann man damit aber auch in Dateien schreiben: So legt echo "Hallo!" > hallo.txt den Text in der Datei hallo.txt im aktuellen Verzeichnis ab.

Nehmen wir einmal an, Sie möchten den Pin 16 der GPIO-Schnittstelle ansprechen, der dem Port GPIO23 entspricht. Im Schaltplan des RasPi (Abbildung 2) bezeichnet diesen Port auch als GPIO_GEN4 [1]. Um ein Benutzerinterface für diesen Port zu erzeugen, führen Sie folgenden Befehl aus:

$ sudo echo 23 >/sys/class/gpio/export
Abbildung 2: Der Raspberry-Pi-Schaltplan bezeichnet Pin 16 (»GPIO23«) auch als GPIO_GEN4. Auf diesem Schema erkennen Sie auch die anderen 16 programmierbaren Pins.

Abbildung 2: Der Raspberry-Pi-Schaltplan bezeichnet Pin 16 (»GPIO23«) auch als GPIO_GEN4. Auf diesem Schema erkennen Sie auch die anderen 16 programmierbaren Pins.

Der Kernel erzeugt daraufhin das Verzeichnis /sys/class/gpio/gpio23, das vier im weiteren Verlauf wichtige Dateien enthält: active_low, direction, edge und value. Sie enthalten die in der Tabelle “Dateien in /sys/class/gpio/gpio23” gezeigten Ausgangswerte, zumindest, solange am Pin noch nichts hängt.

Dateien in

Datei

Ausgangswert

active_low

0

direction

in

edge

none

value

0

Über die vier Dateien erfolgt die gesamte Ansteuerung des Ports GPIO23. Die dazu notwendigen Kommandos fasst Listing 1 zusammen. Um den Port als Ein- oder Ausgang zu definieren, beschreiben Sie beispielsweise die Datei direction mit dem entsprechenden Wert (Zeile 2 und 3). Das gleiche gilt für das Initialisieren eines Ausgangswerts (Zeile 5 und 6). Um die Pin-Ausgabe an- beziehungsweise abzuschalten, schreiben Sie in die Datei value (Zeile 8 und 9). Über das File active_low invertieren Sie bei Bedarf die Pin-Logik (Zeile 11 und 12). Das müssen Sie vor dem Lesen einer Eingabe beziehungsweise dem Setzen eines Ausgabewerts erledigen.

Listing 1

 

# Port als Ein- oder Ausgang verwenden
$ sudo echo in >/sys/class/gpio/gpio23/direction
$ sudo echo out >/sys/class/gpio/gpio23/direction
# Ausgabewert initialisieren
$ sudo echo low >/sys/class/gpio/gpio23/direction
$ sudo echo high >/sys/class/gpio/gpio23/direction
# Pin-Ausgabe ein/aus
$ sudo echo 1 >/sys/class/gpio/gpio23/value
$ sudo echo 0 >/sys/class/gpio/gpio23/value
# Pin-Logik invertieren
$ sudo echo 0 >/sys/class/gpio/gpio23/active_low
$ sudo echo 1 >/sys/class/gpio/gpio23/active_low

Wie schnell lassen sich nun mittels dieser Mechanismen die GPIO-Pin-Werte modifizieren? Das in Listing 2 gezeigte einfache Python-Programm generiert Pulse mit 18 kHz. Die Entsprechung in C [2] schafft dagegen rund 120 kHz. Die tatsächliche Umschaltfrequenz variiert, den der RasPi beschäftigt sich zwischendurch auch noch mit anderen Dingen, wie etwa Netzwerkzugriffen, dem aktualisieren der Zeit und anderen System- und Benutzerprozessen.

Listing 2

 

#!/usr/bin/python
#
# GPIO-Pin umschalten
# Ausgabefrequenz: ~18 kHz
# (je nach anderen Aktivitaeten)
pin_path = '/sys/class/gpio/gpio23'
def write_once(path, value):
  f = open(path, 'w')
  f.write(value)
  f.close()
  return
# Ausgabe setzen, Initialwert "low"
write_once(pin_path + '/direction', 'out\n')
f = open(pin_path + '/value', 'w')
# Schnellstmoeglich blinken
while 1:
  f.write('1')
  f.flush()
  f.write('0')
  f.flush()
f.close()

GPIO ohne Root?

Bisher haben wir als Root auf die GPIO-Schnittstelle zugegriffen, was aus verschiedenen Gründen in der Praxis als nicht unbedingt ratsam erscheint, sich hauptsächlich aber aus Gründen des Sicherheit und Systemstabilität verbietet. Nur allzu leicht bringen Sie mit als Root abgesetzten fehlerhaften Kommandos das System aus dem Tritt oder gar zum Absturz.

Komplett lässt sich dieses Dilemma nicht umgehen, denn Zugriffe auf das GPIO-Interface klappen nun einmal nur mit Root-Rechten. Einen gewissen Schutz bietet das Zwischenschalten einer Kontrollinstanz, wie beispielsweise des C-Programms gpio_control.c, das Sie von der Website Ryniker.ods.org herunterladen können [3]. Die Kommentare am Anfang des Quelltexts beschreiben, wie Sie es übersetzen und auf dem RasPi (als Root) einrichten. Via setuid läuft es nach einem Aufruf durch einen normalen Benutzer mit der effektiven UID von root, sodass es mit allen zum Ansteuern der GPIO-Schnittstelle und ihrer Kontrolldateien notwendigen Rechten agieren kann.

Der meiste Code in gpio_control.c dient ausschließlich dazu, sicherzustellen, dass die übergebenen Argumente sinnvoll sind und keinen Schaden anrichten können. Außerdem informiert Sie das Programm, sobald ein ungewöhnlicher Betriebszustand auftritt. Um den bereits im vorigen Beispiel verwendeten Pin 23 mit Gpio_control anzusteuern, tippen Sie als einfacher Benutzer:

$ gpio_control 23 export

Bei Bedarf konfigurieren Sie gpio_control.c vor dem Übersetzen so, dass es lediglich den Anwendern einer bestimmten Gruppe Zugriff auf das GPIO-Interface einräumt, anstatt allen Benutzern. Für jeden einzelnen GPIO-Port können Sie zudem den Export explizit gestatten oder unterbinden.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
€0,99 – Kaufen
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS
Deutschland