Tech-Talk: Rust & Embassy on Microcontrollers
Am IMVS Tech-Talk vom 20. November 2024 gab Sebastian Hugentobler eine Einführung in das Thema «Rust & Embassy on Microcontrollers». Er hat gezeigt, wie verschiedene Hardware-Technologien mit Rust und Embassy angesprochen werden können. Ausserdem berichtete er über seine Erfahrungen, die er bei der Vorbereitung auf den Tech-Talk sammeln konnte.
Rust und Embassy
Rust ist eine Programmiersprache, die viele moderne High-Level-Features bietet, was das Programmieren im Vergleich zu Low-Level-Sprachen angenehmer macht. Dennoch bietet Rust ein hohes Mass an Kontrolle, verfügt über keinen Garbage Collector und hat nur eine sehr dünne Runtime, wodurch sich die Sprache auch für hardwarenahe und performancekritische Programme eignet.
Da auf Microcontrollern standardweise kein Speicherallokator (memory allocator) zur Verfügung steht, kann die Standardbibliothek von Rust inklusive der Collections nicht ohne weiteres verwendet werden. Diese verlassen sich nämlich darauf, dass Speicher auf dem Heap allokiert werden kann. Es gibt jedoch Bibliotheken für Rust, die einen Teil der Funktionalität der Standardbibliothek bieten, ohne Heap-Allokationen zu verwenden.
Embassy ist eine Softwarebibliothek für Rust, die eine relativ einfache Programmierung von Microcontrollern ermöglicht. Eine Hauptaufgabe von Betriebssystemen ist die Verwaltung von mehreren Prozessen und Threads, die alle auf der gleichen Hardware ausgeführt werden. Microcontroller haben typischerweise kein Betriebssystem, wodurch diese Funktionalität nicht von Haus aus zur Verfügung steht. Eines der Hautpfeatures von Embassy ist das Tasksystem. Dieses bietet die Möglichkeit, verschiedene Tasks zu starten, die alle unabhängig voneinander und nebenläufig ausgeführt werden. Das Task-System implementiert das Async/Await-Model von Rust. Es ist also möglich mit gängigen Syntaxkonstrukten, Embassy-Tasks zu verwalten. Üblicherweise wird die Async/Await Syntax beim Kompilieren in Code übersetzt, der Gebrauch von betriebssystemspezifischen APIs macht, um die asynchrone Programmierung zu ermöglichen. Da es auf Microcontrollern aber kein Betriebssystem gibt, übersetzt Embassy die Async/Await Syntax zu Zustandsmaschinen, die auch auf Microcontrollern ausgeführt werden können.
Serielle Schnittstellen
Mit Embassy ist es ziemlich einfach, serielle Schnittstellen wie zum Beispiel I2C oder SPI zu verwenden. Embassy bietet für gängige Microcontroller sogenannte HALs an. Ein HAL ist ein «Hardware Abstraction Layer». Ein HAL ermöglicht es beispielsweise den gleichen Code für das Programmieren einer SPI-Schnittstelle auf verschiedenen Microcontrollern zu verwenden. Der HAL kümmert sich darum, dass die korrekten Register beschrieben bzw. ausgelesen werden.
Bluetooth
Das Ökosystem für die Bluetooth-Programmierung in Rust ist noch sehr unausgereift. Es gibt verschiedene Bibliotheken, die alle Vor- aber auch Nachteile haben. Es gibt noch keine Bibliothek, die stabil auf einer grossen Anzahl an verschiedenen Microcontrollen funktioniert und zudem auch noch zertifiziert ist. Jedoch entwickelt sich dieser Bereich rasant. Beispielsweise gibt es das TrouBLE-Projekt, welches vielversprechend aussieht und das langfristige Ziel hat, zertifiziert zu werden.
Eine weitere Herausforderung bei Bluetooth ist, dass das Protokoll sehr zeitsensibel ist. Schon kleinste Verzögerungen in der Signalverarbeitung können zu Fehlern führen. In Embassy ist es möglich, die Priorität der einzelnen Tasks festzulegen. Dabei kann es hilfreich sein, die für Bluetooth verwendeten Tasks höher zu priorisieren.
WiFi
Embassy bietet einen umfangreichen Netzwerk-Stack, der alle wichtigen Funktionalitäten wie z.B. Ethernet, IPv6 und IPV4, TCP oder DHCP implementiert. Ausserdem sind WiFi-Treiber für einige gängige Microcontroller in Embassy enthalten. Somit ist es relativ einfach, sich mit einem WiFi-Access Point zu verbinden und auf das Internet zuzugreifen. Sebastian Hugentobler demonstrierte, wie sich der Microcontroller mit einem MQTT-Broker verbinden kann, um z.B. eine Temperaturmessung auszulesen. Dafür hat er selbst eine Implementierung des MQTT-Protokolls geschrieben, die für den Microcontroller RP2040 kompiliert werden kann. Leider gab es bei der Demonstration Probleme mit der WiFi-Verbindung.
Das Aufsetzen der Entwicklungsumgebung ist mit Rust und Embassy gemäss Sebastian Hugentobler vergleichsweise einfach und unkompliziert. Embassy hat eine gute Dokumentation mit vielen Beispielen. Dank CMSIS und dem «Debug Adapter Protocol» (DAP) von Microsoft ist es sogar möglich, den Microcontroller-Code in allen IDEs zu debuggen, die das DAP unterstützen.
Fazit
Es macht Spass, mit Rust für Microcontroller zu programmieren. Es ist erfrischend, eine High-Level-Sprache verwenden zu können, die Typ- und Speichersicherheit garantiert. Embassy ist eine hervorragende Bibliothek, deren Task-System die Entwicklung von nebenläufigen Programmen sehr angenehm gestaltet.
Trotzdem muss jedoch angemerkt werden, dass es noch viel Hardware gibt, die nicht unterstützt wird. Insbesondere Bluetooth steckt noch in den Kinderschuhen. Deshalb muss für jedes Projekt sorgfältig abgewogen werden, ob Rust und Embassy die richtige Lösung sind oder ob man doch lieber einen traditionelleren Ansatz wählt.
Tech-Talk: Sebastian Hugentobler (sebastian.hugentobler@fhnw.ch), MSE Student und Assistent am IMVS
Blog Beitrag: Aaron Ebnöther (aaron.ebnoether@fhnw.ch), zukünftiger MSE Student und Assistent am IMVS
Kommentare
Keine Kommentare erfasst zu Tech-Talk: Rust & Embassy on Microcontrollers