Hallo, ich möchte hiermit einmal meinen USB HID Host Treiber für Windows vorstellen! Auf Mikrocontroller Seite gibt es mittlerweile von jedem Hersteller USB-Stacks, um ein Device zu implementieren. Und auch auf PC-Seite sind einige Host Treiber verfügbar. Warum also noch ein Treiber? Ganz einfach weil deren Anwendung oft zu kompliziert ist! Mein Treiber kommt als Bibliothek (.lib) daher und läßt sich einfach über eine Header-Datei in die Projekte einbinden. Das Ganze funktioniert mit dem Microsoft Visual Studio Express (C++) zusammen. Folgende Funktionen sind implementiert: - AHid_Init(): muß am Anfang aufgerufen werden und initiaisiert die Bib. - AHid_Register(): registriert ein USB-Gerät zur Verwendung. - AHid_Read()/AHid_Write(): wie die Namen schon sagen. - AHid_Attached(): stellt den Anschluß an den USB fest. Vom technischen her ist die Bibliothek so aufgebaut, dass zum Lesen und Schreiben jeweils eigene Threads implementiert sind, was dazu führt, daß die Anwendung nicht 'hängen bleibt'. Der Lesethread sendet nach erfolgreichem Datenempfang eine Nachricht an das Hauptfenster. Dort werden dann die Daten mit AHid_Read() in Empfang genommen und weiterverarbeitet. Bei Anschluß oder Entfernen des USB-Geräts erhält die Anwendung eine WM_DEVICECHANGE-Nachricht. Hierauf wird mit AHid_Attached() überprüft, in wie weit das eigene USB Gerät betroffen ist. Das Ganze ist in eine Demo integriert, die ich mit der WIN32 API geschrieben habe (kleine Dialog-Anwendung). Wer interesse hat kann sich die ahid.lib hier herunterladen: www.embedded24.net. Für Fragen und Verbesserungen bitte bei mir melden (entweder hier oder unter e24(at)basic.io). Gruß Potter
Ich war mal auf deiner Website, aber was genau ist der Unterschied zwischen: - free: no commercial use (download) - private: no commercial use - commercial: commercial use Also den Unterschied zwischen den ersten beiden versteh ich nicht...
Hallo Julian, der wesentliche Unterschied ist, dass in der kostenlosen Version lediglich eine Schnittstelle (ein HID-Gerät und eine Report ID) unterstützt wird. Gruß Potter
Doku bedarf überarbeitung vid und pid getrent oder als string ? du solltest dich schon entscheiden. Wie kann ich geräde eindeutig identivizieren. VID und PID reichen unter umständen nicht aus ( 2 mal das gleiche device am bus und ich wüdre gerne mit einem ganz bstimmten reden ) und ich hab das leichte gefühl du hast HID nicht ganz verstanden. hier gibt es keine Paket struktur oder sowas. Ein HidReport kann verloren gehen oder doppelt "empfangen" werden. Windows frägt in einer von ihm gewählten frequenz den HID reports an. Diesen speichert er zwischen. bei einem Read auf das device wird "ich vermute" der vorher gelesene wert zurückgegeben. wozu 2 threads. die daten wandern sowieso alle auf den gleichen endpoint. spätenstens hier laufen die daten wieder sequenziell über die leitung. Dien hängenbleiben hat eher was mit GUI eigenschaften an sich zu tun. Man darf nicht inerhalb der on klick methode irgend welche zeitraubenden sachen machen. (z.B. auf die rückangwort von einem device oder ... )
Ich wollte es mal ausprobieren, bekomme es aber mit der aktuellen Visual C++ 2010 Express nicht zum laufen. Fehler siehe Bild.
Hallo Laute, erstmal vielen Dank, dass Ihr Euch für die ahid.lib interessiert und die Demo ausprobiert habt. @Matthias: tatsächlich erhält man zwei Linker-Warnungen. Allerdings führen diese nicht dazu, dass die Anwendung nicht läuft (jedenfalls bei mir mit VS 2008). Die Schlußmeldung zeigt ebenfalls an, daß das Erstellen erfolgreich war (Schau mal, ob die Applikation nicht doch in der Task-Leiste zu finden ist?). Wie auch immer, ich werde mich darum kümmern, daß auch diese Warnungen verschwinden. @...: Was die Doku betrifft so bedarf diese nicht nur der Überarbeitung - ich muß die noch komplett schreiben! Der Grund: ich dachte die Funktionen sind so 'übersichtlich', daß ich zunächst auf eine ausführliche Doku verzichten kann. Was die Sache mit VID/PID betrifft hast Du recht. Man sollte sich entscheiden. Allerdings war es lediglich so, dass ich zunächst die ID's als Interger übergeben habe und mich dann nach (reiflicher) Überlegung umentschieden habe und nun diese als String übergebe. Dadurch wird das Ganze etwas flexibler! Man hat nun die Möglichkeit auch einzelne Interfaces (z.B. bei Composite Devices [Verbundgeräte]) anzusprechen. Technisch funktioniert das so, dass der String einfach mit dem Gerätepfadnamen verglichen wird. Es mag sein, dass ich im Header File noch von VID/PID spreche. Danke für den Hinweis, ich werde es verbessern. Also wenn Du zwei mal das gleiche Device am Bus hast, dann wird das ebenfalls über den Gerätepfadnamen erledigt. Dieser wird gebildet aus VID, PID und gegf. Interface des USB-Gerätes sowie Gerätetyp (hier HID) und dem Port, an dem Dein Gerät angeschlossen ist. Wie Du siehst werden diese identischen Geräte über den Port unterschieden. Ich sehe jetzt auch keine Notwendigkeit für die Applikation zu wissen ob ich Gerät A oder B ansteuere, da ja beide sowieso das gleiche machen. Falls es doch Bedarf für so etwas gäbe, dann sag mir ein Beispiel und ich werde noch eine Möglichkeit einfügen, um die Geräte-ID abzufragen. Naja das mit den Paketen ist so eine Redensart. Bei HID's werden Reports versendet. Das kann über den Control-Endpunkt oder über einen Interrupt-Endpunkt geschehen. Momentan werden Interrupt-Endpunkte unterstützt. Den Control-Endpunkt (Feature-Reports) werde ich noch implementieren. Was Du da schreibst bzgl. des Senden und Empfangen von Reports stimmt. Allerdings legt zunächst das USB-Geräte (und nicht Windows) fest, in welchen Abständen die In-Endpunkte gepollt werden sollen - das meinst Du mit Frequenz, oder? Sind dann neue Daten vorhanden, holt diese der Host ab und schreibt sie zunächst mal in einen (internen) Datenpuffer. Hier wird dann (bei Interrupt-Transfer) mit ReadFile ausgelesen. Beim Schreiben an das Gerät funktioniert das genauso nur umgekehrt. Das mit den Threads führt dazu, dass beim Empfang von vielen Daten (oder beim Senden) die Anwendung nicht hängt. Auch das hat nichts mit den Endpunkten direkt zu tun. Übrigens: Senden und Empfangen geht sehr wohl über zwei verschiedene Endpunkte (nämlich In und Out)! Die ganze USB Geschichte ist wirklich nicht trivial. Ich empfehle Dir das Buch von Jan Axselson, falls Du noch ein paar Lücken schließen möchtest. Noch mal Danke für die Resonanz und auch Kritik. Es hilft mir sehr dabei, den Treiber zu verbessern. Gruß Potter
Ralf H. schrieb: > @Matthias: tatsächlich erhält man zwei Linker-Warnungen. Allerdings > führen diese nicht dazu, dass die Anwendung nicht läuft (jedenfalls bei > mir mit VS 2008). Die Schlußmeldung zeigt ebenfalls an, daß das > Erstellen erfolgreich war (Schau mal, ob die Applikation nicht doch in > der Task-Leiste zu finden ist?). Wie auch immer, ich werde mich darum > kümmern, daß auch diese Warnungen verschwinden. Die .Exe ist da, hatte ich vergessen zu erwähen. Starten lässt sie sich jedoch nicht, meldet sofort einen Aufruffehler. Habe Version 10. Die Lib sieht wie für Version 9 aus. Kann es sein, das die nicht zusammen passen?
Es ist tatsächlich so, dass die Konvertierung (von 2008 auf 2010) nicht einwandfrei durchgeführt wird. Der Treiber läuft also momentan nur unter der 2008er Version des Visual Studio C++ - ich bin aber dabei das zu ändern.
Ok das mit den endpoints ist mir entgangen. wobei es ist die gleiche leitung und die hat nur D+ und D-. bzw wie du gesagt hast je nach realisierung ob controll oder interrupt endpoints. Ich frage mich gerade wo du von Interrupt und dem Controll endpoint redest, ob du hier von windows oder von der FW redest. Auf pc seite kann dir das eigentlich recht egal sein. HID api von windows sei dank. Wiso die devices unterscheidbar sein sollen? wenn die geräte gleich sind können sie doch unterschiedliche aufgaben haben. z.B. Weiche1 und weiche2 bei ner eisenban oder temp umgebung / temp heizung. wenn ich dann ggf jedes mal raten muss welche welche ist und das ggf auch nach einem neustart wieder passend drehen und anpassen muss, macht das keinen spass. Serien nummer sollte das device versenden (string descriptor) windows kann bei usb da lustige sachen manchen z.B. Bei SmartCard hier werden die Gerätenamen nach der reihenfolge des erkennens vergeben und durchnummeriert. (pscs api) bei einem neustart von system sind die 2 geräte ja schon angeschlossen. die durchnummerierung erfolgt erneut. nur unter umständen in anderer reihenfolge. Generell werden usb geräte ohne Serien no anahnd ihres steckplates an usb erkannt. hast du nun 2 geräte ohne serien no am pc angeschlossen, und vertasucht die beiden anschlüsse wird windows keinen unterschied ferstellen, und z.B. weiche2 als weiche1 verwenden und umgekehrt. Ich hab bisher zur geräte erkennung die SetupApi verwendet bzw die HID API hier kann man alle am system angeschlossenen geräte abfragen und VID PID und ggf SN abfragen und vergleichen und danach mit write / read file daten senden und lesen. beispiel von st: http://www.st.com/stonline/books/pdf/docs/12179.pdf oder hier: http://www.c-plusplus.de/forum/62399 ok die notwendigen dateien und libs sollte man haben. SDK bzw. DDK bzw WDK keine ahnung wo das jetzt genau drinn ist. und es sieht nach viel wodo aus was da gemacht wird. der code funktiniert aber bei mir ganz gut. gruss
@Matthias: Ich habe mir jetzt mal die Express Version vom Visual Studio C++ 2010 heruntergeladen und das Projekt angepasst. Es sollte nun ohne Fehler laufen. Wäre nett, wenn Du das bestätigen könntest. @...: Also das Problem mit mehreren identischen USB-Geräte an einem PC wird bei der ahid.lib vermieden: Wenn Du die Demo startest, siehst Du im Ausgabefenster ein paar DEBUG-Hinweise. So wird zum Beispiel auch der Gerätepfadname ausgegeben. Dieser Name ist - nachdem ein USB-Gerät einmal am USB-Port des PC angemeldet wurde - für diesen speziellen Port immer gleich. Er ändert sich auch nicht nach einem Neustart des PC! Wenn Du nun hergehst, und im Betrieb Dein Gerät an einen anderen Port ansteckst (also ohne die Applikation zu beenden) wirst Du feststellen, dass das USB-Gerät nicht erkannt wird. Der Treiber hat nämlich Dein Gerät mit dem ersten Gerätepfadnamen in die Registrierung eingetragen und somit erkennt er den falschen Pfad. Erst nach einem Neustart der Applikation kannst Du Dein Gerät an einem anderen Port wieder registrieren lassen. Was heisst das nun für mehrere gleichartige Geräte? Da - wie bereits erwähnt - die Gerätepfade ausschlaggebend sind für eine Registrierung und da diese Gerätepfade alphabetisch durchsucht werden, kannst Du immer sicher sein, dass die Reihenfolge und somit die Gerätezuordnung erhalten bleibt. Das gilt auch nach einem Neustart des PC. Anmerken will ich noch, das die Demo-Version auf einen einzelnen Gerätepfadnamen eingeschränkt ist. Das reicht für die allermeisten privaten Anwendungen.
Zwischenbilanz: - Dynamic Link Library (DLL) hinzugefügt. - ein paar Fehler entfernt. - Funktionalität für UNICODE und MULTIBYTE getestet. - Demos zum Download für C++ und C# (Visual Studio 2010) erstellt. - Homepage aktualisiert: http://www.embedded24.net - Artikel zum Thema erstellt: http://www.mikrocontroller.net/wikisoftware/index.php?title=USB_HID_Host_Treiber&redirect=no
Update: - MULTIBYTE Support entfernt (veraltete Technologie) - Demo-App für Visual Studio VB 2010 erstellt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.