USB HID und C++



Downloads



Applikation


Mit der AHid.dll ist es sehr einfach Daten zwischen PC und HID Gerät zu versenden. Anhand einer Demo-Anwendung zeigen wir Ihnen, welche Schritte dabei zu beachten sind.

Bild 1 zeigt die grafische Oberfläche dieser Demo. Drei Buttons ermöglichen das Verbinden mit dem HID Gerät, das Senden von Daten und das Zurücksetzen der Zähler und der List-Box.

Die Benutzeroberfläche ist in drei Bereiche unterteilt. Der Bereich Device enthält Werte, die sowohl für den Input- als auch den Output-Bericht (Report) gelten. Hierzu zählen die Hersteller-ID (Vendor ID), die Produkt-ID (Product ID), die Schnittstellen-ID (Interface ID) und die GUID des Gerätes.

Die Vendor ID und die Product ID sowie Data sind als hexadezimale Zahlen angegeben. Alle anderen Werte sind Dezimalzahlen. Die Interface ID enthält den Wert des ausgewählten Interfaces, oder den Wert -1, falls das HID Gerät keine Interfaces definiert (was häufig der Fall ist).

Bild 1: GUI zum Senden und Empfangen von Daten zwischen PC und USB HID Gerät.


Der Bereich Output enthält die Daten des Output Reports. Die Report ID ist Null und die Größe beträgt 32. Der Wert Null findet immer dann Verwendung, wenn die ID im Berichtsdeskriptor des HID Gerätes nicht definiert ist.

Der Bereich Input enthält die Daten für den Input Report. Alle Werte hierin finden sich ebenfalls im Berichtsdeskriptor .

Der Berichtsdeskriptor ist Bestandteil der Firmware eines jeden USB HID Geräts. Fragen Sie Ihren Hardware-Entwickler.

Workflow


Die Anwendung der AHid.dll erfolgt in fünf wesentlichen Schritten:

1. Die Initialisierung der DLL mit AHid_init().
2. Die Anbindung an das HID Gerät mit AHid_register().
3. Das Lesen vom Gerät mit AHid_read().
4. Das Senden von Daten an das HID Gerät mit AHid_write().
5. Die Verfolgung des Verbindungs-Status mit AHid_find().

Zunächst wird die DLL durch einen Aufruf von AHid_init() initialisiert. Dies erfolgt in der Funktion connect() (Bild 2). Auch die Anbindung an das HID Gerät erfolgt hier. Es werden zwei Handles (Pipes, Pipe-Handles) mit AHid_register() erstellt, welche jeweils eine Übertragungsleitung zwischen PC und HID Gerät beschreiben (Input und Output). Diese Handles werden im weiteren Verlauf in den Funktionsaufrufen der AHid.dll verwendet.

Bei Beendigung der Anwendung werden die Pipe-Handles durch AHid_deregister() wieder freigegeben.

Bild 2: Initialisierung der DLL und Erstellen der Pipe-Handles..


Nach der Registrierung der Geräte-Handles mit AHid_register() können diese für den Datenaustausch verwendet werden. Das Senden von Daten an das HID Gerät erfolgt in der Funktion write() mit AHid_write() (Bild 3).

Zu beachten ist, dass AHid_write() nur Daten fester Größe versendet. Die Größe entspricht dabei dem Wert der Report Größe, der schon beim Aufruf von AHid_register() verwendet wurde.

Die Daten selber stammen aus der grafischen Benutzeroberfläche und müssen zunächst noch extrahiert und konvertiert werden.

Bild 3: Daten senden.


In der Funktion read() werden Daten vom HID Gerät empfangen. Die Funktion wird wiederholt innerhalb eines Timer-Callbacks aufgerufen.

Zu beachten ist, dass AHid_read() nur Daten fester Größe liest. Die Größe entspricht dabei dem Wert der Report Größe, der schon beim Aufruf von AHid_register() verwendet wurde.

Wesentlich ist hier, dass die theoretisch maximale Anzahl an Datenpaketen (ein Datenpaket pro Millisenkunde bei HID Low- und Full-Speed) empfangen werden kann. Die Funktion AHid_read() muss also bei einem Timer-Intervall von z.B. 100 ms 100 mal aufgerufen werden. Und bei einem Intervall von 10 ms wäre es 10 mal.

Bild 4: Lesen vom USB HID Gerät.


Ein Datenverlust muss in keinem Fall befürchtet werden. Die AHid.dll sammelt alle Daten vom HID Gerät in einem Worker-Thread und speichert sie zwischen.

Die Demo-Anwendung verwendet ein Timer-Intervall von 100 ms.

Bild 5: Verfolgen des Verbindungs-Status und Auslesen der GUID.


USB Gerät lassen sich einfach vom USB abziehen und wieder anstecken. Es kann also hilfreich sein, den Verbindungs-Status zu verfolgen. Dies geschieht mit einem Timer-Callback der die Funktion find() ausführt (Bild 5).

Auch diese Funktion (ähnlich wie AHid_read()) ist nicht allzu zeitkritisch. Die Demo verwendet hier ein Timer-Intervall von einer Sekunde.

Alle Pipe-Handles eines HID Gerätes haben die gleiche GUID. Bei gleichzeitiger Verwendung mehrerer HID Geräte mit der AHid.dll, kann man mit AHid_identify() eine Zuordnung dieser Handles auf die verschiedenen HID Geräte durchführen. Handles eines Gerätes haben eine gemeinsame GUID, Handles anderer HID Geräte haben andere GUIDs. Bei Verwendung eines einzelnen HID Gerätes ist diese Funktion überflüssig.

Das Auslesen der GUID mit AHid_identify() erfolgt ebenfalls in find().