E3930 GPIO mit Linux
« | 28 Aug 2021 | »In meinem Intel Atom Kraftwerk wurde ein neuer Reaktor ans Netz angeschlossen. Und zwar ein Intel Atom E3930 im Supermicro A2SAV-2C-L Mainboard.
Denn seit 3 Jahren arbeitet dessen größerer Bruder E3940 als Server bei mir
und deshalb wagte nie ich sein “spezielles” Feature auszuprobieren.
Beide Boards haben einen 10-Pin Header, über den 8 GPIO
Kontakte frei nach außen geleitet sind.
WARNUNG: Wer Pins am Mainboard kurzschließt kann das Board zerstören. Also bitte meine beschriebenen Schritte NICHT nachmachen bzw. nur mit größter Sorgfalt auf eigene Gefahr probieren.
Angefangen hatte es furchtbar, denn die Lieferung des Boards war ein Alptraum,
und ich hatte die Hoffnung schon aufgegeben es zu erhalten.
Warum sind “einige” Paketdienste in der Lage die Päckchen in einen Shop zu
bringen und darüber zu informieren und andere geben es irgend jemandem im
Wohnblock und finden nicht einmal die Zeit, eine Benachrichtigung an den
eigentlichen Empfänger abzusetzen?
Naja … am Ende mit einigem Herumsuchen hatte ich das Board dann doch
in meinen Händen.
Schon eine Woche zuvor hatte ich mit der Suche im Netz begonnen und gehofft, etwas über die GPIO Ansteuerung zu finden. Doch leider Fehlanzeige.
Im Mainboard-Handbuch stehen die absoluten Adressen der Pins zwar beschrieben, doch wenn man keinen Kernel-Treiber schreibt, hilft einem das nicht. Die Frage war:
Wie kommt man im User-Mode da dran?
Linux sysfs löst alle Probleme
Wenn Linux eines wirklich gut kann, dann ist es: alles in Dateipfade abbilden.
Wenn wir die intern zugeordneten GPIO Pin Nummern kennen und root
Rechte
haben, wird die Sache einfach:
- Man schreibt die GPIO Nummer in die virtuelle Datei
/sys/class/gpio/export
und Linux legt darauf ein Unterverzeichnis mit weiteren “Steuerdateien” an, die den Pin konfigurieren und Bits hinein- und herausschreiben.
z.B.:echo "123" > /sys/class/gpio/export
- Im GPIO-Verzeichnis (z.B.:
/sys/class/gpio/gpio123
) liegen die Dateiendirection
undvalue
, die man ebenfalls Beschreiben oder Auslesen kann. - Wenn man entweder
in
oderout
in diedirection
Datei schreibt, schaltet man den Pin entweder auf Input oder Output, also Stromfluss lesen, oder Strom ein/ausschalten.
z.B.:echo "in" > /sys/class/gpio/gpio123/direction
oder:echo "out" > /sys/class/gpio/gpio123/direction
- In die
value
Datei kann man jetzt entweder die Zahlen1
oder0
hineinschreiben um einen Output-Pin aufhigh
oderlow
zu schalten, was in der Regel3.3
oder0 Volt
bedeutet.
echo "0" > /sys/class/gpio/gpio123/value
Oder man liest die Datei und erhält1
oder0
, wenn eine Spannung am Pin anliegt.
cat /sys/class/gpio/gpio123/value
- Braucht man den Pin nicht mehr, schreibt man seine Nummer in die Datei
/sys/class/gpio/unexport
und Linux entfernt das virtuelle Unterverzeichnis wieder.
Diese Prozedur ist beim Raspberry PI und all seinen ARM Geschwistern bestens bekannt. Doch ob sie auch bei X86 Mainboards klappt, wusste ich bisher nicht.
A2SAV-2C-L GPIO Header
Ärgerlich ist, dass man wenig bis gar keine Infos zu diesem GPIO Header findet (oder vielleicht suche ich falsch…). Denn ich konnte nicht herausfinden, wie sich die 8 Pins am Mainboard in die Linux GPIO Nummern abbilden.
Nach dem Hochfahren von Linux (Debian
11) lieferten alle GPIO Pins gemäß Messung gegen Ground etwa 1.8 V
.
Im /sys/class/gpio
findet man 4 “Chip” Geräte als Verzeichnisse,
und die Dateien label
, base
(Start-Nummer) und ngpio
(Nummern-Anzahl ab
Start) geben folgende Infos preis:
/sys/class/gpio | label | base | ngpio |
---|---|---|---|
gpiochip267 | INT3452:03 | 267 | 43 |
gpiochip310 | INT3452:02 | 310 | 47 |
gpiochip357 | INT3452:01 | 357 | 77 |
gpiochip434 | INT3452:00 | 434 | 78 |
Wir haben also 4 GPIO Bänke, die GPIO PINs ab der Nummer 267 bereitstellen und bis einschließlich zur Nummer 511 reichen.
Also habe ich mir ein kleines Script geschrieben, das bei 267 startend
immer 10 Pins auf out
und low
schaltet. Parallel dazu habe ich immer
per Multimeter die Spannung am Pin gemessen.
Und nach ein paar Iterationen kam ich bei den Pin-Nummern 318 bis 325 an, die offenbar meinen Mainboard Pins zugeordnet waren.
Die folgende Tabelle zeigt den Pin-Header von oben nach unten, wenn das Mainboard so liegt, dass “oben” LAN, USB und Displayanschlüsse liegen:
Nummer | Links | Rechts | Nummer |
---|---|---|---|
- | 3.3 V | 0 V | - |
325 | GP0 | GP4 | 321 |
324 | GP1 | GP5 | 320 |
323 | GP2 | GP6 | 319 |
322 | GP3 | GP7 | 318 |
Input geht, aber keine Output-Spannung möglich
Spannung lesen funktioniert, denn mit
sieht man, ob der rechte untere Pin mit Ground verbunden ist, denn dann
liefert value
eine 0
. Ist er nicht verbunden oder gegen 3.3 Volt
gezogen, sehen wir 1
.
Damit lässt sich schon ein Taster abfragen, der den Pin mit Ground verbindet.
Drückt jemand darauf, sieht man das an der 0
, ansonsten kommt immer 1
.
Im Output Modus wird der Pin mit Ground verbunden. Leider schaltet er aber
nicht auf Spannung um, wenn man eine 1
in value
schreibt.
Der Pin ist also immer low
, wenn er als Output-Pin betrieben wird.
Das schränkt den Handlungsspielraum natürlich stark ein.
Aber eine Sache bekommt man trotzdem hin:
Man nehme eine blaue LED, die
3.3 Volt verträgt (oder eine schwächere mit Vorwiederstand) und verbindet
damit einen GPIO Pin mit 3.3 V auf POWER. Wenn man jetzt zwischen Input und
Output Modus umschaltet, geht die LED an und aus, denn im Output low
Modus
fließt Strom mit 3.3 Volt vom POWER Pin zum GPIO Pin.
Schaltet man aber auf Input, fließt Strom mit 1.8 Volt, was die blaue
LED sprichwörtlich kalt lässt.
Es fließt also immer Strom durch die Leuchtdiode, nur im Input-Modus ist er
zu schwach um gesehen zu werden.
Nutzt man eine niedriger betreibbare rote LED im Input-Modus, kann man erkennen, dass auch die 1.8 Volt ein ganz schwaches kleines Lichtpünktchen auslösen.
Vorsicht, Reboot möglich
Nur als kleine Warnung am Rande:
Ich habe auch weitere Pins mal auf 0
gesetzt und irgendwo ab Nr. 340 löste
mein Mainboard einen Reboot aus. Zwischen 360 und 511 passierte nichts
Bemerkbares mehr.
Entweder liegt da so um Nr. 350 eine Verbindung zum Power oder Reset-Button
oder eine andere Funktion löst den Reboot des Systems aus.
Man lernt jedenfalls daraus:
Wer irgendwelche unbekannten Pins abklopft, kann böse Überraschungen erleben. Also immer alles vor dem Experiment sichern!
Fazit
Also, diese Spielerei hat mir viel Spaß gemacht. Ohne Infos und Dokus wurden die Funktionen geschwind “reverse engineered” und zumindest ein paar Anwendungsmöglichkeiten festgestellt.
Tatsächlich könnte man sich mit der LED eine primitive Anzeige basteln. z.B.: ein Ping jede Minute und wenn die Gegenseite erreichbar ist, leuchtet die LED, andernfalls nicht, oder gerne auch umgekehrt.
GPIO Pins am X86 PC Mainboard sollten aus meiner Sicht überall Pflicht sein. Viele Intel CPUs und Chipsätze bringen dieses Feature mit, nur leider sind so gut wie nie Pins am Mainboard nach außen gelegt.
In diesem Fall muss ich SuperMicro loben, weil sie zumindest ein paar Boards mit dieser genialen Option ausgestattet haben.