LicheePI Zero einrichten
- Einleitung
- Fertige Linux Images nutzen
- Linux Kernel kompilieren
- Compiler und Build-Toolchain vorbereiten
- Kernel konfigurieren und übersetzen
- Neuen Kernel installieren
- Administration per serieller Verbindung
- GPIO Pins
- Pin Funktionen
- Digitale Pins per sysfs ansteuern
- Weitere Infos
Einleitung
Wenn er hochfährt, meldet er sich als:
1 CPU: Allwinner V3s (SUN8I 1681)
2 Model: Lichee Pi Zero
3 DRAM: 64 MiB
Der “Lichee Zero” und der “Lichee Nano” sind
System-On-Chip Modelle, die ähnlich wie der Raspberry PI
kleine Systeme für IOT
und Thinclients bereitstellen.
Das folgende Tutorial bezieht sich auf den “Lichee Zero”.
Für den Nano müssen entsprechend andere Kernel-Images genutzt werden,
der Ablauf von Build und Konfiguration sollte aber recht ähnlich sein.
Die CPU des Lichee Zero läuft zwar mit 1.2 GHz, aber mit nur 64 MB RAM liegt
er weit unter den Möglichkeiten eines Raspberry PI Zero mit 512 MB RAM.
Trotzdem erfüllt er alle Voraussetzungen um kleine Projekte umsetzen zu können.
Etwas mühsam mit dem Chip ist das Finden bzw. das Aufsetzen des
Betriebssystems.
Denn im Gegensatz zum Raspberry PI, für den es viele Linux Distributionen gibt,
muss man bei Lichee Modellen entweder sein eigenes Linux zusammenbauen, oder
ein fertiges Image finden und dann nachrüsten.
Fertige Linux Images nutzen
Unter dem Link dl.sipeed.com/LICHEE findet man
eine Liste von Images für unterschiedlich Lichee Varianten.
Komprimierte RAW-Disk Images befinden sich unter
dl.sipeed.com/LICHEE/Zero/Images/dd_img
und können nach dem Entpacken 1 zu 1 per Tools wie
dd oder
Win32DiskImager auf eine
MicroSD Karte transferiert werden.
Wer seinen Lichee Zero mit LCD Screen ausgestattet hat, kann das
Debian LXDE Image lichee_zero_test_Debian_LXDE.tar.bz2
nutzen
und das System als Desktop-Umgebung nutzen.
Ansonsten bietet sich minmin_dd.tar.bz2
an, in dem außer der
Paketverwaltung apt
und den Linux-Basis Tools sonst nichts installiert
ist.
Benötigte Software lässt sich dann per apt install
nachrüsten.
Das Image arbeitet mit 2 Partitionen. Einer FAT-Boot Partition, wo das Linux
Kernelimage liegt und einer EXT Partition, die während der Linux Sitzung
genutzt wird.
Da bei meinem Modell die Ethernet Schnittstelle mit dem Basis-Image nicht
funktioniert hat und mir Treiber für USB-LAN und WLAN Adapter gefehlt haben,
musste ich den Linux-Kernel neu kompilieren, was nachfolgend beschrieben
wird.
Den Linux Kernel kompilieren
Nachdem wir üblicherweise auf PCs arbeiten (X86 oder X64) brauchen wir einen
Compiler für ARM Systeme um die Quellcodes richtig zu übersetzen.
Diesen müssen wir erst herunterladen und installieren.
Das sollte unter jeder gängigen Linux-Distribution funktionieren und sogar
unter Windows 10 mit dem Subsystem für Linux
durchführbar sein.
Man hat zwei Möglichkeiten:
- Wir installieren den Compiler über das Paketverwaltungssystem der
Distribution.
z.B.:
sudo apt-get install gcc-arm-linux-gnueabihf
- Vorteil: Schnelle und korrekte Installation
- Nachteil: Version kann variieren und eventuell kommt es zu Fehlern beim
Übersetzen der Quelltexte.
- Oder: Wir laden uns den Compiler manuell herunter und richten ihn selbst
ein.
- Vorteil: Perfekt passende Tool-Chain
- Nachteil: Muss manuell eingerichtet werden.
GCC für ARM durch Distribution installieren
Ob eine Linux Distribution einen ARM-Crosscompiler anbietet, ist je nach
Hersteller und Version verschieden.
Für uns ist wichtig, dass am Ende der Compiler mit dem Aufruf von
arm-linux-gnueabihf-gcc
ausgeführt werden kann.
Folgende Installationsaufrufe haben bei mir funktioniert:
- Ubuntu und Debian:
sudo apt-get install gcc-arm-linux-gnueabihf
- Wir starten im Home-Verzeichnis des angemeldeten Benutzers
cd
- Download eines Compilers für ARM Systeme, damit wir den Kernel kompilieren
können:
wget https://licheepizero.us/arm-linux-gnueabihf/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xz
- Entpacken des Archives mit der Compiler Toolchain:
tar xvf gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf.tar.xz
- Anlegen eines “zentralen” Verzeichnisses, wo wir den Compiler
hinverschieben werden:
sudo mkdir -m777 /opt/gcc-6.3.1_arm
- Verschieben der Compiler-Toolchain:
mv gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/* /opt/gcc-6.3.1_arm/
- Pfad zum Compiler bereitstellen:
- Wer den Vorgang nur einmal braucht, kann den Pfad direkt einbinden:
export PATH="$PATH:/opt/gcc-6.3.1_arm/bin/"
- Wer den Compiler auch in Zukunft braucht, kann ihn ins Start-Script
aufnehmen:
echo PATH="\$PATH:/opt/gcc-6.3.1_arm/bin/" >> ~/.bashrc
Hat alles geklappt, liefert der Aufruf von
arm-linux-gnueabihf-gcc -v
die Version des ARM Compilers zurück und wir können mit dem Kompilieren starten.
Kernel konfigurieren und übersetzen
- Wir holen uns die Quelldateien von Github
git clone https://github.com/Lichee-Pi/linux.git
Es existieren mehrere Branches des Kernels, wobei zero-4.10
als
Standard-Konfiguration übermittelt wird. Man kann also auf andere Stände
per git checkout
wechseln, die neueste Version 5.2
konnte ich
allerdings nie zum Laufen bekommen.
- Nun wechseln wir ins neu angelegte Unterverzeichnis linux
cd linux
- Und starten das Erzeugen der Standard-Konfiguration
make ARCH=arm licheepi_zero_defconfig
- Als nächstes bauen und starten wir das Konfigurationsmenü mit:
make ARCH=arm menuconfig
Hier können alle möglichen Einstellungen des Kernels und
das Einbinden weiterer Treiber vorgenommen werden.
- Nach der Konfiguration beginnt der Build-Vorgang des Kernels
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j3
Der Parameter -j3
lässt 3 Tasks parallel laufen, wer mehr
CPU Kerne parat hat, kann die Zahl natürlich erhöhen.
-
Danach können externe Kernel-Module gebaut werden.
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j3 INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j3 INSTALL_MOD_PATH=out modules_install
Diese Schritte sind nur erforderlich, wenn solche Module auch konfiguriert
wurden.
Nachdem der Kernel fertig übersetzt wurde, sollte das neue Kernel-Image namens
zImage
im Unterverzeichnis linux/arch/arm/boot
liegen.
Neuen Kernel installieren
Vorherigen Kernel einfach überschreiben
Hat man bereits ein fertiges SD-Karten Image, kann man einfach die erste
Partition mit FAT Dateisystem mounten und die neue zImage
Datei über
die alte kopieren.
Unter Windows wird diese Partition als einzige erkannt und steht damit
ebenfalls gleich nach Einlegen der SD Karte ins Lesegerät zur Verfügung.
Hat man Windows Services für Linux genutzt, muss man nur noch das Linux
rootfs
Verzeichnis auf der Festplatte finden. Es liegt unter
C:\Users\%WINDOWSUSER%\AppData\Local\Packages\
+
Linux-Distributions-Paket +
\LocalState\rootfs\home\$LINUXUSER\linux\arch\arm\boot
Im Fall von Ubuntu 18.04 lautet der Name des Distributions-Verzeichnisses:
CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc
Gesamtes Image neu erstellen
Will man das gesamte Boot Image neu erstellen, muss man auch einen neuen
Stand des angepassten u-boot
Bootloaders bauen und das SD-Karten Image
manuell neu zusammensetzen.
Eine Anleitung für diese Prozedur befindet sich unter:
licheepizero.us/build–uboot-for-licheepi-zero
Kompliziert daran ist, dass die Daten an bestimmte Positionen der SD Karte
geschrieben werden müssen und nicht einfach ins Dateisystem kopiert
werden dürfen.
Bekannte Probleme
Während des Updates bzw. der Installation von Software mit
apt
über meinen per USB angesteckten LAN-Adapter kam es
immer wieder zu Unterbrechungen der Verbindung.
Die Übertragung endete und es dauerte dann ein paar Minuten
bis die Software ein Response-Timeout meldete und abbrach.
In diesem Fall half ein einfach ifdown
gefolgt von einem
ifup
um die Netzwerkschnittstelle wieder zum Laufen zu
bekommen.
apt
konnte dann erneut gestartet werden und setzte dort
fort, wo es zuvor abgebrochen wurde.
Das Update verlieft auf diese Weise leider sehr schleppend,
am Ende konnte ich aber dennoch die Distribution auf den
neuesten Stand bringen.
Administration per serieller Verbindung
Wenn der Lichee Zero ohne LCD-Panel betrieben wird, kann man ihn am einfachsten
über die serielle Schnittstelle über die UART-0 PINs verwalten.
Die Linux Images nutzen diese Schnittstelle als Standard-Ein/Ausgabe und
somit hat man auf einfache Weise ohne Netzwerk eine Linuxkonsole parat.
Von unten gezählt sind der 6. und 7. linke Pin für das Empfangen und Senden
von Daten bestimmt. Gegenüber stellt von unten der 9. Pin noch Ground dar,
womit wir alle drei Leitungen haben, über die wir eine Kommunikation mit
einem TTL-Serial-to-USB Adapter zum PC herstellen können.
Die Stromversorgung kann entweder der USB Port übernehmen, oder falls
dieser für etwas anderes benutzt wird, nutzt man einfach die beiden
zusätzlichen Pins gleich rechts neben der linken GPIO-Pin-Leiste,
wo man am untersten Pin 5 Volt einspeisen und einen Pin darüber den
Ground anlegen kann.
Unter Windows helfen uns Tools wie PuTTY
um die serielle Verbindung zu nutzen und gleichzeitig die VT-100 Kommandos von
Linux richtig anzuzeigen.
Man wählt die Option Serial
im Konfigurationsdialog und trägt bei
Serial line den COM-Port des USB-Adapters ein, z.B.: COM4
.
Als Geschwindigkeit nutzt der Lichee die vollen 115200
Baud, also wird
dieser Wert unter Speed in PuTTY eingetragen.
Nun wird eine bespielte MicroSD-Karte ins Gerät eingelegt und die serielle
Verbindung in PuTTY gestartet.
Wir der Lichee nun mit Strom versorgt werden, sollten kurze Zeit später die
ersten Zeichen im Konsolenfenster erscheinen und den Linux Boot-Vorgang
dokumentieren.
Die Anmeldung erfolgt mit Benutzer root
und dem Passwort toortoor
.
Laut Doku gibt/gab es auch Images mit dem Root-Passwort licheepi
.
Man muss also nachlesen bzw. ausprobieren, welches Passwort zum
benutzten Image passt.
GPIO Pins
Insgesamt 30 Pins kann man mit “normalen” Pinheadern versehen (2.54mm Abstand),
wie man es von Arduino Systemen kennt, um Projekte daran zu betreiben.
Tatsächlich wären fast doppelt so viele verfügbar, wenn man mit den kleineren
1.27mm Pins arbeiten würde … doch dafür besitze ich keine Hardware und auch
das Löten wäre bei diesen kleinen Abständen recht schwer.
PIN-Funktionen
Fast jeder PIN lässt sich als digitaler Ein- oder Ausgang nutzen. Aber wenn
man I2C oder SPI
nutze möchte, sollte man deren reservierte Pins unberührt lassen.
WICHTIG: Keinesfalls sollte man die letzten Pins auf der rechten Seite
anfassen, denn diese laufen zur SD-Karte von der meist gebootet wird.
Linux würde in diesem Fall nicht mehr auf die Karte zugreifen können
und ein fataler Fehlerfall (de facto ein Absturz) bahnt sich dann an!
Den 2. SD-Karten-Slot kann man sowohl für eine Datenkarte oder auch
als WLAN-Erweiterung nutzen. In diesem Fall wären auch die oberen Pins
der rechten Seite Tabu.
Digitale Pins per sysfs ansteuern
Viele System-on-Chip Boards stellen ihre Pins in Linux durch das
sysfs
einfach im Dateisystem bereit.
- Man schreibt die Pin-Nummer in die virtuelle Datei
/sys/class/gpio/export
z.B.: echo "192" > /sys/class/gpio/export
- Dann geht setzt man den Pin auf Input oder Output über die
direction
Datei im Pin-Unterverzeichnis, namens
/sys/class/gpio/gpioXXX/direction
z.B.: echo "in" > /sys/class/gpio/gpio192/direction
oder
z.B.: echo "out" > /sys/class/gpio/gpio192/direction
- Nun kann man über die
value
Datei den Pin-Status lesen
oder schreiben.
z.B.: echo "1" > /sys/class/gpio/gpio192/value #set HIGH
z.B.: echo "0" > /sys/class/gpio/gpio192/value #set LOW
z.B.: cat /sys/class/gpio/gpio192/value #returns: 0=LOW, 1=HIGH
- Wird der Pin nicht mehr gebraucht, kann er per
unexport
wieder
freigegeben werden.
z.B.: echo "192" > /sys/class/gpio/unexport
1 echo "192" > /sys/class/gpio/export
2 echo "out" > /sys/class/gpio/gpio192/direction
3 echo "0" > /sys/class/gpio/gpio192/value #PIN PG0 LOW, grüne LED ein
4 echo "1" > /sys/class/gpio/gpio192/value #PIN PG0 HIGH, grüne LED aus
5 echo "192" > /sys/class/gpio/unexport
Name |
Nummer |
Funktion |
Weitere Info |
PE21 |
149 |
UART1_TX |
|
PE22 |
150 |
UART1_RX |
|
PB0 |
32 |
UART2_TX |
|
PB1 |
33 |
UART2_RX |
|
PB4 |
36 |
PWM0 |
|
PB5 |
37 |
PWM1 |
|
PB6 |
38 |
TWI0_SCK |
I2C / TWI |
PB7 |
39 |
TWI0_SDA |
I2C / TWI |
PB8 |
40 |
UART0_TX |
Serielle Konsole Senden |
PB9 |
41 |
UART0_RX |
Serielle Konsole Empfang |
PC1 |
65 |
SPI0_CLK |
SPI |
PC3 |
67 |
SPI0_MOSI |
SPI |
PC0 |
64 |
SPI0_MISO |
SPI |
PC2 |
66 |
SPI0_CS |
SPI |
|
|
+5V |
5 Volt Ausgang |
Name |
Nummer |
Funktion |
Weitere Info |
PG0 |
192 |
SDC1_CLK |
0 → Grüne LED |
PG1 |
193 |
SDC1_CMD |
0 → Blaue LED |
PG2 |
194 |
SDC1_D0 |
0 → Rote LED |
PG3 |
195 |
SDC1_D1 |
|
PG4 |
196 |
SDC1_D2 |
|
PG5 |
197 |
SDC1_D3 |
|
|
|
GND |
Ground Ausgang |
|
|
+3V |
3.3 Volt Ausgang |
|
|
KEY |
Referenz Spannung |
PF0 |
160 |
SDC0_D1 |
SD-Karte |
PF1 |
161 |
SDC0_D0 |
SD-Karte |
PF2 |
162 |
SDC0_CLK |
SD-Karte |
PF3 |
163 |
SDC0_CMD |
SD-Karte |
PF4 |
164 |
SDC0_D3 |
SD-Karte |
PF5 |
165 |
SDC0_D2 |
Letzter PIN rechts |
Fortsetzung folgt…
Weitere Infos