BeagleBone Black: Herzstillstand – die Heartbeat-LED abschalten

Der BeagleBone Black hat vier User LEDs oberhalb des USB-Anschlusses, die vom Nutzer konfiguriert werden können. Eine davon blinkt standardmäßig zwei mal pro Sekunde im Herzrhythmus. Bei einer Dauernutzung kann das ausgesprochen lästig sein. Mein BBEowulf läuft Tag und Nacht und die blauen LEDs sind extrem hell. Die Herzschlag-LEDs meiner BBB’s blinken zudem leicht nacheinander, so dass pro Sekunde ständig neun LEDs aufleuchten. Man kann diese Heartbeat-Animation jedoch auch leicht abschalten – zumindest bis zum nächsten Neustart. Will man die LED dauerhaft aktivieren, muss man mit einem Cronjob oder dem Device Tree arbeiten.

Die fünf LEDs auf der Boardoberseite. USR0 blinkt im Heartbeat-Rhythmus

Die fünf LEDs auf der Boardoberseite. USR0 blinkt im Heartbeat-Rhythmus

 

Neben der PWR-LED, die immer leuchtet, wenn der BeagleBone Black unter Strom steht und läuft, haben die Designer dem Board noch vier LEDs spendiert, die standardmäßig folgendermaßen konfiguriert sind:

  • USR0: blinkt im Herzrhythmus
  • USR1: blinkt bei Zugriff auf die SD-Karte
  • USR2: blinkt bei CPU-Last
  • USR3: blinkt bei Zugriff auf den eMMC-Speicher

Diese Funktionen können aber geändert werden. Dazu werfen wir einen Blick ins /sys-Verzeichnis:.

Was ist das Sys-Verzeichnis?

sysfs ist ein virtuelles Dateisystem, dass Informationen über die Hardware in Form eines Dateibaumes verfügbar macht. Das ist notwendig, da, vereinfacht gesagt, die meisten Geräte und deren Treiber normalerweise eng an den Kernel gekoppelt sind, der einen eigenen Speicherbereich für sich beansprucht (Kernel mode), während die meisten Programme und Bibliotheken in einem anderen Speicherbereich laufen (User mode). Sysfs exportiert die Geräteinformationen in den User mode und macht sie somit für Software und die Benutzer zugänglich. Gemäß dem Linux-Grundsatz „Alles ist eine Datei“, sind auch die Hardware-Komponenten eines Computers im Dateisystem abbildbar – und genau diese Abbildung finden wir im /sys-Verzeichnis. In unserem Fall können wir dank der bereitgestellten Optionen die LEDs direkt innerhalb dieses Verzeichnisses manipulieren.

Operation am offenen Herzen

# ls -F /sys/class

Die Liste offenbart einige interessante Ansatzpunkte zum Ansprechen der Hardware, z.B. das /gpio-Verzeichnis. Für unsere Zwecke interessant ist jedoch das /leds-Verzeichnis:

# cd /sys/class/leds # ls -1F
beaglebone:green:usr0@ beaglebone:green:usr1@ beaglebone:green:usr2@ beaglebone:green:usr3@

Hier sehen wir die 4 USR-LEDs. Warum diese grün und nicht blau heißen, weiß ich nicht, aber das tut auch nichts weiter zur Sache. Wir wollen die LED USR0 manipulieren, also wechseln wir ins entsprechende Verzeichnis. Die Schreibweise ist etwas unangenehm. Wer in seiner Shell nicht mit Autovervollständigen arbeitet, der muss Escape-Sequenzen vor die Doppelpunkte setzen.

# cd beaglebone\:green\:usr0 # ls -F
brightness device@ max_brightness power/ subsystem@ trigger uevent

Die jetzt ausgegebene Liste offenbart bereits ein paar Einstellungsmöglichkeiten. Uns interessiert insbesondere der Punkt trigger:

# cat trigger
none nand-disk mmc0 mmc1 timer oneshot [heartbeat] backlight gpio cpu0 default-on transient

Wir sehen, dass hier eine Option heartbeat voreingestellt ist, erkennbar an den eckigen Klammern. Was wohl passiert, wenn wir none aktivieren?

# echo none > trigger
# cat trigger
[none] nand-disk mmc0 mmc1 timer oneshot heartbeat backlight gpio cpu0 default-on transient

Bingo! Die LED leuchtet nicht mehr. Was aber bringen die anderen Optionen? Das ist nicht gerade leicht, herauszufinden. Selbst im offiziellen Benutzerhandbuch findet sich nicht wirklich etwas zu diesem Thema. Zum Teil musste ich raten, was ich mit einem Fragezeichen gekennzeichnet habe. Da der Linux-GPIO-LED-Treiber jedoch nicht speziell auf den BeagleBone Black zugeschnitten ist, ist es auch gut möglich, dass einige der Funktionen keine Bedeutung haben.

  • none: deaktiviert die LED dauerhaft
  • nand-disk: Hat beim BBB keine Bedeutung, da kein NAND-Speicher vorhanden ist* (?)
  • mmc0: Lässt die LED bei Zugriff auf den eMMC-Speicher leuchten (Standard: USR3)
  • mmc1: Lässt die LED bei Zugriff auf die SD-Karte leuchten (Standard: USR1)
  • timer: Ermöglicht es, die An-Aus-Zeiten der LED im Millisekundenbereich manuell einzustellen
  • oneshot: lässt die LED einmalig aufblinken (?). Hat vermutlich vor allem Sinn in Verbindung mit System- oder GPIO-Ereignissen. Kann invertiert werden
  • heartbeat: lässt die LED im Heartbeat-Rhytmus blinken
  • backlight: (?) (vermutlich nicht relevant für den BBB)
  • gpio: Ermöglicht die Kopplung der LED an einen GPIO-Pin
  • cpu0: Lässt die LED bei CPU-Last leuchten (Standard: USR2)
  • default-on: aktiviert die LED dauerhaft
  • transient: (?) (wörtlich übersetzt: von kurzer Dauer, vorübergehend. Worin der Unterschied zu oneshot liegt, weiß ich nicht.)

* das Beagleboard verfügt anstatt eMMC- über NAND-Speicher

Bei einigen dieser Optionen verändert sich der Inhalt des LED-Verzeichnisses:

# echo timer > trigger
# ls -F
brightness delay_on max_brightness subsystem@ uevent delay_off device@ power/ trigger

Uff! Im ersten Moment kann das ziemlich verwirrend sein. Aufgrund des Linux-Mantras „Alles ist eine Datei“ befinden wir uns hier in einem Dateisystem, in dem einfach so Dateien auftauchen und verschwinden, wenn wir eine andere Datei verändern! Alles halb so wild! Die neuen Optionen ergeben ja durchaus einen Sinn – und zwar nur in diesem speziellen Fall.
Die Auswahl timer lässt nämlich, wie oben gezeigt, zwei neue Optionen delay_on und delay_off erscheinen, mit denen die Leuchtdauer und die Pause der LED in Millisekunden eingestellt werden kann, also z.B.

# echo 100 > delay_on
# echo 900 > delay_off

Jetzt sollte die LED im Sekundentakt eine 100stel-Sekunde lang aufblinken. Auch die Helligkeit der LEDs soll zwischen 0 bis 255 eingestellt werden können. Das funktioniert de-facto jedoch nicht (außer, dass die LED mit 0 aus ist). Wie gesagt, der GPIO-LED-Treiber ist nicht speziell auf den BeagleBone zugeschnitten und wer sich die Dokumentation anschaut, wird feststellen, dass die LEDs derart verdrahtet sind, dass sie nur ein- oder ausgestellt werden können.

# echo 10 > brightness
# echo 0 > brightness
# echo 255 > brightness

Wer die LEDs unbedingt dimmen möchte, kann allerdings ein künstliches PWM-Verhalten selbst erzeugen. Was war nochmal PWM? Hier ein Seitenverweis zu meinem Artikel über Computerlüfter. Dafür stellt man im timer-Triggermodus möglichst kurze on– und off-Zeiten ein:

# echo 1 > delay_on
# echo 10> delay_off

Der Spielraum ist hier allerdings recht klein, denn ein Wert von über 20 lässt die die LED bereits sichtbar flackern. Kleine Veränderungen sind überdies kaum wahrnehmbar. Im Allgemeinen ist diese PWM-Emulation also kaum von größerem Nutzen.

Aber wir wollen das ja sowieso alles nicht. Stellen wir die LED also lieber wieder aus!

# echo none > trigger

Aaaaaaah, sehr gut!!!

Nach einem Neustart wurde die LED wiederbelebt

Unglücklicherweise sind die Änderungen, die wir durchgeführt haben, nur von kurzer Dauer. Wenn der BBB neu gestartet wird, blinkt’s wieder wie vorher. Also was tun?

Schaut man sich im beim Auslieferungszustand installierten Ångström Linux ein wenig um, so bemerkt man, dass dort ein Systemd-Service namens leds.service läuft. Mit diesem Service kann man scheinbar zum Systemstart die Trigger-Werte der LEDs verändern. Der Haken ist nur, dass dieser Service keinerlei Wirkung hat – weder unter Ångström, noch portiert auf Arch Linux.

Diese verlockend einfache Möglichkeit scheidet also aus. Es bleiben aber noch zwei weitere.

Cron

Cron ist ein Unix-Tool, welches es ermöglicht, Aufgaben in wiederkehrenden Zeiteinheiten durchzuführen. Es wird gerne zur Systemwartung genutzt. Was wäre, wenn wir einen Cronjob einrichten, der die User-LED vom Blinken abhält?

Erstellen wir zunächst ein Shellscript:

# touch /usr/bin/disable-led.sh
# chmod +x /usr/bin/disable-led.sh
# nano /usr/bin/disable-led.sh

#! /bin/bash
echo none > /sys/class/leds/beaglebone\:green\:usr0/trigger

Jetzt müssen wir die Crontab editieren. Die Crontab enthält Informationen darüber, welche Shellscripts oder Kommandobefehle wann ausgeführt werden sollen.

env EDITOR=nano crontab -e

@reboot /usr/bin/disable-led.sh

Der Eintrag bewirkt, dass bei jedem Systemstart das disable-led.sh – Skript ausgeführt wird.

Anschließend aktivieren wir noch den cronie-Service und starten neu:

# systemctl enable cronie
# systemctl start cronie
# reboot

Die LED blinkt beim Neustart zwei, drei mal auf, um dann aus zu bleiben. DAUERHAFT!

Device Tree

Wer ansonsten nicht mit Cronjobs arbeitet, für den stellt sich die Frage, ob es sich lohnt, extra einen Systemdienst wegen dieser Kleinigkeit zu starten. Es gibt eine Alternative, die ebenfalls funktioniert, nämlich die Manipulation des Device Trees.

Vorab ein wenig Hintergrundwissen. Bevor die ARM-Architektur, auf der RaspberryPi, BeagleBone Black, Samsungs Chromebook und viele viele andere Geräte (z.B. praktisch alle aktuellen Smartphones) basieren, so populär wurde, ging es in der Prozessorwelt verhältnismäßig geordnet zu. Intes x86-Prozessoren, AMDs Konkurrenzen beherrschten den Markt. Diese waren innerhalb ihrer Modellvielfalt recht einheitlich, was auch für die umgebende Hardware-Architektur gilt (Stichwort Chipsatz). Das Design des Linux-Kernels konnte allgemein gehalten werden und es war ziemlich sicher, dass die Treiber der umgebenden Komponenten vom Kernel ohne großes Zutun geladen wurden.

Ganz anders schaut das in der ARM-Welt aus. Zu einer Vielzahl von unterschiedlichen ARM-Prozessoren und System-on-Chip-Lösungen kommen ebenso viele Unterschiede in der umgebenden Hardware-Architektur (man vergleiche nur einmal Raspberry Pi und BeagleBone Black). Der Grund für diese Vielfalt und gleichzeitig für den Erfolg der ARM-Prozessoren ist wohl hauptsächlich darin zu suchen, dass ARM Limited selbst nur Lizenzen für ARM-Prozessoren verteilt, selbst aber keine herstellt.

Das Konzept hat sich zweifelsohne bewährt, die Kernel-Entwickler stellt das allerdings vor ein gewaltiges Problem. Wie soll man mit dieser erschlagenden Vielfalt umgehen? Anfänglich wurde für jedes unterstützte ARM-Board ein eigener Kernel kompiliert. Das wurde allerdings sehr schnell unpraktikabel. Letztendlich hat man sich zu einer Methode entschlossen, die schon vorher für PowerPC- und SPARC-Systeme genutzt wurde. Für die ARM-Plattform führte man eine Art Hardware-Verzeichnis ein, sozusagen als Lexikon für den Kernel. In diesem Verzeichnis ist die verfügbare Hardware des jeweiligen Gerätes mitsamt ihren Eigenschaften baumartig aufgelistet. Dieses Verzeichnis nennt man Device Tree.

Der Device Tree besteht aus device tree binary files (dtb). Diese Dateien befinden sich auf der Boot-Partition:

# ls -F /boot/dtbs/
am335x-boneblack.dtb omap3-beagle.dtb omap4-panda-es.dtb
am335x-bone.dtb omap3-beagle-xm.dtb omap4-sdp.dtb
am335x-evm.dtb omap3-evm.dtb omap4-var-som.dtb
am335x-evmsk.dtb omap3-tobi.dtb omap5-evm.dtb
am335x-tester.dtb omap4-panda-a4.dtb
omap2420-h4.dtb omap4-panda.dtb

Da diese Dateien im Binärformat vorliegen, müssen wir sie dekompilieren (Endung dts – device tree source file), um sie lesen und editieren zu können. Dazu müssen wir ein Paket installieren:

# pacman -S dtc-overlay

Mit dem Device Tree Compiler (dtc) können wir dtb-Dateien kompilieren und dekompilieren. Um an die entsprechende Einstellung für unsere User-LEDs zu kommen, müssen wir die Datei am335x-boneblack.dtb dekompilieren:

# cd /boot/dtbs
# dtc -O dts -I dtb -o am335x-boneblack.dts am335x-boneblack.dtb
# cp am335x-boneblack.dts am335x-boneblack.dts.bak
# nano am335x-boneblack.dts

Die dekompilierte Datei hat über 1300 Zeilen. Wir suchen deshalb gezielt nach folgender Zeile:

linux,default-trigger = "heartbeat";

Die Änderung ist trivial: „heartbeat“ wird zu „none“. Wir speichern die Datei und rekompilieren sie:

# dtc -O dtb -I dts -o am335x-boneblack.dtb am335x-boneblack.dts
# reboot

Nach dem Neustart leuchtet die Heartbeat-LED nicht ein einziges Mal mehr auf.

Operation gelungen – Patient tot.

Welchen Weg man verfolgt, ob Cronjob oder Device Tree, bleibt jedem selbst überlassen. Wer zu einem späteren Zeitpunkt Capes für den BBB verwenden will, wird sich ohnehin noch intensiver mit dem Device Tree auseinander setzen müssen. Das Deaktivieren der LED ist ein gutes Einstiegsbeispiel zum Üben. Wer hingegen, so wie ich, Cronjobs verwendet, um sein System zu administrieren, der wird sich vermutlich eher mit dem entsprechenden Weg anfreunden können. Funktionieren tut beides. In beiden Fällen ist es auch möglich, die LED im Bedarfsfall noch manuell zu steuern, mit Hilfe des oben gezeigten Weges über /sys/class/leds/.

GD Star Rating
loading…

BeagleBone Black: Herzstillstand – die Heartbeat-LED abschalten, 5.0 out of 5 based on 2 ratings

Dieser Blogeintrag wurde 4659 mal gelesen.

Kategorien: Computer, Hardware und Single Board Computer.