Werkzeuge
Der Umgang mit Mikrocontrollern erfordert den Einsatz verschiedener Werkzeuge, da wir es mit einer Architektur zu tun haben, die sich von der Ihres Laptops unterscheidet, und Programme auf einem entfernten Gerät ausführen sowie debuggen müssen.
Wir werden alle unten aufgeführten Werkzeuge verwenden. Sofern keine Mindestversion angegeben ist, sollte jede aktuelle Version funktionieren; wir haben jedoch die Versionen aufgelistet, die wir getestet haben.
- Rust 1.31, 1.31-beta oder neuer, SOWIE Unterstützung für die Kompilierung für ARM Cortex-M.
cargo-binutils~0.1.4qemu-system-arm. Getestete Version: 3.0.0- OpenOCD >=0.8. Getestete Versionen: v0.9.0 und v0.10.0
- GDB mit ARM-Unterstützung. Version 7.12 oder neuer wird dringend empfohlen. Getestete Versionen: 7.10, 7.11, 7.12 und 8.1.
cargo-generateodergit. Diese Werkzeuge sind optional, erleichtern es jedoch, dem Buch zu folgen.
Der folgende Text erläutert, warum wir diese Werkzeuge verwenden. Installationsanweisungen finden Sie auf der nächsten Seite.
cargo-generate ODER git
„Bare-Metal“-Programme sind Rust-Programme ohne Standardbibliothek (no_std), die Anpassungen am Linker-Vorgang erfordern, um das korrekte Speicherlayout des Programms zu gewährleisten. Dies macht zusätzliche Dateien (wie Linker-Skripte) und Einstellungen (wie Linker-Flags) erforderlich. Wir haben diese Elemente in einer Vorlage zusammengefasst, sodass Sie lediglich die noch fehlenden Angaben ergänzen müssen (etwa den Projektnamen und die Spezifikationen Ihrer Zielhardware).
Unsere Vorlage ist mit cargo-generate kompatibel – einem Cargo-Unterbefehl zum Erstellen neuer Cargo-Projekte auf Basis von Vorlagen. Alternativ können Sie die Vorlage auch mithilfe von git, curl, wget oder Ihrem Webbrowser herunterladen.
cargo-binutils
cargo-binutils ist eine Sammlung von Cargo-Unterbefehlen, die die Verwendung der mit der Rust-Toolchain ausgelieferten LLVM-Werkzeuge vereinfachen. Zu diesen Werkzeugen gehören die LLVM-Varianten von objdump, nm und size, die zur Untersuchung von Binärdateien dienen.
Der Vorteil dieser Werkzeuge gegenüber den GNU-Binutils liegt darin, dass (a) die Installation der LLVM-Werkzeuge unabhängig vom Betriebssystem stets mit demselben einzelnen Befehl (rustup component add llvm-tools) erfolgt und (b) Werkzeuge wie objdump alle von rustc unterstützten Architekturen abdecken – von ARM bis x86_64 –, da sie auf demselben LLVM-Backend basieren.
qemu-system-arm
QEMU ist ein Emulator. In diesem Fall verwenden wir die Variante, die ARM-Systeme vollständig emulieren kann. Wir nutzen QEMU, um Embedded-Programme auf dem Host-System auszuführen. Auf diese Weise können Sie einige Teile dieses Buches auch dann nachvollziehen, wenn Sie keine Hardware zur Hand haben!
Werkzeuge für das Debugging von Embedded Rust
Überblick
Das Debugging eingebetteter Systeme in Rust erfordert spezialisierte Werkzeuge, darunter Software zur Steuerung des Debugging-Prozesses, Debugger zur Überwachung und Kontrolle der Programmausführung sowie Hardware-Probes, die die Interaktion zwischen dem Host-System und dem eingebetteten Gerät ermöglichen. Dieses Dokument stellt wesentliche Software-Werkzeuge wie Probe-rs und OpenOCD vor, die den Debugging-Prozess vereinfachen und unterstützen, sowie bekannte Debugger wie GDB und die Probe-rs-Erweiterung für Visual Studio Code. Zudem werden wichtige Hardware-Probes wie Rusty-probe, ST-Link, J-Link und MCU-Link behandelt, die für das effiziente Debugging und Programmieren eingebetteter Geräte unerlässlich sind.
Software, die Debugging-Werkzeuge steuert
Probe-rs
Probe-rs ist eine moderne, auf Rust ausgerichtete Software für das Debugging in Embedded-Systemen. Im Gegensatz zu OpenOCD wurde Probe-rs mit dem Fokus auf Einfachheit entwickelt und zielt darauf ab, den bei anderen Debugging-Lösungen oft hohen Konfigurationsaufwand zu reduzieren. Es unterstützt diverse Debug-Probes sowie Zielsysteme und bietet eine komfortable Schnittstelle für die Interaktion mit Embedded-Hardware. Probe-rs lässt sich direkt in die Rust-Toolchain sowie – dank einer entsprechenden Erweiterung – in Visual Studio Code integrieren, wodurch Entwickler ihren Debugging-Workflow optimieren können.
OpenOCD (Open On-Chip Debugger)
OpenOCD ist ein Open-Source-Softwaretool für das Debugging, Testen und Programmieren eingebetteter Systeme. Es stellt eine Schnittstelle zwischen dem Host-System und der eingebetteten Hardware bereit und unterstützt verschiedene Übertragungsprotokolle wie JTAG und SWD (Serial Wire Debug). OpenOCD lässt sich in GDB, einen Debugger, integrieren. Das Werkzeug ist weit verbreitet, verfügt über eine umfangreiche Dokumentation sowie eine große Community, kann jedoch – insbesondere bei kundenspezifischen Embedded-Konfigurationen – eine komplexe Einrichtung erfordern.
Debugger
Ein Debugger ermöglicht es Entwicklern, die Ausführung eines Programms zu untersuchen und zu steuern, um Fehler oder Bugs zu identifizieren und zu beheben. Er bietet Funktionen wie das Setzen von Haltepunkten (Breakpoints), das schrittweise Durchlaufen des Codes sowie die Überprüfung von Variablenwerten und Speicherzuständen. Debugger sind für eine gründliche Softwareentwicklung und -wartung unerlässlich, da sie Entwicklern helfen sicherzustellen, dass sich ihr Code unter verschiedenen Bedingungen wie vorgesehen verhält.
Debugger bieten folgende Möglichkeiten:
- Auf die im Speicher abgebildeten Register zugreifen.
- Haltepunkte/Überwachungspunkte setzen.
- In/aus im Speicher abgebildeten Registern lesen und schreiben.
- Erkennen, wenn die MCU aufgrund eines Debug-Ereignisses angehalten wurde.
- Die MCU-Ausführung nach dem Auftreten eines Debug-Ereignisses fortsetzen.
- Den Flash-Speicher des Mikrocontrollers löschen und beschreiben.
Probe-rs Visual Studio Code Extension
Probe-rs bietet eine Visual Studio Code-Erweiterung, die ein nahtloses Debugging-Erlebnis ohne aufwendige Einrichtung ermöglicht. Dank dieser Integration können Entwickler Rust-spezifische Funktionen wie Pretty-Printing und detaillierte Fehlermeldungen nutzen und so sicherstellen, dass ihr Debugging-Prozess optimal auf das Rust-Ökosystem abgestimmt ist.
TRACE32
TRACE32 ist eine von Lauterbach für Embedded-Systeme entwickelte professionelle Debugging- und Tracing-Lösung. Sie unterstützt eine Vielzahl von Prozessorarchitekturen, darunter ARM und RISC-V, und stellt die Verbindung zur Zielhardware über JTAG, SWD sowie diverse Trace-Schnittstellen her. TRACE32 bietet leistungsstarke Debugging-Funktionen wie Multicore-Debugging, komplexe Breakpoints und Echtzeit-Trace-Analyse. Da das System auf Standard-ELF/DWARF-Debuginformationen basiert, ist es mit Rust-Binärdateien kompatibel, die mit herkömmlichen Werkzeugen erstellt wurden.
GDB (GNU Debugger)
GDB ist ein vielseitiges Debugging-Werkzeug, das es Entwicklern ermöglicht, den Zustand von Programmen während der Laufzeit oder nach einem Absturz zu untersuchen. Im Bereich Embedded Rust verbindet sich GDB über OpenOCD oder andere Debugging-Server mit dem Zielsystem, um mit dem Embedded-Code zu interagieren. GDB ist hochgradig konfigurierbar und unterstützt Funktionen wie Remote-Debugging, Variableninspektion und bedingte Haltepunkte. Es ist auf einer Vielzahl von Plattformen einsetzbar und bietet umfassende Unterstützung für Rust-spezifische Debugging-Anforderungen, wie etwa Pretty-Printing und die Integration in IDEs.
Probes
Eine Hardware-Sonde ist ein Gerät, das bei der Entwicklung und dem Debugging eingebetteter Systeme eingesetzt wird, um die Kommunikation zwischen einem Host-Computer und dem eingebetteten Zielsystem zu ermöglichen. Sie unterstützt typischerweise Protokolle wie JTAG oder SWD und ermöglicht so das Programmieren, Debuggen und Analysieren des Mikrocontrollers oder Mikroprozessors auf dem eingebetteten System. Hardware-Sonden sind für Entwickler unverzichtbar, um Haltepunkte (Breakpoints) zu setzen, den Code schrittweise auszuführen sowie Speicher und Prozessorregister zu untersuchen; dies erlaubt es ihnen, Probleme effizient in Echtzeit zu diagnostizieren und zu beheben.
Rusty-probe
Rusty-probe ist ein Open-Source-Hardware-Debugging-Interface auf USB-Basis, das für den Einsatz mit probe-rs entwickelt wurde. Die Kombination aus Rusty-Probe und probe-rs bietet Entwicklern, die mit Embedded-Rust-Anwendungen arbeiten, eine benutzerfreundliche und kostengünstige Lösung.
ST-Link
Der ST-Link ist ein weit verbreiteter Debugging- und Programmieradapter, der von STMicroelectronics primär für die Mikrocontroller-Serien STM32 und STM8 entwickelt wurde. Er unterstützt sowohl das Debugging als auch die Programmierung über JTAG- oder SWD-Schnittstellen (Serial Wire Debug). Dank der direkten Unterstützung durch das umfangreiche Angebot an Entwicklungsboards von STMicroelectronics sowie der Integration in gängige Entwicklungsumgebungen (IDEs) ist der ST-Link weit verbreitet und stellt eine komfortable Wahl für Entwickler dar, die mit STM-Mikrocontrollern arbeiten.
J-Link
J-Link, entwickelt von SEGGER Microcontroller, ist ein robuster und vielseitiger Debugger, der neben ARM auch eine breite Palette weiterer CPU-Kerne und Bausteine – wie etwa RISC-V – unterstützt. J-Link ist für seine hohe Leistungsfähigkeit und Zuverlässigkeit bekannt und unterstützt diverse Kommunikationsschnittstellen, darunter JTAG, SWD sowie Fine-Pitch-JTAG-Schnittstellen. Geschätzt wird das System zudem für seine erweiterten Funktionen, wie etwa unbegrenzte Breakpoints im Flash-Speicher, sowie für seine Kompatibilität mit einer Vielzahl von Entwicklungsumgebungen.
MCU-Link
MCU-Link ist ein von NXP Semiconductors bereitgestellter Debugging-Adapter, der auch als Programmiergerät fungiert. Er unterstützt eine Vielzahl von ARM-Cortex-Mikrocontrollern und lässt sich nahtlos in Entwicklungsumgebungen wie die MCUXpresso IDE integrieren. MCU-Link zeichnet sich besonders durch seine Vielseitigkeit und Kosteneffizienz aus und ist damit eine attraktive Lösung für Hobbyanwender, Lehrkräfte und professionelle Entwickler gleichermaßen.