Sonntag, 17. Februar 2019

12. Teil iRadio: Displayanbindung über Framebuffer

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