Hallo! Kann mir jemand ein möglichst kostengünstiges Gerät empfehlen, dass sich am USB bei Full Speed als WinUSB-Device enumeriert? Hintergrund: Ich versuche gerade auf einem PIC24 (dsPIC24FJ64GB202) WinUSB umzusetzen (alles in Assembler). Ich habe mich durch die USB 2.0 Spec. durchgewühlt und kann z.B. einen FTDI FT232 Chip nachstellen mit erfolgreicher Enumeration unter Win10. Aber beim Versuch auf WinUSB zu erweitern bin ich leider gescheitert. Die Enumeration wird mit Fehlercode 10 abgebrochen. Hab's schon ein paar mal kontrolliert und mit diversen Beispielen aus dem Netz abgeglichen. Ich muss wohl irgendwo einen kleinen, dummen Fehler drinn haben, den ich übersehen habe. Daher mein Plan: Ich nehme ein funktionierendes Full Speed (auf keinen Fall High Speed) WinUSB Gerät, hänge mein Picoscope 5444B dazu, das kann Full Speed USB dekodieren, schaue wie das Gerät antwortet und baue das nach. Schöne Grüsse aus dem Wienerwald.
Gernot S. schrieb: > Ich nehme ein funktionierendes Full Speed (auf keinen Fall High Speed) > WinUSB Gerät, hänge mein Picoscope 5444B dazu, das kann Full Speed USB > dekodieren, > schaue wie das Gerät antwortet und baue das nach. Dafür brauchst du ja aber keine Hardware kaufen. Such doch einfach mal nach WinUSB Data Dumps oder sowas. Du wirst ja nicht der enizige sein. Das sieht interessant aus: https://github.com/pbatard/libwdi/wiki/WCID-Devices https://github.com/pbatard/libwdi/wiki/WCID-Devices#implementation
> Dafür brauchst du ja aber keine Hardware kaufen. Such doch einfach mal > nach WinUSB Data Dumps oder sowas. Du wirst ja nicht der enizige sein. > > Das sieht interessant aus: > https://github.com/pbatard/libwdi/wiki/WCID-Devices > https://github.com/pbatard/libwdi/wiki/WCID-Devices#implementation Ja eh. Genau solche Beispiele habe ich schon durchgeschaut und nachgebaut, aber es geht halt nicht. Wie gesagt, irgendwo muss ich was übersehen haben. Und was in all den Beispielen die ich gefunden habe fehlt, ist der zeitliche Ablauf, die Reihenfolge der Setup-Transactions, den hätte ich mit einer echten HW. Wenn ich keine günstige HW finde, dann werde ich mich sowieso nochmal durch die Beispiele durcharbeiten, aber das ist mein Plan B.
Gernot S. schrieb: > Und was in all den Beispielen die ich gefunden habe > fehlt, ist der zeitliche Ablauf, die Reihenfolge der Setup-Transactions, falscher Ansatz. Du must sowieso die Requests korrekt bearbeiten, die Reihenfolge ist völlig wumpe. Damit das funktioniert muss bcdUSB auf 2.0 stehen im Falle der Bos Requests auf 2.10. Beitrag "Usb BOS descriptor" Die BOS Geschichte habe ich schon gemacht könnte dir also ev einen Stick zur Verfügung stellen. Generell sollte das aber dein LA schön anzeigen können. Ich hab bei mir einen Trigger Pin zu Begin des Setup Requests auf 0 gesetzt und nach dem kopieren des Setup Packets wieder auf 1. Die BOS Requests kommen relativ früh während der Enum.
Gernot S. schrieb: > Die Enumeration wird mit Fehlercode 10 abgebrochen. Dann häng das Teil mal an einen Linux PC (z.B. via Boot vom USB Stick). Der Linux Kernel ist mit dmesg sehr viel aussagefreudiger verglichen mit Windows. Der zeitliche Ablauf sagt Dir gar nüscht, Du musst bei USB einfach die reinkommenden Anfragen für Deskriptoren korrekt beantworten. Welche Deskriptoren wann abgefragt werden kann sich je nach OS und Version durchaus unterscheiden.
Schon mal probiert mit wireshark den USB traffic zu sniffen? Damit habe ich schon öfter 2-deutige Specs für mein Hirn "geknackt" :) Wireshark ist imho besser verständlich auf protokollebene, da vergleichsweise "high level". Ansonsten Linux fragen... Der Kernel gibt wie oben erwähnt oft sehr hilfreiche Hinweise was nicht passt. 73
Hans W. schrieb: > Schon mal probiert mit wireshark den USB traffic zu sniffen? Wireshark wird wie alle Software Sniffer erst nach der Enum einsetzbar. Solange die Enum nicht abgeschlossen ist hilft nur ein LA mit Software Dekoder oder halt ein professioneller USB Bus Analyzer.
Ich hatte das mal für einen STM32F042 implementiert: https://github.com/Solartraveler/audiomux/commit/93f77494a07cac6d8725a0295ec0d34d0a35b499 Hier hab ich das auch mal aufgeschrieben, was zu tun ist: https://www.mikrocontroller.net/articles/USB_Programmierung_auf_dem_PC#WinUSB_und_WCID Vielleicht hilfts. Genutzt hab ich damals Wireshark unter Linux, welches dann ein Windows in VirtualBox beobachtet hat.
Hier habe ich erläutert wie das geht: https://www.mikrocontroller.net/articles/USB-Tutorial_mit_STM32#Konfiguration_der_PC-Seite Auf GitHub sind Binaries für den STM32F103 welche eine Enumeration als WCID Device durchführen, musst du nur auf ein Bluepill o.ä. flashen: https://github.com/Erlkoenig90/f1usb/releases Was einem das Testen gehörig verhageln kann: Zu vergessen das Gerät aus Windows zu löschen nachdem man an der Firmware etwas repariert hat. Windows merkt sich die Kombination VID+PID+Serial und ob es ein WCID Device ist oder nicht. Nach jedem Testlauf musst du das Gerät im Gerätemanager deinstallieren, und dann auch noch in folgendem Registry-Key den Subkey für dein Gerät manuell löschen: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\usbflags Wenn du das nicht tust nachdem die WCID-Enumeration einmal fehlgeschlagen ist, wird sie die danach auch nicht funktionieren. Der 2. Reg-Key ist ebenfalls interessant, aber wird vom Gerätemanager automatisch gelöscht: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB
:
Bearbeitet durch User
Beitrag #7553000 wurde vom Autor gelöscht.
Ich hab' jetzt mal ein paar Stunden weitergesucht und endlich den kleinen dummen Fehler gefunden: Ich hab im configuration descriptor angegeben, dass es 3 Endpoints gibt, habe danach aber nur 2 definiert => Enumerations-Abbruch Jetzt Enumeriert das Ding mal und Windows frägt mich auch nach dem MS Extended Properties OS Feature Descriptor, was es vorher nicht getan hat. Werd jetzt mal auf der Windows-Seite in C versuchen das WinUSB-Gerät zu finden und mich mit ihm zu unterhalten.... Windows ist wenig überraschend nicht sonderlich effizient. Laut meinem Log macht es beim Enumerieren ein paar Abfragen mehrfach: 2x Get Standard Device Descriptor 2x Get Standard Configuration Descriptor 3x Get Standard Device Qualifier Descriptor 5x Get Standard String Descriptor Index:01 (Manufacturer) 6x Get Standard String Descriptor Index:02 (Product) 8x Get Standard String Descriptor Index:00 (Language)
Da fehlen noch so einige: USB Reset USB Suspend USB SetAddress USB SetConfiguration Vermutung: du wertest wLength nicht richtig aus. Bei Fehlern fängt USBD immer wieder von vorne an. Zeig doch mal deine Deskriptoren
Gernot S. schrieb: > Windows ist wenig überraschend nicht sonderlich effizient. > Laut meinem Log macht es beim Enumerieren ein paar Abfragen mehrfach: > 2x Get Standard Device Descriptor Das ist normal, das macht Linux auch so. Das OS kennt zu Beginn die Länge des Deskriptors nicht, und auch nicht die maximale Paketgröße vom EP0. Daher werden erst die ersten paar Bytes vom Device Descriptor abgefragt, welche Länge & maximale Paketgröße enthalten. Mit der Information wird dann der ganze Desktiptor angefragt.
Niklas G. schrieb: > Gernot S. schrieb: >> Windows ist wenig überraschend nicht sonderlich effizient. >> Laut meinem Log macht es beim Enumerieren ein paar Abfragen mehrfach: >> 2x Get Standard Device Descriptor > > Das ist normal, das macht Linux auch so. Das OS kennt zu Beginn die > Länge des Deskriptors nicht, und auch nicht die maximale Paketgröße vom > EP0. Daher werden erst die ersten paar Bytes vom Device Descriptor > abgefragt, welche Länge & maximale Paketgröße enthalten. Mit der > Information wird dann der ganze Desktiptor angefragt. Das hab' ich schon rausgerechnet. Es wird der erste Teil des DevDesc geholt, dann der Ganze und später das ganze nochmal. ;-)
Thomas Z. schrieb: > Da fehlen noch so einige: > USB Reset > USB Suspend > USB SetAddress > USB SetConfiguration > > Vermutung: du wertest wLength nicht richtig aus. Bei Fehlern fängt USBD > immer wieder von vorne an. > Zeig doch mal deine Deskriptoren Ich hab nur die mehrfachen aufgezählt. Die die du da auflistest kommen eh, aber eben nur einmal (ausser dem BUS Reset, aber das ist ja nicht wirklich ein Request). Komplettes Log wenn Gerät "zum ersten Mal" angesteckt: ########################### BUS RESET BUS RESET SETUP: 80 06 00 01 00 00 40 00 - Get Standard Device Descriptor (Len:40) IN 12: 12 01 00 02 FF 00 00 40 11 01 11 11 04 00 01 02 03 01 OUT (ACK) BUS RESET SETUP: 00 05 01 00 00 00 00 00 - Set Address: 01 IN (ACK) SETUP: 80 06 00 01 00 00 12 00 - Get Standard Device Descriptor (Len:12) IN 12: 12 01 00 02 FF 00 00 40 11 01 11 11 04 00 01 02 03 01 OUT (ACK) SETUP: 80 06 00 02 00 00 FF 00 - Get Standard Configuration Descriptor (Len:FF) IN 20: 09 02 20 00 01 01 00 C0 32 09 04 00 00 02 FF 00 00 00 07 05 81 02 40 00 00 07 05 02 02 40 00 00 OUT (ACK) SETUP: 80 06 EE 03 00 00 12 00 - Get Standard String Descriptor Index:EE (Len:12) IN 12: 12 03 4D 00 53 00 46 00 54 00 31 00 30 00 30 00 21 00 OUT (ACK) SETUP: 80 06 03 03 09 04 FF 00 - Get Standard String Descriptor Index:03 (Len:FF) (Serial Number) IN 08: 08 03 43 00 43 00 50 00 OUT (ACK) SETUP: C0 21 00 00 04 00 10 00 - Get MS Compatible ID Feature Descriptor (Len:10) IN 10: 28 00 00 00 00 01 04 00 01 00 00 00 00 00 00 00 OUT (ACK) SETUP: C0 21 00 00 04 00 28 00 - Get MS Compatible ID Feature Descriptor (Len:28) IN 28: 28 00 00 00 00 01 04 00 01 00 00 00 00 00 00 00 00 01 57 49 4E 55 53 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 OUT (ACK) SETUP: 80 06 00 03 00 00 FF 00 - Get Standard String Descriptor Index:00 (Len:FF) (Language) IN 04: 04 03 09 04 OUT (ACK) SETUP: 80 06 02 03 09 04 FF 00 - Get Standard String Descriptor Index:02 (Len:FF) (Product) IN 14: 14 03 47 00 42 00 55 00 20 00 23 00 31 00 20 00 76 00 30 00 OUT (ACK) SETUP: 80 06 00 06 00 00 0A 00 - Get Standard Device Qualifier Descriptor Index:00 (Len:0A) STALL SETUP: C1 21 00 00 05 00 0A 00 - Get MS Extended Properties OS Feature Descriptor (Len:0A) IN 0A: 8E 00 00 00 00 01 05 00 01 00 OUT (ACK) SETUP: C1 21 00 00 05 00 8E 00 - Get MS Extended Properties OS Feature Descriptor (Len:8E) IN 40: 8E 00 00 00 00 01 05 00 01 00 84 00 00 00 01 00 00 00 28 00 44 00 65 00 76 00 69 00 63 00 65 00 49 00 6E 00 74 00 65 00 72 00 66 00 61 00 63 00 65 00 47 00 55 00 49 00 44 00 00 00 4E 00 00 00 IN 40: 7B 00 30 00 31 00 31 00 42 00 42 00 34 00 38 00 39 00 2D 00 38 00 31 00 31 00 45 00 2D 00 34 00 44 00 37 00 42 00 2D 00 41 00 33 00 34 00 38 00 2D 00 30 00 34 00 31 00 42 00 33 00 46 00 38 00 IN 0E: 37 00 32 00 38 00 38 00 34 00 7D 00 00 00 OUT (ACK) SETUP: 80 06 00 01 00 00 12 00 - Get Standard Device Descriptor (Len:12) IN 12: 12 01 00 02 FF 00 00 40 11 01 11 11 04 00 01 02 03 01 OUT (ACK) SETUP: 80 06 00 02 00 00 09 00 - Get Standard Configuration Descriptor (Len:09) IN 09: 09 02 20 00 01 01 00 C0 32 OUT (ACK) SETUP: 80 06 00 02 00 00 20 00 - Get Standard Configuration Descriptor (Len:20) IN 20: 09 02 20 00 01 01 00 C0 32 09 04 00 00 02 FF 00 00 00 07 05 81 02 40 00 00 07 05 02 02 40 00 00 OUT (ACK) SETUP: 80 00 00 00 00 00 02 00 - Get Status IN 02: 01 00 OUT (ACK) SETUP: 00 09 01 00 00 00 00 00 - Set Configuration: 01 IN (ACK) SETUP: 80 06 00 03 00 00 FF 00 - Get Standard String Descriptor Index:00 (Len:FF) (Language) IN 04: 04 03 09 04 OUT (ACK) SETUP: 80 06 01 03 09 04 FF 00 - Get Standard String Descriptor Index:01 (Len:FF) (Manufacturer) IN 2C: 2C 03 49 00 6E 00 67 00 2E 00 20 00 47 00 65 00 72 00 6E 00 6F 00 74 00 20 00 53 00 63 00 68 00 72 00 65 00 69 00 6E 00 65 00 72 00 OUT (ACK) SETUP: 80 06 02 03 09 04 FF 00 - Get Standard String Descriptor Index:02 (Len:FF) (Product) IN 14: 14 03 47 00 42 00 55 00 20 00 23 00 31 00 20 00 76 00 30 00 OUT (ACK) ########################### Die vielen Retrys sind aus einem älteren Log, wo noch nicht alles in Ordnung war. Jetzt ist's besser und die "echten" Retrys sind weniger: Device Descriptor, Configuration Descriptor, Language, Product.
Thomas Z. schrieb: > Da fehlen noch so einige: > USB Reset > USB Suspend > USB SetAddress > USB SetConfiguration > > Vermutung: du wertest wLength nicht richtig aus. Bei Fehlern fängt USBD > immer wieder von vorne an. > Zeig doch mal deine Deskriptoren Ich hab nur die mehrfachen aufgezählt. Die die du da auflistest kommen eh, aber eben nur einmal (ausser dem BUS Reset, aber das ist ja nicht wirklich ein Request). Im Anhang ein komplettes Log wenn Gerät "zum ersten Mal" angesteckt. Die vielen Retrys sind aus einem älteren Log, wo noch nicht alles in Ordnung war. Jetzt ist's besser und die "echten" Retrys sind weniger: Device Descriptor, Configuration Descriptor, Language, Product. Wobei ich Language & Product nach Set Configuration durchaus OK finde, könnte ja jemand ändern nach Set Config, auch wenn's so nicht in der Spec. steht. Bleibt nur noch Dev. und Conf. Desc. die meiner Ansicht nach unnötig doppelt abgefragt werden.
Gernot S. schrieb: > Im Anhang ein komplettes Log wenn Gerät "zum ersten Mal" angesteckt das sieht gut aus. SetConfiguration kommt vom Function Driver (WinUsb). Das Gerät ist danach enumeriert. Im Gerätemanager solltet du sehen können dass Winusb als Treiber verwendet wird. UsbTreeView https://www.uwe-sieber.de/usbtreeview_e.html sollte dir die Deskriptoren im Klartext anzeigen können Gernot S. schrieb: > Spec. steht. Bleibt nur noch Dev. und Conf. Desc. die meiner Ansicht > nach unnötig doppelt abgefragt werden. Das hat historische Gründe weil es früher durchaus kaputte Geräte gab. GetDesc (device) mit 0x40 wird auf der Addresse 0 abgesetzt. Weil das früher manche Geräte durcheinander brachte kommt noch mal ein Reset GetDesc(config) kommt 2mal weil ein Config Desc ja auch lännger als 0x40 sein kann. das MacOs z.B macht den 1. GetDesc(config) mit wlength 0x09 um die wTotallength rauszubekommen und den 2. Request dann mit wLength wTotalLength.
:
Bearbeitet durch User
Niklas G. schrieb: > Was einem das Testen gehörig verhageln kann: Zu vergessen > das Gerät aus Windows zu löschen nachdem man an der > Firmware etwas repariert hat. Ah ja, das kann ich mir gut vorstellen, daß einem das gelegentlich ein paar Phantom-Debug Ehrenrunden spendiert; umso mehr falls man aus irgend einem Grund zwischendurch auch mal an einem weiteren Windows PC testet. > Windows merkt sich die Kombination VID+PID+Serial > und ob es ein WCID Device ist oder nicht. Spräche in dem Zusammenhang irgendetwas dagegen, zumindest in der FW-Entwicklungs-Phase ganz einfach bei jeder neuen Version die Serial hochzuzählen? Dann sollte doch Windows das auch jedesmal als noch niemals gesehenes Gerät betrachten, oder?
Michi S. schrieb: > Spräche in dem Zusammenhang irgendetwas dagegen, zumindest in der > FW-Entwicklungs-Phase ganz einfach bei jeder neuen Version die Serial > hochzuzählen? Sollte gehen, allerdings hast du dann eine Unzahl an "alten" Geräten im Gerätemanager und in der Registry. Ich weiß ja nicht wie du arbeitest, aber so oft wie ich neu kompilieren & flashe wäre die Liste nach ein paar Tagen sehr, sehr lang ;-)
Thomas Z. schrieb: > Gernot S. schrieb: >> Im Anhang ein komplettes Log wenn Gerät "zum ersten Mal" angesteckt > > das sieht gut aus. SetConfiguration kommt vom Function Driver (WinUsb). > Das Gerät ist danach enumeriert. Im Gerätemanager solltet du sehen > können dass Winusb als Treiber verwendet wird. Gerätemanager verwende ich nicht. Aber im usbtreeview finde ich: "Service: WINUSB" > Gernot S. schrieb: >> Spec. steht. Bleibt nur noch Dev. und Conf. Desc. die meiner Ansicht >> nach unnötig doppelt abgefragt werden. > > Das hat historische Gründe weil es früher durchaus kaputte Geräte gab. > GetDesc (device) mit 0x40 wird auf der Addresse 0 abgesetzt. Weil das > früher manche Geräte durcheinander brachte kommt noch mal ein Reset Nein das meine ich nicht. Es kommt ein Get Device Desc., dann ein Bus Reset, dann ein Set Address und dann nochmal ein Get Device Desc. und danach ein Get Config Desc. Klar, ist auch so dokumentiert: https://techcommunity.microsoft.com/t5/microsoft-usb-blog/how-does-usb-stack-enumerate-a-device/ba-p/270685 Etwas später wird dann aber nochmal Dev. und Conf. Desc. geholt, das meine ich mit doppelt. Ganz interessant wird's wenn man die VID/PID ändert. Bisher hab ich mit einer Phantasie-VID/PID gearbeitet die ich leicht in der Registry finde. Da steht dann auch mein Product String im usbtreeview. Jetzt habe ich auf meine zugewiesene Microchip VID/PID umgestellt und das Windows frägt plötzlich den Manufacturer und Product String zig mal ab, als ob's nicht glauben will, dass als Manufacturer nicht "Microchip" drinn steht (siehe Log im Anhang). Es wird auch nicht mehr mein Produktname angezeigt sondern "Microchip WinUsb Device". Und es zeigt auch an, dass es weiss, dass die VID von Microchip ist: "Vendor ID : 0x04D8 (Microchip Technology Inc.)" Im Gerätemanager steht trotzdem weiterhin mein Product-String.
Gernot S. schrieb: > Nein das meine ich nicht Die hatte ich übersehen. Meine Vermutung ist, dass nach dem Get MS Extended Properties OS Feature Descriptor die Kontrolle an winusb.sys übergeben wird, der dann einfach nochmal alles einliest. Diese unsinnigen String Desc Requests mit wLength 0x1FE hab ich hier auch schon gesehen. Unsinning deshalb weil ein StringDesc ja nur max 0xFE Bytes lang sein kann. Eine Vermutung wäre dass auf deinem PC Software von Mikrochip im Hintergrund läuft die PNP Events abfängt. Die Desc Requests lassen sich ja auch vom Usermode ganz ohne Treiber absetzen.
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.