Anbieter zum Thema
Triggerung durch hrtimer-Event
Das IIO-Framework bietet Unterstützung für das Einlesen von Sensordaten beim Auftreten eines Ereignisses, wie zum Beispiel eines Interrupts. Die dann eingelesenen Werte können in einen Speicherbereich eingestellt und asynchron mit einem Device-Node abgefragt werden.
Die am häufigsten eingesetzte Triggerung ist der hrtimer-Event. Hierbei wird der Hardware-Timer durch das hrtimer-Framework auf einen Zeitpunkt in der Zukunft programmiert. Tritt der Zeitpunkt ein, liefert der Hardware-Timer einen Interrupt, welcher als hrtimer-Event zur Verfügung steht. Eine Callback-Funktion im Industrial-IO-Treiber wird aufgerufen und der Sensor abgefragt.
Die Daten können in einen Puffer eingestellt werden. Dieser muss im Treiber eingerichtet werden und dient der Zwischenspeicherung der Daten, bis diese mithilfe des Device-Nodes (/dev/iio:device<N>) abgefragt werden. Das IIO-Framework kümmert sich darum, dass der Timer erneut programmiert wird. Dadurch entsteht ein zyklischer Timer mit konstanter Abtastfrequenz.
Abfrage der gepufferten Daten
Für die Abfrage der Daten existiert im Verzeichnis tools/iio der Linux-Sourcen ein Hilfsprogramm namens iio_generic_buffer. Diesem wird mitgeteilt, von welchem Device mit welchem Trigger welche Daten wie häufig abgefragt werden. Nachfolgendes Beispiel zeigt, wie man hrtimer-Events aus dem Userspace heraus verwendet:
root@waage: cd /sys/kernel/config/iio/triggers/hrtimer
root@waage: mkdir mytmr
root@waage: cd /sys/bus/iio/devices/trigger0
root@waage: echo 1 > sampling_frequency
root@waage: cd /sys/bus/iio/devices/iio_device1/scan_elements
root@waage: echo 1 > in_voltage0_en
root@waage: echo 1 > in_timestamp_en
root@waage: iio_generic_buffer -c 3 -N 1 -T 0
iio device number being used is 1
iio trigger number being used is 0
/sys/bus/iio/devices/iio:device1 mytmr
10.062591 1511821230327326320
11.024664 1511821231327324360
10.025594 1511821232327323800
Zunächst wird der hrtimer-Trigger generiert. Dies erfolgt im configfs durch Anlegen eines neuen Verzeichnisses. Als Name dafür wurde im Beispiel mytmr gewählt. Handelt es sich um den ersten angelegten Trigger, dann hat dieser die Nummer 0.
Im sysfs ist ein neues Device-Verzeichnis mit dem Namen trigger<T> entstanden, wobei T die Nummer des Triggers ist. In diesem Verzeichnis kann der Trigger parametrisiert werden. In obigem Beispiel wird die Frequenz auf 1 Hz eingestellt. Im Verzeichnis scan_elements können die einzelnen Kanäle sowie der Timestamp aktiviert werden.
Die Datenabfrage erfolgt mit dem Programm iio_generic_buffer. Es werden die voreingestellten Kanäle 3-mal (-c 3) vom Device mit der Nummer 1 (-N 1) unter Verwendung des Triggers mit der Nummer 0 (-T 0) abgefragt. Angezeigt werden in obigem Beispiel der Rohwert multipliziert mit dem Skalierungsfaktor (aus Datei involtagescale) in der ersten Spalte und der Timestamp in Nanosekunden in der zweiten Spalte.
Datenabfrage im Userspace
Sollen die durch einen Trigger generierten und gepufferten Daten durch eine Userspace-Anwendung abgefragt werden, kann dies durch Auslesen des Device-Nodes (/dev/iio:device<N>) erfolgen, wobei <N> wieder die Nummer des Devices ist.
Diese Daten stehen in dem Device-Node binär drinnen und können mithilfe eines kleinen C-Programmes in ASCII gewandelt und ausgegeben werden. Wie die Daten binär zu interpretieren sind, ist im Verzeichnis scanelements dokumentiert. Beispiel:
root@waage: cd /sys/bus/iio/devices/iio:device1/scan_elements
root@waage: cat in_voltage0_type
le:u24/32>>0
root@waage: cat in_voltage0_index
0
So besagt dieses Beispiel, dass der Spannungswert des Kanales 0 little-endian-codiert, unsigned 24 Bit groß ist und in einem 32-Bit-Feld ohne Bit-Shifting drinnen steht. Der Wert wird als erstes geliefert (in_voltage0_index == 0). Mit diesen Informationen ist es ein leichtes ein eigenes Programm zu schreiben, welches die gepufferten Daten ausliest und korrekt interpretiert.
Userspace-Libraries
Das IIO-Subsystem ist, wie oben ausgeführt, sehr systematisch nach bekannten und dokumentierten Regeln aufgebaut. Dass dies so bleibt, darüber wachen die Reviewer und der Maintainer. Bevor neue Definitionen verwendet werden, wird versucht, neue Treiber in die bestehenden Interfaces zu integrieren.
Am Framework angemeldete IIO-Geräte werden in der Reihenfolge der Anmeldung durchnummeriert. Dies erfordert vom Userspace-Entwickler, dass er den Zusammenhang zwischen Device-Nummer und dem gewünschten Treiber herstellen kann. Er muss die Devices im sysfs durchlaufen und anhand des Attributes name den betreffenden Treiber erkennen. Analog dazu funktioniert die Erkennung von Trigger-Events.
Dies ist mühsame Routine und kann aufgrund der Systematik von IIO gut auf eine Library ausgelagert werden. Die libiio ist genau dafür erschaffen worden. Mit ihr kann gut automatisiert werden:
- Verbindung zu lokalem oder entferntem IIO-Subsystem, auf welchem der iiod-Dämon läuft
- Abfrage der vorhanden Devices
- Kanäle und Attribute durchiterieren
- Lesen und Schreiben von Attributen
Auswertung der Bienenwaage
In Bild 5 ist der Temperatur- sowie Gewichtsverlauf im Zeitraum einer Woche aufgezeichnet. Zur Auswertung wurde GNUPlot verwendet. Aus dem Diagramm kann ausgelesen werden:
[07.-09.05.] Bei Regenwetter und Temperaturen unter 12°C findet kein Ausflug statt
-> Honig wird verbraucht.
[10.05.] Um 12:00 Uhr fliegt Bienenschwarm von ca. 1000 g Gewicht innerhalb weniger Minuten ab.
[11.-12.05.] Bienen tragen Nektar bei Temperaturen über 12°C ein.
[13.05.] Manueller Eingriff des Imkers führt zu Gewichtsveränderungen.
Verweise und Link zum Autor
- Sourcen der in Artikel verwendeten Treiber finden sich im Kernel-Source-Tree in den Unterverzeichnissen:
drivers/iio/adc/hx711.c
drivers/iio/pressure/bmp280*.c
- Kernel-Mailing-Liste für das Industrial-IO-Subsystem: linux-iio
- Zur Homepage des Autors geht es hier: www.it-klinger.de.
* Andreas Klinger ist selbständiger Linux-Trainer und Referent der Embedded Linux Woche sowie Gewinner des Best Speaker Awards auf dem ESE Kongress. Er ist als Bio-Landwirt und Imker im Nebenerwerb tätig.
Artikelfiles und Artikellinks
(ID:45131467)