Forum: Mikrocontroller und Digitale Elektronik Full Speed WinUSB-Gerät gesucht


von Gernot S. (Firma: Ing. Gernot Schreiner) (leuchtspirale)


Lesenswert?

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.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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

von Gernot S. (Firma: Ing. Gernot Schreiner) (leuchtspirale)


Lesenswert?

> 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.

von Thomas Z. (usbman)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

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.

von Hans W. (Firma: Wilhelm.Consulting) (hans-)


Lesenswert?

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

von Thomas Z. (usbman)


Lesenswert?

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.

von Malte _. (malte) Benutzerseite


Lesenswert?

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.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

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.
von Gernot S. (Firma: Ing. Gernot Schreiner) (leuchtspirale)


Lesenswert?

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)

von Thomas Z. (usbman)


Lesenswert?

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

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

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.

von Gernot S. (Firma: Ing. Gernot Schreiner) (leuchtspirale)


Lesenswert?

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. ;-)

von Gernot S. (Firma: Ing. Gernot Schreiner) (leuchtspirale)


Lesenswert?

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.

von Gernot S. (Firma: Ing. Gernot Schreiner) (leuchtspirale)


Angehängte Dateien:

Lesenswert?

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.

von Thomas Z. (usbman)


Lesenswert?

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
von Michi S. (mista_s)


Lesenswert?

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?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

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 ;-)

von Gernot S. (Firma: Ing. Gernot Schreiner) (leuchtspirale)


Angehängte Dateien:

Lesenswert?

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.

von Thomas Z. (usbman)


Lesenswert?

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
Noch kein Account? Hier anmelden.