Original-URL des Artikels: https://www.golem.de/news/windows-on-devices-grosses-betriebssystem-auf-kleinem-rechner-1408-108801.html    Veröffentlicht: 27.08.2014 12:03    Kurz-URL: https://glm.io/108801

Windows on Devices

Großes Betriebssystem auf kleinem Rechner

Windows für Steuerungsaufgaben auf einem Bastelrechner und auch noch mit Arduino-Sketches kompatibel? Absurd! Blasphemie! Aber es geht, zwar mit Einschränkungen, aber doch erstaunlich komfortabel, wie Golem.de nach einem kurzen Test festgestellt hat.

Ein Windows ohne grafische Benutzeroberfläche zu bedienen, scheint so manchem immer noch ein Ding der Unmöglichkeit - obwohl die Windows-Server-Linie einen Headless-Betrieb bereits seit geraumer Zeit unterstützt. Gerne wird auch vergessen, dass Microsoft mit Windows CE bereits seit fast 20 Jahren Erfahrung bei Steuerrechnern und eingebetteter Elektronik besitzt. Und bereits seit 1997 die ARM-Plattform unterstützt, als Linux-Distributionen noch mit einer Bootdiskette kamen. So war es durchaus absehbar, dass Microsoft auf den wachsenden Erfolg der Kleinrechner mit einer eigenen, aktuellen Windows-Version reagieren würde. Nun bietet es ein spezielles Windows an. Wir haben es ausprobiert und entdeckt, dass es aus Entwicklersicht eine überraschend interessante Plattform ist.

Merkwürdig ist allein die Wahl der unterstützten Hardware: Statt für die populären ARM-Rechner, wie das Raspberry Pi, erscheint das Windows für den Intel Galileo und seinen 486-basierten Quark-SoC. Und das, obwohl es durchaus bereits funktionierende Ansätze gab, Windows CE auf dem Raspberry Pi zum Laufen zu bringen.

Microsoft verzichtet auf eine spezielle Bezeichnung für dieses Windows und auch auf eine explizite Versionsnummer. Formulierungen wie Windows on Devices oder Windows Internet-Of-Things bezeichnen vielmehr bestimmte Entwicklerprogramme und Marketingunternehmungen rund um diese spezielle Windows-Variante.

Unkomplizierte Installation und übersichtliche Verzeichnisse

Die Installation des Windows für den Galileo gestaltet sich schlicht: SD-Karten-Image auf einen Windows-PC herunterladen und dazu ein Kopierprogramm in Form einer Batch-Datei. Das Kopierprogramm wird mit einigen Parametern aufgerufen, damit gelangt das Image auf die SD-Kartei. Dazu werden noch der Name des Rechners für das Netzwerk und das Passwort für den Administrator-Account der zukünftigen Windows-Installation angegeben. Die Eingabe einer Seriennummer oder Ähnliches ist nicht notwendig.

Nachdem der Kopiervorgang beendet ist, wird die SD-Karte in den Galileo gesteckt, dann der Galileo mit dem LAN verbunden und schließlich mit Strom versorgt.

Nach der recht langen Bootzeit von etwa zwei Minuten ist der Galileo im Netzwerk sichtbar. Per telnet gelangen wir auf die Kommandozeile. Wir schauen uns ein wenig mit dir um. Die Verzeichnisstruktur und deren Inhalte unterscheiden sich nicht deutlich von einem klassischen Windows, allerdings fehlen erwartungsgemäß viele GUI-Programme.

Beim Navigieren fällt uns auf, dass die Verzeichnisstruktur exakt der entspricht, die wir nach dem Kopiervorgang auf dem Windows-PC gesehen haben. Die SD-Karte besitzt ein Fat32-Dateisystem, auf dem alle Verzeichnisse und Dateien sowohl auf dem Windows-PC als auch auf dem Galileo direkt sichtbar sind.

Bei Linux-Installationen ist es hingegen üblich, dass die SD-Karte mit FAT formatiert ist und das "normale" Dateisystem in einem Image mit fester Größe liegt. Nur auf die Kernel- und die Bootdateien kann direkt auf anderen Systemen zugegriffen werden, wenn die SD-Karte dort eingesteckt wird. Ein Image muss hingegen erst gemountet werden. Der Ansatz von Windows ist hier deutlich komfortabler, insbesondere, wenn Dateien direkt auf die Karte kopiert werden sollen, außerdem kann die Speichergröße der Karte ohne Umwege ausgenutzt werden. Das gilt allerdings auch nur, solange dieses System seinerseits das FAT32-Format lesen und schreiben kann.

Die Windows-Installation selbst belegt initial rund 600 MByte auf der Karte, genehmigt sich im laufenden Betrieb aber zunehmend Speicher im GByte-Bereich für die Auslagerungsdatei.

Etwas später entdecken wir noch, dass wir alternativ auch über FTP vollständig lesend und schreibend Zugriff auf die Inhalte der SD-Karte haben.

Kaum Programme und Treiber

Ein Blick in das System32-Verzeichnis offenbart nur eine kleine Anzahl an Programmen, es handelt sich in erster Linie um Netzwerk-Werkzeuge wie netsh. Auch das Drivers-Verzeichnis ist eher übersichtlich und enthält neben den Treibern für das Galileo-Board nur generische Treiber - unerwarteterweise zum Beispiel auch für Floppydisk-Laufwerke.

Ärgerlich ist, dass Microsoft nicht dokumentiert, welche Arten bestehender Treiber und Programme mit dieser Windows-Version tatsächlich funktionieren sollen. Ein per USB verbundener WLAN-Dongle, eine Webcam sowie ein Bluetooth-Dongle interessierte das System nicht, ein heruntergeladenes ffmpeg (statischer 32-bit-Build) ließ sich nicht zum Arbeiten bewegen.

Eigene Programme schreiben ist Pflicht

Da auch eine Powershell- oder VBScript-Umgebung fehlt, ist diese Windows-Variante ohne selbst geschriebene, kompilierte Programme nicht sinnvoll zu nutzen. Also widmen wir uns im Folgenden der Programmierung (nach Arduino-Art).

Intel hat für das Galileo-Board eine abgewandelte Arduino-IDE bereitgestellt, womit Arduino-Sketches für das standardmäßig installierte Linux des Galileo kompiliert und auf das Board übertragen werden. Diese funktioniert mit dem installierten Windows nicht mehr.

Microsoft hat seine IDE Visual Studio (VS) um entsprechende Fähigkeiten ergänzt, um für diese Windows-Variante auf dem Galileo zu programmieren. In Form von VS Express 2013 for Windows Desktop gibt es die IDE nach einer Registrierung auch kostenlos. Diese Version ist zwar mit Einschränkungen versehen, für Hobbyanwender fallen die Einschränkungen aber kaum ins Gewicht.

Über die IDE kann nicht nur mit einem Mausklick der Quellcode kompiliert und auf dem Galileo gestartet, sondern auch Zeile für Zeile debuggt werden - Out-of-the-Box. Bei anderen Plattformen und Umgebungen erfordert so etwas meist Fummelei, zusätzliche Hardware oder Geld.

Netter, sofakompatibler Nebenaspekt: Da die Kommunikation durchgängig über das Netzwerk erfolgt, muss der Galileo zum Programmieren nicht per - stets zu kurzem - USB-Kabel mit dem Rechner verbunden sein.

Arduino-Sketches jetzt als Windows-Programme

Aktuell ist die Programmierung und Ansprache der GPIO-Pins nur mit Visual C++ möglich. Um es Einsteigern leichter zu machen, gibt es auch eine "arduino.h", welche die bekannten Methoden des Wiring-APIs des Arduinos emuliert.

Im Gegensatz zur Arduino-IDE versucht Visual Studio, die C++-Basis der Sketches nicht zu verbergen, wie am Quellcode-Template von VS deutlich wird:

#include "stdafx.h" #include "arduino.h" int _tmain(int argc, TCHAR* argv[]) { return RunArduinoSketch(); } int led = 13; void setup() { pinMode(led, OUTPUT); } void loop() { digitalWrite(led, LOW); // ... }

Infolgedessen reicht ein einfaches Copy-and-Paste bestehender Sketches nicht unbedingt aus, sondern erfordert unter Umständen kleinere Nacharbeiten, um den strengeren Kompilieranforderungen des VS-Compilers zu genügen. Bei der Einbindung von Arduino-Bibliotheken Dritter sollte es wenig Probleme geben, da sie zumeist direkt in C umgesetzt wurden.

Beim Herumexperimentieren sind wir auch auf das Problem gestoßen, dass VS die notwendigen Header-Dateien nicht immer automatisch einband. Hier mussten wir explizit den Include-Pfad erweitern.

Die kompilierten Programme sind nicht unter 20 KByte groß, im Debug-Modus geht es mit 160 KByte los.

Das Windows-API kann benutzt werden

Bei den kompilierten Programmen handelt es sich um normale Windows-Programme. Und sie können auch Teile des normalen Win32-APIs verwenden. Leider dokumentiert Microsoft nicht, welche Einschränkungen bestehen - vermutlich betrifft das vor allem Funktionen mit Bezug auf die grafische Oberfläche.

In einem kleinen "Sketch" nutzen wir das Win32-API, um uns beim Programmstart die Windows-Version anzuzeigen zu lassen:

#include "stdafx.h" #include "arduino.h" #include "windows.h" int _tmain(int argc, TCHAR* argv[]) { DWORD dwVersion = GetVersion(); DWORD dwMajorVersion = (DWORD)(LOBYTE(dwVersion)); DWORD dwMinorVersion = (DWORD)(HIBYTE(dwVersion)); Log(L"%d.%d\n", dwMajorVersion, dwMinorVersion); return RunArduinoSketch(); } ...

Nun kann dieses Programm auch unter anderen Windows-Varianten auf der Kommandozeile laufen, wenn eine bestimmte DLL parallel in diesem System mitkopiert wurde (embprusr.dll). Interessanterweise liefert uns das Programm für die Windows-Variante auf dem Galileo-Board die Versionsnummer 6.3, unter Windows 8.1 Pro hingegen 6.2.

Microsoft will später noch zusätzliche APIs und C#-Integration anbieten, so dass auch Universal-Apps unter dieser Windows-Version laufen können.

Wer nach der langen Bootzeit vermutet, dass auch Programme auf der Kommandozeile lange zum Start brauchen, der irrt. Bei unseren kleinen Testprogrammen gab es beim Start über Telnet direkt auf dem Galileo keine Wartezeiten.

GPIO-Pins unter Windows nutzen

Unter Linux konnten GPIO-Pins eines Rechners schon lange über das Dateisystem angesteuert werden. Der Ansatz ist äußerst flexibel und zwingt dem Anwender keine Programmiersprache auf. Intels Implementierung des Wiring-APIs des Arduino auf dem Galileo setzt darauf auf. Der Umweg über das Dateisystem ist allerdings vergleichsweise zeitintensiv, Auswertungen im Milli- oder gar Mikrosekundentakt sind schon deswegen kaum möglich. Deshalb hat Intel auch auf eine Implementierung der pulseIn()-Funktion des Wiring-APIs verzichtet, die eine bestimmte Schnelligkeit voraussetzen würde.

Auch unter Windows können GPIO-Pins angesteuert werden, diese Funktion wurde aber lange Zeit im API für die Treiberprogrammierung versteckt.

Beim Windows für den Galileo geht Microsoft einen anderen Weg und führt das "Embedded Peripheral Usermode API" ein, das von der oben angesprochenen DLL embprusr.dll implementiert wird. Dieses API ist derzeit nicht weiter dokumentiert, lediglich ein Blick in die zugehörige C-Header-Datei gibt einige Informationen preis: So wird der Lese- wie Schreibzugriff auf GPIO-Pins unterstützt, PWM- und Analog-zu-digital-Funktionalität als auch der I2C- und SPI-Zugriff.

Um es vorwegzunehmen: analogRead() sowie digitalWrite() und digitalRead() funktionieren ohne Murren.

Viel interessanter ist, ob sich die vorhandene pulseIn()-Funktion sinnvoll nutzen lässt. Das haben wir mit einem Entfernungsmesser auf Ultraschallbasis getestet. Der Sensor übermittelt die Entfernung, indem am Echo-Anschluss ein HIGH-Signal anliegt. Die Dauer des Signals korreliert mit der gemessenen Entfernung. Allerdings ist das Signal auch bei größeren Entfernungen nur wenige Mikro- bis Millisekunden lang. Bei einem Microcontroller ist die Auswertung kein Problem, das entsprechende Programm "auf dem blanken Metall" hat die Ressourcen des Controllers exklusiv. Sobald ein Programm aber auf einem multitaskingbasierten Betriebssystem läuft, wird es schwierig.

So war es absehbar, dass unser Windows-Programm scheitern würde - zur Erinnerung: Unter Intels Ansatz mit Linux kann es nicht scheitern, weil die entsprechende Funktionalität ganz fehlt.

Ein Blick in die Implementierung

Wir waren neugierig, wie pulseIn() implementiert wird - um herausfinden zu können, unter welchen Umständen pulseIn() vernünftige Ergebnisse liefern könnte.

Ein Blick in den Sourcecode der Microsoft-Implementierung des Wiring-APIs unter Windows ist möglich, da dieses unter einer BSD-Lizenz veröffentlicht wurde.

Die Implementierung ernüchtert uns - pulseIn() ist letztlich nur ein Wrapper um wiederholte digitalRead()-Aufrufe, es werden keine speziellen Treiberroutinen genutzt. Also testeten wir, wie lange ein einzelner digitalRead()-Aufruf benötigt.

Etwa 110 Millisekunden benötigt das Auswerten eines Pins! Zum Vergleich: Das im Galileo gespeicherte Linux braucht dafür nur 2 Millisekunden. Bei digitalWrite() fällt der Vergleich ähnlich ernüchternd aus: Unter Windows benötigt die Funktion um die 210 Millisekunden, das Linux begnügt sich mit 62 Millisekunden.

Eine leere loop()-Funktion selbst wird standardmäßig alle 16 Millisekunden aufgerufen - diese Zeitspanne entspricht der Standardtaktung von Windows. Sie ist zwar vergleichsweise lang, das Zeitmuster wird aber offenbar sehr stabil eingehalten. Unter Linux ist die Dauer mit von der Auslastung abhängig und liegt normalerweise im einstelligen Mikrosekundenbereich, sporadisch beträgt sie aber auch mal mehr als eine Millisekunde.

Ein erstes Fazit

Die gute Nachricht für die Linux-Fans: Sofort wird Windows Linux nicht von ihrem Bastelrechner verdrängen. Dazu fehlt es unter Windows noch an zu vielen kommandozeilenfähigen Werkzeugen - und Treibern für externe Hardware. "Mal so eben" komplexere Anwendungen zu scripten, geht vorerst nur mit Linux.

Doch das kann sich ändern. Die Out-of-the-Box-Integration des Galileo-Boards mit Visual Source ist exzellent und vereinfacht die Entwicklung enorm. Hier hatte Microsoft wirklich konsequent die Entwickler im Blick. Neue Treiber, kompatible Bibliotheken und Programme könnten schneller kommen, als mancher denkt. Erst recht, wenn Code tatsächlich kompatibel zu Desktop- und Mobile-Versionen von Windows sein soll.

Unser Eindruck von der Performance ist gemischt. Ja, Windows ist langsamer als Linux, aber es fühlt sich nicht so deutlich langsamer an, wie es zu erwarten wäre. Eine Copter-Steuerung würden wir damit nicht umsetzen, für eine Fütterungs- und Beleuchtungsautomatik am Aquarium reicht die Performance aber wohl. Eine Sanduhr als ASCII-Symbol haben wir jedenfalls nicht vermisst. Ein richtiger Benchmarktest steht allerdings noch auf unserer To-do-Liste.

Interessant wird es, wenn diese Windows-Version auch auf dem Intel Galileo der 2. Generation laufen wird. Dort soll die hardwareseitige GPIO-Ansteuerung verbessert worden sein; wir würden gern wissen, ob auch das Windows-GPIO-API davon profitiert.

Hätte Steve Ballmer vor einem Jahr behauptet, ein aktuelles Windows wäre auf einem Single-Core-x486-Prozessor mit 400 MHz und 256 MByte RAM benutzbar, wir hätten es als Marketingübertreibung abgetan. Aber in der Kommandozeilen-Variante funktioniert es tatsächlich.  (am)


Verwandte Artikel:
US Air Force: Biegbares Arduino-Board für die Uniform oder den Jetflügel   
(12.02.2018, https://glm.io/132721 )
Microsoft: KI-Framework kommt auf Windows-10-Endgeräte   
(08.03.2018, https://glm.io/133217 )
Bastelrechner Eagleye 530s: Zigbee und Flash-Speicher im Raspberry-Pi-Format   
(01.03.2018, https://glm.io/133078 )
Optane SSD 800p: Intel bringt 3D Xpoint in die Mittelklasse   
(08.03.2018, https://glm.io/133229 )
ARM-SoC-Hersteller: Qualcomm darf NXP übernehmen   
(19.01.2018, https://glm.io/132261 )

© 1997–2020 Golem.de, https://www.golem.de/