Betriebssysteme Wie entwickle ich einen Gerätetreiber für Windows Embedded CE?

Autor / Redakteur: Rudi Swiontek und Ralf Ebert* / Martina Hafner

Einen Gerätetreiber für ein Betriebssystem zu entwickeln kann eine große Herausforderung für jeden Entwickler sein. Die wichtigsten Aspekte für Microsofts neues Windows Embedded CE 6.0 fast dieser Beitrag zusammen.

Firmen zum Thema

( Archiv: Vogel Business Media )

In der neuesten Version bietet Windows Embedded CE 6.0 völlig neue Features. Windows Mobile und benutzerdefinierte eingebettete Geräte sind durch ein umfangreiches Technologieportfolio verbunden, das einen leistungsfähigen Multithread-Kernel, ein reichhaltiges Angebot an Programmierungs-APIs (Win32, MFC8, ATL, COM, DCOM und .NET Compact Framework) sowie eine funktionsreiche erweiterbare Palette von Entwicklungstools umfasst.

Windows Embedded CE 6.0 ist mit einem neuen Kernel ausgestattet, der die Einschränkungen früherer Kernel überwindet und gleichzeitig den CPUs mehr Leistung entlockt. Die meisten Systemaufrufe können vom Betriebsysten etwa 20% schneller ausgeführt werden weil sich die Systemdienste nun im Kernel befinden.

Die meiste Treiber besitzen ein Stream-Treiber-Interface und werden durch den Gerätemanager vollständig entkoppelt. Dabei spielt es keine Rolle ob es sich um einen User- oder Kernel-Mode-Treiber handelt. Auf beide Treibermodelle wird in diesem Artikel tiefer eingegangen.

Bildergalerie

1. Wie funktioniert das Memory Management?

(Archiv: Vogel Business Media)

Der neue Kernel besitzt eine komplett neue Speicherarchitektur (Bild 1), die die früheren Einschränkungen bezüglich verfügbarer Prozess- und Adressbereichsgrößen aufhebt. CE 6.0 erhöht die maximale Anzahl von Prozessen auf 32.000 und jeder Prozess verfügt über einen 2 GByte großen virtuellen Adressspeicher. In CE 6.0 erhält jeder Prozess seinen eigenen, wirklich privaten Prozess-Adressbereich von 1 GBybte. Die MMU (Memory Management Unit) bildet den virtuellen Adressbereich auf den physikalischen Adressbereich (ROM und RAM) ab.

Die neue Speicherarchitektur erleichtert einiges, besonders für Anwendungen die sehr große Speicherblöcke benötigen; so kann ein Speicherblock mit (VirtualAlloc) zugewiesen werden.

Die Anwender DLLs (User DLLs) liegen im Adressbereich der User-Prozesse und können durch die MMU in jeden anderen Prozess-Adressbereich gelegt (gemapped) werden. Der Programmcode der DLLs ist shared und die Datenbereiche sind prozessglobale Daten.

Für die Interprozess-Kommunikation kann man aus den Adressbereich (Memory Maped Files) gemeinsame Speicherobjekte bis zu 512 MByte allokieren. Die dafür notwendigen Befehle sind CreateFileForMapping, CreateFileMapping, MapViewOfFile und UnmapViewOfFile. Dabei lässt sich das Speicherobjekt als RAM-Objekt oder auch als File-Objekt erzeugen.

Wenn es sich um ein File-Objekt handelt, kann dieses auch auf einem XP/Vista-PC liegen. Dazu muß das Verzeichniss auf einem XP/Vista-PC als shared gekennzeichnet sein. Mit den WinCE Befehlen „net view xp-host-name“ und „net use gemeinsamer_name //xp_host_name/temp“ kann ein temp-Netzwerk-Laufwerk gemappt werden auf das das Mapping-File-Objekt abgespeichert wird. Damit ist es möglich, den zur Verfügung stehende Speicher beliebig zu erweitern. Umfangreiche Testdaten lassen sich somit auf ein externes Verzeichnis abspeichern. Stürtzt die WinCE Test-Applikation ab, so enthält die Datei den letzten Schreibzugriff. Der Zugriff auf ein gemeinsames Objekt lässt sich dabei durch ein Globales-Mutex synchronisieren.

2. Aus welchen Teilen setzt sich die Systemarchitektur zusammen?

Bild 2: Systemarchitektur. Alle Treiber sind Dynamic Link Librarys und werden mit dem Platform Builder entwickelt. (Archiv: Vogel Business Media)

Wie in Bild 2 zu erkennen ist stehen Systemprozesse zur Verfügung um Service-Dienste wie Telnet, Web oder FTP zu nutzen. Es lassen sich auch eigene Dienste entwickeln. Sowohl die Systemdienste, als auch die selbst geschriebenen werden vom ServicesD-Prozess verwalten und administrieren.

Alle Benutzer-Anwendungen (Applikationen) sind User-Mode-Anwendungen und werden mit VS2005 entwickelt. Für die Anwenderprogramme muß ein SDK (Software Development Kit) bereitgestellt werden, das mit dem Platformbuilder erstellt wird. Ferner stellt die Entwicklungsumgebung des VS für alle Anwendungen einen Aplikationdebugger zu Verfügung.

Jeder Treiber ist eine DLL (Dynamic Link Library) und wird mit dem Platform-Builder entwickelt. Zum Testen steht ein Kernelmode-Debugger zur Verfügung mit dem es auch möglich ist in die WinCE Systemaufrufe zu debuggen. Die User-Mode-Treiber benötigen einen User-Prozess (Udevice.exe) in dem sie verwaltet werden können. Die Kernel-Mode Treiber liegen im Adressraum des Kernel-Prozesses (nk.exe) und werden durch den Gerätemanager (Devmgr.dll) verwaltet.

Wenn eine Anwendung (User-Application) einen Buffer erzeugt, der als Aufrufparameter an einen Treiber übergeben wird, so wird der Buffer in den Adress-Bereich des Treibers gemappt. Dieses Mapping erfolgt bei jedem Treiber-Aufruf immer automatisch. Wichtig! Erzeugt der Anwender hingegen eine Struktur und die Struktur enthält als Strukturelement eine Adresse (Embedded-Pointer), so wird diese nicht in den Adressraum des Treibers gemappt. Dies bleibt dann dem Treiber-Entwickler überlassen. Hierfür werden zwei Funktionen bereitgestellt: für einen synchronen Zugriff auf den Embedded-Pointer ist dies „CeOpenCallerBuffer“ und für den asynchronen Zugriff „CeAllocAsynchronousBuffer“.

Wie im Bild zu erkennen ist, kann ein Anwender-Programm einen CAN-Treiber sowohl als User- als auch als Kernel-Mode Treiber aufrufen. An den Schnittstellen ändert sich nichts. Wo und wie der CAN-Treiber implementiert wird, ist Aufgabe des Treiber-Entwicklers. Kernel-Mode- Treiber sind sehr schnell und haben Kernel-Zugriffsrechte. Hingegen sind User-Mode-Treiber sehr robust und haben nur Anwender-Zugriffsrechte.

(ID:264282)