Schnelles Erstellen von grafischen Oberflächen
Plattformübergreifende und intuitive GUI-Entwicklung
Der Markt der GUI-Frameworks für Desktop- und Embedded-Geräte schien ausgereift, als vor vier Jahren das Startup SixtyFPS mit einem weiteren Toolkit an den Start ging. Zwei Dutzend Releases und über 3.000 gesammelte GitHub-Stars später lässt sich konstatieren, dass mit SixtyFPS ein spannendes industrielles HMI-Werkzeuge verfügbar ist. Seit Ende 2023 heißt das Toolkit für Bedienoberflächen Straightforward Lightweight Native Toolkit (Slint).
Slint unterstützt eine breite Palette von Hardware-Geräteklassen, von Cortex-M bis zu großen Embedded-Geräten. Den Vergleich mit etablierten Werkzeugen wie emWin, TouchGfx, Qt, Qt for MCU, Embedded Web, Embedded Wizard oder Crank muss die Plattform damit nicht scheuen. Ihre Funktionalität konzentriert sich auf das Erstellen und Verwalten von Bedienoberflächen. Grundgerüst für die Programmierung ist das in jüngerer Zeit zunehmend populäre Rust, Slint bringt aber auch Bindings für C++ und künftig NodeJS mit.
Als Cross-Platform-Native-Toolkit läuft Slint auch auf Geräten mit wenig Speicher und leistungsschwachem Prozessor. Eine deklarative Sprache ermöglicht es, das User Interface und seine Elemente zu beschreiben, woraufhin ein Compiler diese Beschreibungen in nativen Code umwandelt.
GUI intuitiv entwickeln
Bei der Entwicklung seiner Graphical-User-Interface-Plattform (GUI) verfolgt Slint mehrere zentrale Ziele. Zum einen die Skalierbarkeit: UIs passen sich problemlos jedem Bildschirm an und sind kompatibel mit einer Vielzahl an Geräten, von Desktop-Computern bis zu einfachen eingebetteten Systemen. Leichtgewichtigkeit ist ein weiteres Merkmal. Auch mit begrenzten Ressourcen bietet Slint ein flüssiges, Smartphone-ähnliches Benutzererlebnis auf jeglichem Device.
Bei der Bedienung legt Slint großen Wert auf intuitives Arbeiten. Designer und Developer fühlen sich beim Gestalten und Entwickeln von GUIs produktiv und unterstützt. Die Slint-Tools sind einfach zu handhaben, die APIs zeichnen sich durch Konsistenz und Benutzerfreundlichkeit aus, unabhängig von der gewählten Programmiersprache. Außerdem wurde Wert darauf gelegt, dass die erstellten Benutzeroberflächen einer nativen Anwendung in ihrer Anmutung und Funktionalität nicht nachstehen, egal ob auf Desktop, Mobilgerät, Web oder eingebettetem System. Slint orientiert sich hierbei an CSS und verwendet in der Syntax eine Mischung aus Rust, Python und JavaScript.
Rust vereint Programmierparadigmen
Die Open-Source-Programmiersprache Rust wurde mit dem Ziel entwickelt, sicher, nebenläufig und praxisnah zu sein; gesponsert wird sie von u.a. Mozilla Research. Sie vereint Ansätze aus verschiedenen Programmierparadigmen, unter anderem aus der funktionalen, der objektorientierten und der nebenläufigen Programmierung. Dies ermöglicht ein hohes Abstraktionsniveau und führt zu einer mit C++ vergleichbaren Performanz.
Die Konzepte des Ownership und Borrowing gewährleisten durch klare Eigentumsregeln eine sichere Handhabung von Speicher und Daten. Wettlaufsituationen und unsichere Zugriffe lassen sich so vermeiden. Das Konzept der Lifetimes trägt zur Sicherheit bei, indem es die Gültigkeitsdauer von Referenzen definiert und vor unsicherem Zugriff, wie herrenlosen oder verwaisten Referenzen, schützt. Ergänzend dienen Crates als Bausteine für modulare und wiederverwendbare Code-Pakete und unterstützen so die gemeinschaftliche Entwicklung und Vereinfachung der Code-Organisation. Zusammengenommen ermöglichen diese Merkmale eine leistungsstarke, sichere und effiziente Softwareentwicklung.
Rust verfügt über eine Vielzahl an Bibliotheken, mit denen sich die Entwicklung beschleunigen lässt. Die std-Bibliothek bietet - stark getestete - Grundfunktionalitäten. Für die MCU-Entwicklung ist die Bibliothek alloc wichtig. Sie ist Bestandteil von std, enthält aber nur Smart Pointer sowie Funktionen zur Heap Allokation. Dadurch lässt sich ein komfortables Memory Management umsetzen. Allgemein können benötigte Funktionalitäten immer durch Einbinden entsprechender C-Bibliotheken bereitgestellt werden.
Slint für Mikrocontroller
Cloudflight hat die Plattform mit dem spezifischen Embedded-Testsystem STM32H7G Development Kit getestet. Die Evaluierung auf Mikrokontrollern brachte einige interessante Erkenntnisse zutage, aber auch Einschränkungen, die bei der Implementierung auf diesen Plattformen zu berücksichtigen sind.
Zunächst unterstützt Slint einen Framebuffer für Single/Double-Buffering in Farbtiefen bis zu 24Bit, wobei die volle (oder doppelte) Framebuffer-Bereitstellung bevorzugt wird, solange genügend RAM vorhanden ist. Ist der RAM knapp, ermöglicht ein Line Buffer das partiale Rendering, was das System entlastet, indem es Bildinhalte Zeile für Zeile verarbeitet. Im Bereich der Hardwarebeschleunigung bietet Slint auf MCUs derzeit keine native Unterstützung für GPU-Beschleunigung, was eine potenzielle Einschränkung für bestimmte Anwendungen darstellt. Es gibt allerdings einen Prototypen für STs DMA2D, der die Fertigstellung oder Integration anderer GPUs als Dienstleistung erlaubt.
Aktuell unterstützt Slint nur eine begrenzte Anzahl von MCU-Plattformen, für die ein entsprechendes Rust-Crate existiert. Die wichtigsten sind immerhin vorhanden und vereinfachen die Integration erheblich, da große Teile des BSPs und die Anbindung an Slint bereits vorgegeben sind. Für nicht explizit unterstützte MCUs oder Boards müssen Entwicklungsteams die Anbindung jedoch selbst vornehmen, einschließlich der Initialisierung von Pins, Peripheriegeräten und Treibern. Der Hersteller bietet entsprechende Anpassungen auch als Dienstleistung an.
Für leistungsstärkere Systeme ermöglicht Slint das Interpretieren von .slint-Dateien zur Laufzeit. MCU-Systeme, die für no_std kompiliert werden, stehen jedoch vor Herausforderungen, da ihnen eine Schnittstelle zum dynamischen Laden von externen Ressourcen fehlt. Dies zwingt zur Vorkompilierung und direkten Integration von .slint-Dateien in das Binary, ein Vorgang, der auf MCU-Systemen aufgrund potenzieller Leistungseinbußen ohnehin häufige Standardpraxis ist.
Einige Einschränkungen gibt es hinsichtlich Schriftarten und Bildern. Zwar können sie über den Slint-Compiler automatisch in Bitmap-basierte Formate umgewandelt und in das Binary eingebettet werden; diese Integration kann jedoch schnell den verfügbaren internen Flash-Speicher überfordern, insbesondere wenn die Bilder bzw. Fonts zuvor in einem Vektor Format vorlagen und in unterschiedlichen Größen angezeigt werden sollen. Pfadkomponenten für SVGs oder Vektorgrafiken zu verwenden wäre platzsparend, allerdings wird diese Funktion für MCUs noch nicht unterstützt. Auch dies ist nicht in jedem Fall ein Nachteil, da aus Performance-Gründen auf MCUs gerne auf Pixel-basierte Formate zurückgegriffen wird und die Konsistenz der Toolchain die komfortable Verwendung derselben Ressourcen-Dateien etwa in einem plattform-übergreifenden Projekt erlaubt. Auf leistungsfähigen MCUs ist Grafik-Beschleunigung durch eine eingebaute GPU heute aber keine Seltenheit mehr. Auf solchen Systemen wäre es komfortabel, Vektor-Formate direkt verwenden zu können.
Auch das dynamische Laden von Übersetzungsdateien in Umgebungen, auf welchen std nicht zur Verfügung steht, unterstützt Slint noch nicht. Pläne, Übersetzungen zur Compile-Zeit zu integrieren, sind für größere Anwendungen, die mehrere Sprachen unterstützen müssen, nicht praktikabel. Schließlich wird, obwohl dafür Pläne bestehen, die Umschaltung der Sprache zur Laufzeit derzeit nicht nativ unterstützt. Als Zwischenlösung lassen sich globale Variablen verwenden, die zur Laufzeit verschiedene Werte annehmen können.
Animierte Diagramme mit Echtzeitdaten
Es ist davon auszugehen, dass es sich bei den vorgenannten Einschränkungen lediglich um derzeit noch fehlende Funktionalitäten handelt, die in weiteren Ausbaustufen nachgerüstet werden - der Preis für die Verwendung eines neuen Werkzeugs. Wesentlich sind die Pluspunkte von Slint, zuvorderst die flüssigen Animationen. Eigenschaften wie Größe, Position, Opazität oder Farbe lassen sich dynamisch animieren und kubische Bezier-Kurven ermöglichen gleitende Übergänge. Auch bei vollflächigen Überblendungen und Bewegungen sind Animationen stets flüssig. So lassen sich animierte Diagramme mit Echtzeitdaten umsetzen.
Werkzeuge für Entwickler
Zur Erstellung von Desktop-Builds für Windows/macOS/Linux stehen mehrere Backend-Optionen (d.h. Windows-System-Anbindung) zur Verfügung. Dies ist überaus hilfreich, da kein großer Aufwand für eine Desktop-Simulation anfällt. Für das Prototyping gibt es eine Integration für Visual Studio Code Editor mit Syntax-Highlighting, Code-Completion und Live-Preview (vgl. mit SlintPad). Außerdem stellt Slint einen Code-Generator für Figma-Designwerkzeuge bereit.
Wer CSS und Typescript kennt, wird die simple Syntax während der Entwicklung zu schätzen wissen. Für das unterstützte Board war Slint einfach in Betrieb zu nehmen. Es braucht nur zwei Kommandozeilen Befehle: einmal zum Bauen, einmal zum Aufspielen auf das Gerät. Ansonsten ist abgesehen von Rust nichts einzurichten. Auch die Dokumentation überzeugt.
Der Markt der GUI-Frameworks für Desktop- und Embedded-Geräte schien ausgereift, als vor vier Jahren das Startup SixtyFPS mit einem weiteren Toolkit an den Start ging. Zwei Dutzend Releases und über 3.000 gesammelte GitHub-Stars später lässt sich konstatieren, dass mit SixtyFPS ein spannendes industrielles HMI-Werkzeuge verfügbar ist. Seit Ende 2023 heißt das Toolkit für Bedienoberflächen Straightforward Lightweight Native Toolkit (Slint).
Slint unterstützt eine breite Palette von Hardware-Geräteklassen, von Cortex-M bis zu großen Embedded-Geräten. Den Vergleich mit etablierten Werkzeugen wie emWin, TouchGfx, Qt, Qt for MCU, Embedded Web, Embedded Wizard oder Crank muss die Plattform damit nicht scheuen. Ihre Funktionalität konzentriert sich auf das Erstellen und Verwalten von Bedienoberflächen. Grundgerüst für die Programmierung ist das in jüngerer Zeit zunehmend populäre Rust, Slint bringt aber auch Bindings für C++ und künftig NodeJS mit.
Als Cross-Platform-Native-Toolkit läuft Slint auch auf Geräten mit wenig Speicher und leistungsschwachem Prozessor. Eine deklarative Sprache ermöglicht es, das User Interface und seine Elemente zu beschreiben, woraufhin ein Compiler diese Beschreibungen in nativen Code umwandelt.
Cloudflight Germany GmbH
Dieser Artikel erschien in SPS-MAGAZIN 2 (März) 2024 - 04.03.24.Für weitere Artikel besuchen Sie www.sps-magazin.de