Hallo,
Ich habe ein Gerät xmega128a1u, daß ich mit dem PC unter Win7-Win10 via
USB -CDC verbinden will. Auf dem Xmega läuft die Kommunikation als CDC.
Auf dem PC soll eine Eigen-Software laufen, die selbstständig erkennt,
wenn das Gerät an oder abgesteckt wird. Weiterhin möchte ich, daß der
Benutzer nach Möglichkeit keine Treiber installieren soll.
Die USB-CDC-Kommunikation funktioniert sowohl unter Win7, als auch unter
Win10.
Unter Win7 muss ich jedoch eine entsprechende *.inf-Datei installieren,
was unter Win10 nicht nötig und offensichtlich auch nicht ohne weiteres
möglich ist.
Eine Erkennung, ob ein USB-Gerät an oder abgesteckt wurde funktioniert
auch, es wird die Windows-Message WM_DEVICECHANGE verwendet.
Was mir fehlt, ist eine direkte Abfrage der USB-Descriptoren im xmega.
Das kann ich mit Libusb erreichen, jedoch komme ich mit der
Standard.inf-Datei nicht an die String-Descriptoren. Um das zu erreichen
muss ich mittels dem Programm Zadig die entsprechende Umschaltung für
die Libusb vornehmen.
Unter Win10, habe ich LibusK in Zadig eingestellt, um die
String-Descriptoren auszulesen.
Dies möchte ich dem Benutzer jedoch nicht aufbürden.
Fragen:
- Wie kann ich am einfachsten die Treiber-Installation automatisieren ?
- Wie komme ich an eindeutige Informationen über das USB-Gerät
(String-Descriptor) ?
- Gibt es möglichkeiten die Eindeutigkeit mittels idVendor und idProduct
zu erreichen ? (dazu bräuchte ich nicht libusb_open() verwenden).
Danke Dieter
Dieter schrieb:> Auf dem PC soll eine Eigen-Software laufen, die selbstständig erkennt,> wenn das Gerät an oder abgesteckt wird.
Dann ist CDC nicht unbedingt sinnvoll; du kannst ja über libusb direkt
mit dem Gerät kommunizieren und brauchst den CDC-Treiber (usbser.sys)
überhaupt nicht. Dann hast du auch allgemein mehr Kontrolle über die
Kommunikation (Timing, Handshake usw).
Wenn dein USB-Gerät keine Standard-Klasse hat, kannst du es über
zusätzliche Deskriptoren als WinUSB-Device markieren. Dann wird ab
Windows 8 automatisch der WinUSB-Treiber geladen, ohne dass irgendwelche
Treiber-Installation oder Konfiguration nötig ist. Unter Windows 7 muss
man manuell per Zadig oder Geräte-Manager WinUSB auswählen.
Wenn dann WinUSB für dein Gerät aktiv ist, kannst du per libusb direkt
darauf zugreifen, Deskriptoren auslesen und Daten senden/empfangen wie
du möchtest. Das ist m.M.n sowieso die sauberere Lösung als CDC, weil so
kein anderes Programm versehentlich auf das Device zugreift und du die
Kommunikation direkt steuern kannst.
Siehe auch mein Tutorial:
https://www.mikrocontroller.net/articles/USB-Tutorial_mit_STM32#Eigene_Anwendung_f.C3.BCr_PC-Seite
Ist zwar für STM32, aber für die PC-Seite ist das egal.
Dieter schrieb:> - Wie kann ich am einfachsten die Treiber-Installation automatisieren ?
Im Zadig bzw. dessen Quellcode ist ein "wdi-simple.exe" Programm dabei,
das man als Admin bei der Installation aufrufen kann.
Die andere Alternative über WinUSB ist dort auch beschrieben: Das USB
Device gibt (IIRC über Vendor-specific Requests) dem OS zu Verstehen das
es WinUSB.sys als Treiber haben will. Funktioniert ab Win8 (IIRC).
Die LibUSBK verträgt AFAIK auch WinUSB als Backend.
Win10 hat aber USB CDC nativ, also ohne Treiber - ganz normal über einen
COM Port. Das macht die Treiber-Installation aufwändiger, denn man muss
ja den vorhanden Treiber ersetzen.
Besser wäre es den CDC Support komplett zu droppen (also Vendor Specific
Class in den Deskriptor eintragen), wenn man mit LibUSB/WinUSB arbeiten
will.
> Was mir fehlt, ist eine direkte Abfrage der USB-Descriptoren im xmega.
Schau Dir mal das SetupAPI Zeuchs an, IIRC kann man darüber viele Infos
über USB Devices ran schaffen.
Niklas G. schrieb:> Dann wird ab Windows 8 automatisch der WinUSB-Treiber geladen
Das wurde auch im Windows 7 dann mal nachgerüstet.
Ansonsten kann man den WinUSB Treiber auch so nutzen, man muss dann nix
signieren, aber ein Inf und die wdf coinstaller DLLs haben. Kann man mit
Wix in eine Setup Exe packen. Oder die dpinst daneben legen.
Vielen Dank,
ich denke, ich habe mich der libusb ein wenig verlaufen, da ich die
Verbindung von der Geräte-Kennung (VID/PID) zum zugewiesenen COM-Port
unter Windows brauche. Ich habe rausgefunden, daß ich diese Infos
mittels der Windows SetupAPI-Funktionen lesen kann. D.h. libusb ist
erstmal aussen vor.
Jedoch haben sich andere Probleme aufgetan:
- unter Windows 10 wird für CDC einfach ein Standard-Treiber verwendet,
das kann ich mittlerweile auch ganz gut auswerten
- wie kann ich aber unter Windows 7 die entsprechende inf-Datei zum CDC
automatisch installieren ?
Ich habe schon Versuche mit dpinst und devcon gemacht, bin aber nicht so
richtig zufrieden.
Meine Planung sieht wie folgt aus (für Windows 7):
- der User startet die Anwendung
- es soll geprüft werden, ob bereits ein Treiber installiert ist
- wenn ja ist gut
- wenn nein: inf-Datei installieren (z.B. devcon update ...)
Dabei ist immer zu bedenken: das USB-Gerät ist entweder eingesteckt oder
auch nicht.
Wie kann ich vernünftig die Ergebnisse prüfen, ich lasse devcon in einer
Batch laufen ?
Wie ist das mit dem automatischen online-Treiber-update, lässt sich dies
programmtechnisch abschalten (nur für diesen Vorgang) ?
Darf ich devcon und co. verwenden, wenn die Software kommerziell genutzt
wird ?
Danke Dieter
Dieter schrieb:> Eine Erkennung, ob ein USB-Gerät an oder abgesteckt wurde funktioniert> auch, es wird die Windows-Message WM_DEVICECHANGE verwendet.> Was mir fehlt, ist eine direkte Abfrage der USB-Descriptoren im xmega.
Die vollständigen Descriptoren kann man nicht einfach abfragen, aber
VID/PID geht. Ein elegante RegEx auf die HardwareID des neu erkannten
(aber "unbekannten") Gerätes anwenden.
> Fragen:> - Wie kann ich am einfachsten die Treiber-Installation automatisieren ?
1) Setup-Api benutzen, um die HardwareID des neuen "unbekannten" Gerätes
zu ermitteln.
2) s.o.
3) erhöhte Rechte anfordern (der Benutzer muss dann die UAE-Frage
abnicken)
4) passende *.inf aus Programmresource holen und als Datei speichern.
5) Treiberinstallation für diese *.inf anstoßen
Allerdings: Punkt 3 wird fehlschlagen, falls der Benutzer nicht lokaler
Admin ist. Dann wäre die letzte Ausweichmöglichkeit: Impersonation eines
Admin-Accounts, zu dem der Benutzer die Credentials besitzt.
Hat er die nicht, hat er verloren. Und das ist GUT SO!
Eine Anwendung die einen Treiber installiert? Naja ich weiß nicht. Wieso
kein sauberes Setup für Anwendung und Treiber? Das kannste dir ganz
einfach in Wix zusammen stellen.
Ansonsten gibts das API was hinter dpinst steckt, ja auch zur
Integration in eigene Software, macht Wix ja auch nicht anders:
https://technet.microsoft.com/en-us/ff544838(v=vs.96)
Christian R. schrieb:> Eine Anwendung die einen Treiber installiert?
Nicht die Anwendung installiert den Treiber. Sie stößt die
Treiberinstallation nur an.
Und das ist der absolute Normalfall. Jedenfalls unter Windows. Der
Unterschied ist hier nur: es ist "ausnahmsweise" mal keine Anwendung,
die Windows im Lieferumfang mitbringt...
Das "ausnahmsweise" steht aber ganz bewußt in Anführungsstrichen. Es
gibt nämlich unzählige, durchaus verbreitete Anwendungen, die in der
Lage und willens sind, zur Laufzeit eine Treiberinstallation anzustoßen.
Naturgegeben natürlich besonders Anwendungen vom "portable"-Typ...
Christian R. schrieb:> Eine Anwendung die einen Treiber installiert?
Es gibt USB-Devices, z.B. als Development Device, die enthalten nicht
nur Hardware, sondern in einem ROM auch die gesamte Software - nicht nur
Treiber, sondern z.B. alles bis zum C-Compiler. Die muss man wirklich
nur einstecken und alles abnicken.
Ich finde das Konzept aber fragwürdig, nicht nur wegen des Aufwands,
sondern auch weil die Software niemals aktuell ist. Praktisch muss man
nach der Installation gleich updaten, da kann man sich Treiber usw. auch
gleich aus dem Netz holen.
Georg