Displayanbindung über Framebuffer
Autor: Bernhard
14.02.2019
gestern hatte ich dem iRadio ein "Treiberpaket" mit Democode für einen
Displaydaemonen mitgegeben. Damit ist es möglich, fernab von einem
grafischen Grundsystem in Linux, durch Grafikprimitiven eine eigene
Benutzeroberfläche zu programmieren. Unser HolgerK hat ja schon gezeigt
wie schön soetwas funktioniert und seinen Code als Patch für das iRadio zur Verfügung gestellt. Vielen Dank nochmal.
Per Email erhielt ich heute eine Anfrage, ob es denn nicht auch möglich
ist, die FLTK-Oberfläche (weiter vorn in diesem Thread) auf so einem
Display laufen zu lassen.
Ja klar geht das, man könnte sogar (mit Einschränkungen) unsere
Skalensimulation auf solche Displays bringen. Das geht über das
Framebuffer von Linux für eine ganze Reihe von Displays! Allerdings muss
man sich auch fragen ob eine Skalensimulation auf einem monochromen
128x64 Pixel großem OLED mit SSD1306-Controller überhaupt Sinn macht.
Theoretisch ist es möglich. Ich möchte anhand eines 128x160 Pixel
großen Displays, mit ST7735 Controller, mal zeigen wie die Einrichtung
erfolgt.
Den meisten Linuxdistributionen für Raspberrys und anderen SoCs hat man
für solche Kleindisplays bereits Framebuffer-Treiber mitgegeben, diese
müssen nur noch aktiviert, sprich beim Systemstart geladen werden.
Welche Displays von dem Framebuffer unterstützt werden, kann man hier sehen:
https://github.com/notro/fbtft/wiki/LCD-Modules
Weiter unten auf der verlinken Seite sind die Display abgebildet und
teilweise schon mit den Namen versehen, wie man sie bei ebay oder Amazon
findet.
Die Standardpinbelegung ist ebenfalls aufgeführt, kann aber abgeändert werden.
Beispielhaft nehme ich ein Display von Saintsmart, welches auf der Seite
nicht abgebildet ist. Ich weis aber das das Display ein
ST7735-Controller besitzt, über SPI angesteuert wird und kann es somit
dennoch verwenden.
Wie gehe ich vor.
1. ) Zunächst muss ich beim Raspbian (oder einer anderen Distribution) die SPI-Schnittstelle aktivieren.
In Raspbian geht das auf zwei Arten.
1a.) Aktivieren über das Raspbian-inkludierte Programm raspi-config. In
ein Terminal gebe ich zum Start dieses Programms folgendes ein:
sudo raspi-config
Danach erhalte ich folgenden Bildschirm:
SPI aktiviere ich unter Option 5.
Damit wäre SPI nach einem Reboot aktiviert.
1b.) ODER: Ich öffne die Datei config.txt die in /boot liegt und entkommentiere die Zeile dtparam=spi=on
Nach dem Speichern der Datei und einem Reboot ist die SPI-Schnittstelle des Raspberrys ebenfalls einsatzbereit.
2.) Nun sorge ich dafür das die Framebuffer-Treiber beim Systemstart geladen werden.
Ich öffne dazu die Datei /etc/modules-load.d/fbtft.conf , wenn diese noch nicht existiert, dann lege ich sie gleich mit an.
In diese Datei schreibe ich folgenden Inhalt:
spi-bcm2835
fbtft_device
Beim nächsten Neustart wird also der Framebuffertreiber fbtft_device
gestartet. Nun muss ich nur noch mitteilen welches Display denn am
Raspberry hängt.
Dazu schaue ich nochmal auf die Seite https://github.com/notro/fbtft/wiki/LCD-Modules und suche welches Display dort mit dem ST7735-Controller ausgestattet ist.
In der Tabelle "FBTFT devices" finde ich zum Beispiel nahezu am Anfang den Eintrag
Adafruit 1.8
Device=adafruit18
Driver=fb_st7735r SPI 8-bit
Jetzt habe ich alle Daten um den Framebuffertreiber zu konfigurieren.
Ich öffne/erstelle dazu die Datei /etc/modprobe.d/fbtft.conf
Darin trage ich folgendes ein.
options fbtft_device name=adafruit18
Ich speichere die Datei. In dieser Datei kann man noch weitere Angaben
hinzufügen. Zum Beispiel abweichende Anschlüsse an den GPIOs oder die
Geschwindigkeit der Schnittstelle um ggf. höhere Frameraten zu erhalten.
So zu Beispiel:
options fbtft_device name ........ gpios=reset:25,dc:24,led:18 speed=16000000 rotate=90
Hier wird dem Framebuffertreiber mitgeteilt, das ein Display abweichend
die Resetleitung an Pin 25, die DC-Leitung an Pin 24 und die
LED-Hintergrundbeleuchtungssteuerung an Pin 18 hat. Die Geschwindigkeit
der Schnittstelle wird auf 16 MHz gesetzt, das Bild soll um 90 Grad
rotiert/gedreht werden.
Nachdem die beiden Dateien oben angelegt wurden, reboote ich das System.
3.) Nach dem Neustart schaue ich nach ob der richtige Framebuffertreiber
geladen wurde. Dazu öffnet ich ein Terminal und gebe ein:
lsmod
Dieser Befehl zeigt alle geladenen Module im Betriebssystemkernel an. Es kommt zu folgender Ausgabe:
Wir sehen das SPI aktiv ist und der fb_st7735r für das Adafruit1.8 (und baugleiche) geladen wurde.
Zusätzlich geben wir in der Konsole den Befehl dmesg ein. Damit bekommen wir den Nachrichtenpuffer des Kernels angezeigt. Wir scrollen darin und suchen
die Ausgaben zu SPI und dem Framebuffer. In meinem Beispiel erhalte ich mitten im ausgegeben Text:
...
[ 2.529825] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[ 2.544881] fbtft_device: module is from the staging directory, the quality is unknown, you have been warned.
[ 2.546036] spi spi0.0: spidev spi0.0 125000kHz 8 bits mode=0x00
[ 2.546049] spi spi0.1: spidev spi0.1 125000kHz 8 bits mode=0x00
[ 2.546089] bcm2708_fb soc:fb: soc:fb id=-1 pdata? no
[ 2.546125] spi spi0.0: Deleting spi0.0
[ 2.546542] fbtft_device: GPIOS used by 'adafruit18':
[ 2.546548] fbtft_device: 'reset' = GPIO25
[ 2.546554] fbtft_device: 'dc' = GPIO24
[ 2.546559] fbtft_device: 'led' = GPIO18
[ 2.546570] spi spi0.1: spidev spi0.1 125000kHz 8 bits mode=0x00
[ 2.546581] spi spi0.0: fb_st7735r spi0.0 32000kHz 8 bits mode=0x00
[ 2.578991] i2c /dev entries driver
...
Sieht doch erstmal ganz gut aus.
Auch die Eingabe von: ls -l /deb/fb* liefert uns zwei Framebuffer.
crw-rw---- 1 root video 29, 0 Feb 14 13:16 /dev/fb0
crw-rw---- 1 root video 29, 1 Feb 14 14:13 /dev/fb1
pi@raspberrypi:/$
Nun wollen wir, das das grafische System von Linux direkt in den
Framebuffer geschrieben wird um damit auf unseren Kleinstdisplay zu
erscheinen. Wir benötigen noch einen Eintrag in einer weiteren Datei.
4.) Zuletzt öffnen wird die Datei /usr/share/X11/xorg.conf.d/99-fbturbo.conf
Diese ändern wird ab, sodaß das sie wie folgt aussieht:
# This is a minimal sample config file, which can be copied to
# /etc/X11/xorg.conf in order to make the Xorg server pick up
# and load xf86-video-fbturbo driver installed in the system.
#
# When troubleshooting, check /var/log/Xorg.0.log for the debugging
# output and error messages.
#
# Run "man fbturbo" to get additional information about the extra
# configuration options for tuning the driver.
Section "Device"
Identifier "Allwinner A10/A13 FBDEV"
Driver "fbdev"
Option "fbdev" "/dev/fb1"
Option "SwapbuffersWait" "true"
EndSection
Wichtig ist, das der Driver fbdev ist und wir /dev/fb1 als unser "Ausgabefenster" wählen.
Nachdem die Datei gespeichert wurde und wir nochmals einen Neustart
durchführen, läuft unsere Desktopumgebung anstelle auf dem HDMI-Monitor
auf unserem Kleinstdisplay.
Hmmm, macht irgendwie wenig Sinn an diesem Desktop zu arbeiten oder?
Aber wir können anstelle von LXDE auch jede andere "X11"-Anwendung auf
dem Display erscheinen lassen. So zum Beispiel durch startx
/usr/bin/xeyes auch die "Spassanwendung" des X11-Paketes. Zwei Augen die
dem Mauszeiger folgen.
Wenn jetzt jemand eine Skalensimulation hat, deren fotorealistische
Abbildung 128x160 Pixel groß ist (ist soetwas überhaupt möglich?), dann
kann
er diese ebenso wie xeyes auf dem Display anzeigen lassen. Das gleiche
gilt für eine der Displaygröße angepassenten FLTK-GUI, die ich weiter
vorne in diesem Thread gezeigt habe.
Soweit so gut! Ich denke ich konnte die Mailfrage damit ausreichend
beantworten. Der Framebuffer ist ein wichtiges Instrument für
Benutzeroberflächen ist, die den grafischen "Aufsatz" von Linux
benötigen.
Keine Kommentare:
Kommentar veröffentlichen