- Experimentelles Projekt, das den in Einweg-E-Zigaretten verbauten leistungsschwachen ARM Cortex-M0+-Mikrocontroller nutzt, um einen Webserver zu betreiben
- Analyse des PY32F002B-Chips von PUYA mit 24 KiB Flash und 3 KiB RAM; Implementierung der Netzwerkanbindung per SLIP
- Portierung von TCP/IP-Kommunikation und HTTP-Server-Funktionalität über ein virtuelles tty unter Verwendung von Semihosting, dem SLIP-Protokoll und dem uIP-TCP/IP-Stack
- Ursprünglich sehr langsam, aber durch Pufferoptimierung und Verbesserungen bei der Datenverarbeitung deutliche Steigerung von Reaktionszeit und Seitenladegeschwindigkeit
- Selbst in einer Umgebung mit sehr wenig Speicher wurden dynamischer Servercode und API-Endpunkte realisiert
- Der Code ist veröffentlicht; praktisches Hosting ist möglich, aber Ressourcen wie Speicher sind stark begrenzt
Einleitung
- Vorab der Hinweis, dass dieser Artikel nicht von einem direkt auf der Einweg-E-Zigarette laufenden Webserver ausgeliefert wird, sondern derselbe Inhalt von einem separaten Server bereitgestellt wird
- Ein reales Funktionsbeispiel ist unter http://ewaste.fka.wtf/ zu sehen
Hintergrund
- Über mehrere Jahre wurden Einweg-E-Zigaretten von Bekannten gesammelt, um deren Batterien wiederzuverwenden
- Interesse entstand daran, dass Einweg-E-Zigaretten in letzter Zeit immer ausgefeilter werden und inzwischen mit USB-C und wiederaufladbaren Akkus ausgestattet sind
- Beim Zerlegen wurde ein ARM Cortex-M0+-Mikrocontroller mit eingebettetem Flash von PUYA entdeckt, ein Chip, der als günstiger Mikrocontroller gut bekannt ist
- Diese Mikrocontroller wurden aus mehreren Modellen gesammelt; durch die Beschriftung der Debug-Pins war die Analyse einfach
Verwendete Hardware
- Die Chip-Beschriftung lautete
PUYA C642F15; tatsächlich handelt es sich vermutlich um die PY32F002B-Familie
- Wichtige Spezifikationen:
- 24 MHz Cortex-M0+-Kern
- 24 KiB Flash
- 3 KiB RAM
- mehrere Peripherieeinheiten vorhanden, in diesem Projekt jedoch ungenutzt
- Im Vergleich zu einem normalen Smartphone ist die Leistung gering, doch in einer Embedded-Umgebung ist der Aufbau eines einfachen Webservers durchaus möglich
Netzwerkverbindung
- Die Grundidee war nicht völlig neu, doch beim Experimentieren mit dem Semihosting-Konzept entstand die Idee, einen Webserver zu betreiben
- Semihosting ist eine Methode, auf Embedded-ARM-Systemen Syscalls nachzuahmen
- Werden Werte oder Pointer in Register gelegt und ein Breakpoint ausgelöst, interpretiert der Debugger dies und führt die gewünschte Aktion aus
- Üblicherweise wird dies zum Senden von Logs verwendet, aber auch bidirektionale Datenkommunikation ist möglich
- USB-Seriell-Geräte unterstützen das Protokoll SLIP (Serial Line Internet Protocol), das hier als Netzwerkschnittstelle genutzt wurde
- Unter Linux (und teilweise macOS) wurde mit
slattach und socat eine SLIP-Netzwerkumgebung über ein virtuelles tty aufgebaut
pyocd gdb -S -O semihost_console_type=telnet -T $(PORT) $(PYOCDFLAGS) &
socat PTY,link=$(TTY),raw,echo=0 TCP:localhost:$(PORT),nodelay &
sudo slattach -L -p slip -s 115200 $(TTY) &
sudo ip addr add 192.168.190.1 peer 192.168.190.2/24 dev sl0
sudo ip link set mtu 1500 up dev sl0
- Als TCP/IP-Stack wurde uIP gewählt: sehr klein, ohne RTOS nutzbar und leicht zu portieren
- Aus den uIP-Beispielen wurde der HTTP-Server verwendet; durch die Portierung des SLIP-Codes auf den Semihosting-Ansatz gelang der Start des Webservers
- Wegen eines 16-Bit-Ausrichtungsproblems auf der ARM-Architektur wurden das Skript zur Dateisystemerzeugung angepasst und Umwandlungen mit Perl vorgenommen
Geschwindigkeitsoptimierung
- Im Anfangszustand waren Ping-Zeiten von 1,5 Sekunden, 50 % Paketverlust und Seitenladezeiten von über 20 Sekunden zu beobachten, also eine sehr langsame Reaktion
- Ursache war der hohe Overhead von Byte-für-Byte-Ein-/Ausgabe
- Durch konsequente Nutzung der 3 KiB RAM wurde ein Ringpuffer ergänzt und die SLIP-Funktion so verbessert, dass Daten gebündelt bereitgestellt werden
- Schreibvorgänge wurden ebenfalls in Blöcke aufgeteilt und so übertragen, was ein schnelleres Cleanup ermöglichte
- Nach der Optimierung wurden 20 ms Ping, kein Paketverlust und 160 ms Seitenladezeit erreicht
- Gesamte RAM- und Flash-Nutzung:
- Flash: 5.116 B von 24 KB (20,82 %)
- RAM: 1.380 B von 3 KB (44,92 %)
- Auch kompletter Blog-Content lässt sich in diesem Umfang problemlos ausliefern, und sogar serverseitiger C-Code kann ausgeführt werden
Weitere Funktionen und Abschluss
- API-Endpunkte wurden direkt implementiert, die die Anzahl der Anfragen an die Hauptseite sowie die eindeutige ID des Mikrocontrollers zurückgeben
- Dies ist ein Experiment, das selbst auf extrem schwacher Hardware und mit minimalem Speicher noch einen dynamischen Webserver und eine API realisiert
Referenz
Noch keine Kommentare.