Der Autor analysierte die Hardware sowie das CAN-Bus-Kommunikationsprotokoll des Egret GT E-Scooters über den physisch unkonformen USB-C-Anschluss des Displays. Durch das Auslesen der Firmware des Motor-Controllers (APM32E103) und des Displays (AT32F415) mittels SWD und OpenOCD wurden die unverschlüsselten CAN-Update-Mechanismen sowie interne UART-Protokolle vollständig rekonstruiert. Daraufhin entwickelte der Autor eine maßgeschneiderte, nebenläufige Display-Firmware in Rust auf Basis des Embassy-Frameworks und des Actor-Modells. Zur effizienten UI-Darstellung ohne Framebuffer und dynamische Speicherallokation wurde das Buoyant-GUI-Framework um eine Quadtree-basierte Partielle-Redraw-Logik erweitert.
Wichtigste Punkte
CAN-Bus über USB-C: Entdeckung eines nicht-spezifikationskonformen CAN-Busses auf den Datenpins der USB-C-Ladebuchse des Displays, analysiert via Oszilloskop und einem ESP32-C6 Dual-Transceiver-Log-Rig (SN65HVD230 und MCP2515).
Firmware-Extraktion via SWD: Auslesen von Flash und RAM des Motor-Controllers (APM32E103xCxE, STM32F103-Klon) und der Haupt-MCU des Displays (AT32F415, ArteryTek) mittels STLINK/OpenOCD sowie Code-Analyse in Ghidra unter Nutzung passender SVD-Dateien.
Unauthentifizierter Update-Prozess: Rekonstruktion des Bootloader-Flash-Ablaufs über CAN-Frame-ID 0x384, der 64-Byte-Datenblöcke verteilt über 9 klassische CAN-Frames inklusive CRC-16-CCITT ohne kryptografische Authentifizierung akzeptiert.
Rust Hardware Abstraction Layer (HAL): Entwicklung von at32f4xx-hal durch Anpassung von stm32-rs-Peripherieregistern an die spezifische AT32F415-Architektur.
Actor-Architektur mit Embassy: Strukturierung der neuen Firmware in isolierte, asynchrone Tasks (ADC, System State, Operation State, GUI, Bluetooth, CAN, Config Store via sequential-storage).
Protokoll-Dekodierung mit Deku: Bitgenaue Dekodierung von CAN- und Bluetooth-Protokollstrukturen mittels Makros der Rust-Crate deku.
Quadtree-basierter GUI-Redraw: Eliminierung von Display-Flimmern bei der buoyant-UI-Bibliothek durch Implementierung zweier Quadtrees (Dirty Region & Overdrawn Region) für gezielte partielle Renderschritte ohne Framebuffer im begrenzten 32-KB-RAM.
Clock-Teardown Workaround: Notwendiges manuelles Zurücksetzen aller vom herstellereigenen Bootloader aktivierten CRM/Takt-Konfigurationen, um korrekte Baudraten-Teiler für den CAN-Controller bei 96 MHz Systemtakt zu ermöglichen.
Diskussions-Highlights
Framework-Wahl für Embedded-UI: Der Autor (nitros) stellte in den Kommentaren klar, dass alternative GUI-Lösungen wie Slint aufgrund höherer Flash-Anforderungen und der Notwendigkeit eines Heap-Allocators das Binärgrößenlimit sprengten.
CAN-Protokoll-Framing: Unklarheiten bezüglich der 64-Byte-Pakete auf klassischem CAN (max. 8 Byte pro Frame) wurden geklärt: Die 64-Byte-Chunks werden ISO-TP-ähnlich über 9 Einzelframes verteilt (Frame 0: Sequenz + 5 Byte Daten; Frames 1–7: je 7 Byte Daten; Frame 8: 3 Byte Daten + 2 Byte CRC).
Sicherheitsdebatte & KI-Einsatz: Intensive Diskussion über die Risiken individueller Firmware auf Mikromobilitätsgeräten. Während Kritiker vor logischen Fehlern (z. B. abruptes Blockieren oder unkontrollierte Beschleunigung) warnten, wurde betont, dass Rust zwar Speichersicherheit bietet, aber keine Logikfehler ausschließt.
Proprietäre Ökosysteme: Vergleiche zu geschlossenen Herstellersystemen (z. B. Bosch E-Bikes), bei denen herstellerseitige Sperren den Einsatz von Drittanbieter-Akkus oder Modifikationen ohne aufwendiges Reverse Engineering unterbinden.
Glossar
CAN-Bus (Controller Area Network): Ein robuster, serieller Bus-Standard für die vernetzte Kommunikation von Steuergeräten in Fahrzeugen ohne zentralen Host-Rechner.
SWD (Serial Wire Debug): Eine 2-Pin-Schnittstelle (SWDIO/SWCLK) zur Programmierung und zum Debugging von ARM-Cortex-Mikrocontrollern.
OpenOCD: Ein Open-Source-Tool zum Debuggen, Flashen und Testen von Mikrocontrollern über Hardware-JTAG/SWD-Adapter.
SVD (System View Description): Eine XML-basierte Spezifikation, die das Register-Layout und die Peripheriegerätemappings eines Mikrocontrollers für Disassembler und Debugger wie Ghidra beschreibt.
Embassy: Ein asynchrones (async/await) Embedded-Framework für Rust, das effizientes Multitasking auf Mikrocontrollern ohne Betriebssystem ermöglicht.
HAL (Hardware Abstraction Layer): Eine Softwareschicht, die Low-Level-Registerzugriffe eines Mikrocontrollers in abstrakte Programmierschnittstellen (APIs) kapselt.
Framebuffer: Ein reservierter Speicherbereich im RAM, der das vollständige Rasterbild speichert, das auf ein Display ausgegeben wird.
Quadtree: Eine Baumdatenstruktur, bei der jeder innere Knoten genau vier Kinder hat; wird hier zur effizienten 2D-Bereichszerlegung für partielle Bildschirm-Redraws genutzt.
ISO-TP (ISO 15765-2): Ein Transportprotokoll über CAN-Bus, das die Übertragung von Datenpaketen ermöglicht, die länger als die maximale CAN-Frame-Länge (8 Bytes) sind.
FOC (Field Oriented Control): Ein mathematisches Regelungsverfahren für Drehstrommotoren, das Drehmoment und Fluss entkoppelt regelt, um hohe Effizienz und weichen Lauf zu erzielen.