Betriebssysteme · Institut für Systemarchitektur · Fakultät Informatik · TU Dresden

Windows 2000 Treiber (Teil 1)




1.Übung - Windows 2000 Treiber

Aufgabe der Übung ist es, sich mit der Entwicklungsumgebung Visual C++ vertraut zu machen, Recherchen nach Funktionen durchzuführen und eine Testapplikation zu entwickeln, welche Geräte anspricht.

Ziel der Übung ist es, Ihnen ein Grundgerüst für eine Testanwendung in die Hand zu geben, welches es Ihnen später ermöglicht Ihren Treiber zu testen.

Die folgende Beschreibung ist für Microsoft Visual C++ 6. Bei späteren Versionen gibt es Änderungen an der Menüführung und den Hilfen.

Die Entwicklungsumgebung Visual C++

Um sich mit der Entwicklungsumgebung vertraut zu machen ist es am Besten ein kleines "Hello World!" Programm selber zu erstellen. Um am Ende der Übung eine minimale Testapplikation am Laufen zu haben, reicht es, wenn dieses Programm eine Konsolenanwendung ist.

Um mit Visual C++ eine Konsolenanwendung zu erzeugen, gehen Sie auf den Menüpunkt Datei und wählen Sie dort Neu.... Es erscheint eine Dialogbox mit verschiedenen Seiten, welche über "Reiter" auswählbar sind. Über den Reiter "Dateien" können einzelne Dateien neu erzeugt werden und sofort dem aktuellen Projekt hinzugefügt werden. Über den Reiter "Projekte" kann man verschiedene Projekte erzeugen, auf die wir später noch genauer eingehen. "Arbeitsbereiche" können mehrere Projekte zusammenfassen. Wird ein neues Projekt angelegt wird automatisch ein neuer Arbeitsbereich dazu angelegt. Ein extra Arbeitsbereich ist dann interessant, wenn man z.B. eine Anwenung und mehrere DLLs in einem Arbeitsbereich verwalten will. "Andere Dokumente" fassen Dokumente zusammen, welche z.B. während der Enwticklungsarbeit benötigt werden, wie Klassendagramme (mit Visio) oder ähnliches.

Ein neues Projekt

Wählen Sie den Reiter "Projekt" aus und markieren Sie in der Auswahlliste "Win32-Konsolenanwendung". Wie Sie sehen können, kann man z.B. auch Win32-Bibliotheken (Libraries) oder MFC-Anwendungen (EXE) erstellen. Legen Sie rechts den Namen und den Pfad zu den Prjektdateien fest und markieren Sie den Auswahlbutton "Neuen Arbeitsbereich erstellen". Wenn Sie jetzt auf OK klicken wird ein Projekt-Assistent aufgerufen. Alle verschiedenen Projektarten rufen einen solchen Assistenten auf. Zweck des Assistenten ist Einstellungen am Projekt für Compiler und Linker festzulegen. Welche Einstellungen vorgenommen werden müssen erfährt der Assistent aus dem Dialog mit dem Nutzer - Ihnen.

Haben Sie die Win32-Konsolenanwendung ausgewählt und auf OK geklickt erscheint ein Dialog verschiedenen Optionen. Wählen Sie: "Eine Hello World! Anwendung" aus und bestätigen Sie mit OK. Der Assistent erzeugt Dateien zur Verwaltung des Projektes und erste Quelldateien. Ausserdem nimmt er Einstellungen für das Projekt vor, damit dieses korrekt übersetzt werden kann. Um das Projekt zu übersetzen drücken Sie F7 oder wählen Sie im Menü Erstellen | Name.exe erstellen aus. Die Quelldateien werden übersetzt und eine Anwednungsdatei erzeugt.

Um die Anwendung auszuprobieren öffnen Sie eine Konsole über Start | Ausführen | "cmd". Wechseln Sie in das Verzeichnis des Projektes. Visual C++ erstellt - abhängig von der aktuellen Konfiguration - eine "Debug" oder eine "Release" Version des Anwendung. Diese werden in den Unterverzeichnissen "Debug" oder "Release" abgespeichert. Wechseln Sie in das Debug Verzeichnis (dies ist die Standard-Konfiguration für ein neues Projekt) und starten Sie die Anwendung durch Aufrufen der EXE Datei. Es sollte die Ausschrift "Hello World!" erscheinen.

Klassen- und Dateiansicht

Wenn Sie zu Visual C++ zurückwechseln, sehen Sie auf der linken Seite ein extra Fenster welches zwei Reiter am unteren Ende hat, die mit "Klassen" und "Dateien" beschriftet sind. Beide beinhalten so genannte Tree-views von den Klassen bzw. Dateien des Projektes. Klicken Sie auf den Reiter Dateien und expandieren Sie die einzelnen Knoten des Ansicht (markiert durch ein Plus vorm Namen). Sie sehen, dass es bereits vier Dateien im Projekt gibt - eine "Read Me" Datei, eine "StdAfx.cpp" und "StdAfx.h" sowie eine CPP Datei welche den Namen des Projektes trägt. Die StdAfx Dateien beinhalten Standard-Konfigurations-Einstellungen. Wenn Sie auf diese Dateinamen doppelt klicken sehen Sie das so gut wie nichts in ihnen enthalten ist.

Doppelklicken Sie auf die andere CPP Datei und Sie sehen eine kleine main-Funktion, welche nur den Text "Hello World!" auf die Standard Ausgabe schreibt. Diese Anwendung werden wir jetzt erweitern um Geräte anzusprechen.

Funktionen recherchieren

Um die Parameter und Funktionsweise von Funktionen heraus zu bekommen, gehen Sie mit dem Cursor auf den Namen eine Funktion und drücken Sie F1. Es öffnen sich eine weitere Anwenung und es wird die Funktion mit den nötigen Parametern und eine Erklärung angezeigt.

Auf der linken Seite der Hilfeanwendung finden Sie Stichpunkt-Übersicht und inhaltliche Übersicht, welche es Ihnen ermöglich entweder gezielt nach einer Funktion oder anderen Werten zu suchen, bzw. durch die verschiedenen Kapitel des Programmierhandbuches zu blättern. In der Übung werden Sie diese Hilfe benutzen um heraus zu bekommen, welche Funktionen Sie wie einsetzen müssen um sich mit einem Gerät zu verbinden und dieses anzusteuern.

Die Testapplikation

Da wir noch keinen eigenen Treiber haben, welcher uns ein Gerät anbietet, verwenden wir bereits im System vorhandene Geräte um "mit ihnen herum zu spielen". Als erstes werden wir das CD Rom Laufwerk dazu bewegen die Klappe auf und zu zu machen und anschliessend senden wir Daten über ein COM Gerät.

Das CD Rom Laufwerk

1.Teil
Um ein Gerät benutzen zu können, benötigen wir ein Handle auf es. Diese Handle bekommen wir mit der Funktin CreateFile. Um das Object des CD Rom Gerätes zu finden benötigen wir den Namen des Gerätes. Dieser ist für das erste CD-Rom "\\\\.\\CdRom0". Benutzen Sie die Funktion CreateFile und den Name des CD Rom Gerätes um ein Handle auf das CD-Rom zu bekommen. Suchen Sie nach der Funktion welche das Handle nach Gebrauch wieder frei gibt und Prüfen Sie ob das Anlegen des Hanlde erfolgreich war.

Probieren Sie anschliessend ein Handle auf das Gerät "COM2" zu bekommen. Der Name des Gerätes ist "\\\\.\\COM2".

Beschreiben Sie Probleme beim Testen und geben Sie mögliche Gründe dafür an. Wie haben Sie die Probleme behoben?

2.Teil
Mit der Funktion DeviceIoControl können Sie die Geräte konfigurieren. Schreiben Sie die Funktionsaufrufe zum Öffnen und Schliessen des CD-Rom Laufwerkes. Warten Sie zwischen Öffnen und Schliessen 2 Sekunden.

Beschreiben Sie wiederum aufgetretene Probleme und geben Sie Lösungsvorschläge.

3.Teil
Mit den Funktionen ReadFile und WriteFile können Daten auf das Gerät geschrieben werden und von dort gelesen werden. Schreiben Sie ein Programm, welches auf die COM Schnittstelle COM2 100 Bytes schreibt und liest.

Geben Sie den Quelltext des Programmes an.
Was für Probleme könnte das Lesen von COM2 machen (testen Sie diesen Fall)?
Beschreiben Sie mit Hilfe der Erklärungen der Vorlesung, welche Vorgänge bei Schreiben auf die Schnittstelle COM2 ablaufen.

Für das Lesen und Schreiben auf die Schnittstelle COM2 sind timeouts zu verwenden. Finden Sie die Funktion um die timeouts zu setzen.

Anmerkungen

Testen Sie Rückgabewerte der Funktionen. Es ist keine grosse Hilfe zu sagen: "Es geht nicht.". Wenn Sie sagen das Programm funktioniert nicht, dann sagen Sie welche Zeile des Programmes nicht geht und warum.

Konsultieren Sie zur Fehlersuche die Hilfe und machen Sie Funktionen ausfindig, welche mehr Informationen zu Fehlern liefern können.


Solch eine Fehlerfunktion könnte zum Beispiel so aussehen:

void PrintError(LPCTSTR msg)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Display the string.
printf("%s: %s", msg, (LPTSTR)lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
}

Typen werden in Windows gross geschrieben, z.B. DWORD oder CHAR. Zusätzlich werden zu den meisten Typen Pointer definiert, welche durch ein LP oder P am Anfang gekennzeichnet sind: LPVOID, LPDWORD. Beachten Sie dies, wenn Sie in der Hilfe Parameterlisten ansehen. Erwartet eine Funktion einen Parameter vom Type LPDWORD, dann deklarieren Sie eine Variable vom Type DWORD und übergeben einen Zeiger auf diese Variable. Eine Besonderheit ist hier der Type LPVOID. Variablen vom Typ VOID können nicht deklariert werden. Die Funktion erwartet also einen Zeiger auf beliebig getypten Speicher (z.B. BYTE oder DWORD).


Die Hilfe der Funtionen ReadFile und WriteFile nennt Parametertypen LPCVOID. Dieser Typ ist ein const void Pointer. D.h. der Zeiger wird nicht verändert.


Wenn beim Lesen und Schreiben Timeouts gesetzt sind, dann kann es passieren, dass diese Funktionen zurückkehren, keinen Fehler liefern und trotzdem nichts (oder zu wenig) gelesen haben. Dann Sollte man mit GetCommTimeouts testen, ob denn Timeouts aufgetreten sind (z.B. ReadIntervalTimeout testen).


webmaster@os, home
25. Jun 2004
· Copyright © 2001-2022 Operating Systems Group, TU Dresden | Impressum ·