Forum: PC-Programmierung Wie Standby von USB verhindern?


von Peter (Gast)


Lesenswert?

Hallo,
ich habe ein HID USB Device und ein eigens Programm dafür geschrieben.

Beim Testen unter Windows 8.1 ist mir aufgefallen das Windows die 
Powereinstellungen falsch macht und mein Device in einen Stromsparmodus 
schickt. Das ist für mich eine Katastrophe, da dann irgendwas nicht mehr 
sauber läuft.

An jedem Rechner in der registry herum zu suchen und die Werte zu ändern 
ist absolut nicht praktikabel.

Hat jemand eine Ahnung wie ich verhindern kann das Windows mein Device 
runter fährt?

Peter

von bluppdidupp (Gast)


Lesenswert?

Ein USB-Device sollte normalerweise nur dann in den Suspend-Mode 
geschickt werden, wenn für ein paar ms keine Aktivität mehr auf dem 
USB-Bus war oder z.B. der Rechner selbst in den Ruhezustand/Standby 
geschickt wird.

D.h. es könnte einfach ausreichen, wenn man dafür sorgt dass dauernd mit 
dem Gerät kommuniziert wird (irgendwelche Keepalives) und nicht nur 
gelegentlich

von Christian R. (supachris)


Lesenswert?

Das macht doch der USB Stack schon. Ich vermute den Fehler eher im 
Device. Vielleicht antwortet das nicht schnell genug auf das Polling? 
Zumindest bis Windows 8.0 hatte der Windows USB Stack keine bekannten 
Bugs. Ist das so ein VUSB Gefrickel?

von Peter (Gast)


Lesenswert?

Mit VUSB hat das nichts zu tun, das ist ein STM32F407.

Dem Device immer was zu senden nur weil WIN8.1 beim anlegen anscheinend 
Standardmäßig ein Flag falsch setzt ist wohl etwas daneben.

Der PC ist normal in betrieb und das Programm redet auch fleißig mit dem 
Device. Nur seit WIN8.1 sind halt die Einstellungen falsch und ich würde 
gerne das umgehen oder dafür sorgen das es richtig angelegt wird.

In den USB Kennungen finde ich keine Angaben zum Suspendmode.
Aber auch auf PC Seite finde ich irgendwie nichts.

Kann sein das ich es immer überlese und falsch suche.

Peter

von bluppdidupp (Gast)


Lesenswert?

Ich würde erstmal testweise "selektives USB-Energiesparen" in den 
Energieoptionen abschalten.
http://blogs.msdn.com/b/usbcoreblog/archive/2011/05/11/demystifying-usb-selective-suspend.aspx

von Christian R. (supachris)


Lesenswert?

Dieses Polling macht der Host Controller mit dem Stack auf unterster 
Ebene. Wenn das ein Controller mit echtem USB ist, liegts sicher daran 
nicht, da hast du wohl recht. In den Descriptoren gibts da meines 
Wissens keine Einstellung, aber Windows meldet den Standby ja am Gerät 
an, das kann man doch auch ablehnen...

von Frank M. (frank_m35)


Lesenswert?

Wenn du das Programm für das HID Device selbst programmiert hast und 'da 
dann irgendwas nicht mehr sauber' läuft wenn du es an einen gewöhnlichen 
08/15 Windows PC anschließt, mit dem sonst ALLE anderen USB Geräte 
sauber laufen, dann würde ich den Fehler doch erst einmal in der 
Firmware des HID Devices selber suchen, anstatt an Windows eine 
Einstellung zu ändern die man nicht ändern sollte, sondern das HID 
Device damit ordnungsgemäß umgehen können sollte.

(Da es erst seit Win 8.1 ist, könnte sein, dass win 8.1 eben aggressiver 
mit den Energiesparplänen umgeht und dein HID Device eben schon immer 
diesen Fehler hatte der bisher eben nie auftauchte da du bspw. nie den 
Standby Modus benutzts oder nur an einem Desktop PC arbeitest, ..., 
andere Geräte arbeiten ja anscheinend Problemlos mit Win 8.1)

von Arc N. (arc)


Lesenswert?

Frank M. schrieb:
> (Da es erst seit Win 8.1 ist, könnte sein, dass win 8.1 eben aggressiver
> mit den Energiesparplänen umgeht und dein HID Device eben schon immer
> diesen Fehler hatte der bisher eben nie auftauchte da du bspw. nie den
> Standby Modus benutzts oder nur an einem Desktop PC arbeitest, ...,
> andere Geräte arbeiten ja anscheinend Problemlos mit Win 8.1)

Richtig,
"Windows 8.1: What's new for USB"
http://msdn.microsoft.com/en-us/library/windows/hardware/dn303354%28v=vs.85%29.aspx
http://msdn.microsoft.com/library/windows/hardware/dn385748
http://blogs.msdn.com/b/usbcoreblog/archive/2011/05/11/demystifying-usb-selective-suspend.aspx

von Peter (Gast)


Lesenswert?

So nach dem ich etliches gelesen habe bin ich zwar schlauer aber 
geholfen hat es nicht.

Mein Device darf unter keinen Umständen in einen Standby geschickt 
werden.
Ich jage je nach Betriebs Modus bis zu 800 MSGs hin und zurück.
Aber es kann auch mal nur alle 10 Minuten eine MSG gesendet werden.
Das Device muss aber in der Lage sein sofort zu senden und ich brauche 
logischerweise ständig meine 500mA

Gibt es denn keine Funktion mit der ich von meinem WIN Programm 
wenigstens sagen kann: "nicht in den Suspendmodus".

Peter

von bluppdidupp (Gast)


Lesenswert?

Lass dein Device doch mal irgendwo wegloggen oder LED togglen oder 
sowas, wenn es in den Suspend-Mode geht und wann es wieder aufwacht. 
Quasi um erstmal herauszufinden, ob es daran überhaupt liegt.

Peter schrieb:
> Gibt es denn keine Funktion mit der ich von meinem WIN Programm
> wenigstens sagen kann: "nicht in den Suspendmodus".
Das gibt üblicherweise der Treiber vor, in deinem Falle vermutlich der 
Standard HID-Treiber von Microsoft  - Der in aktuellen Windows-Versionen 
dem Host-Controller scheinbar relativ früh sagt es soll das jeweilige 
Gerät in Suspend schicken. Für "normale" HID-Geräte wie Maus/Tastatur 
vermutlich auch relativ unproblematisch, weil man die Verzögerung durch 
Wakeups durch das USB-Device als Anwender kaum bemerken dürfte.
Ich würde aber vermuten, das ununterbrochenes Senden von irgendwelchen 
Dummy-Reports dafür sorgt das der HID-Treiber sich ausrechnet, dass es 
sich nicht lohnt das Gerät schlafen zu legen.
Man kann aber in den Energieoptionen Selective Suspend deaktivieren und 
im Gerätemanager gibt es bei den USB-Geräten auch nochmal 
Energieeinstellungen.

von Peter (Gast)


Lesenswert?

Das Problem ist doch mal wieder der Benutzer.
Den interessiert es doch nicht was Windows hier für Energie 
Einstellungen hat. Wenn es nicht geht wird gemeckert und sonst wo was 
negatives berichtet.
Ich verdiene damit zwar kein Geld (Verein) aber negative Meldungen will 
ich auch nicht haben.

Das mit dem Debuggen ist nicht so einfach, ich habe selber kein WIN8.1 
wo ich das selber testen kann.
Ich sende die Software zu einem Kumpel der hat aber keine Ahnung davon.
Der kann nur mit dem Gerät arbeiten und inzwischen die Software 
einspielen.

Peter

von bluppdidupp (Gast)


Lesenswert?

Hmm, dann könnte man die Evaluations-Version runterladen und irgendwo 
zum Debuggen installieren:
http://technet.microsoft.com/de-de/evalcenter/hh699156.aspx

von Christian R. (supachris)


Lesenswert?

Anscheinend kann man das über die Microsoft OS Descriptoren einstellen. 
Schau mal hier: 
http://msdn.microsoft.com/en-us/windows/hardware/gg463179 da gibts die 
Doku unten. Und in dem File "OS_Desc_Ext_Prop.doc" steht ab Seite 8 wie 
man den Slective Suspend bei HID einstellt. Offenbar musst du nur den 
Descriptor hinzufügen und dann wird der Registry Wert beim Anstecken 
geschrieben.

von Peter (Gast)


Lesenswert?

Das klingt interessant.
Muss jetzt nur noch herausfinden wo ich was eintragen muss.

von Christian R. (supachris)


Lesenswert?

Naja, das ist bissl Gewurschtel, denn diese OS Descriptoren müssen 
manuell im Device eingetragen werden. Prinzipiell aber nichts anderes 
als der String Descriptor für die Seriennummer. Nur der Index ist recht 
hoch, kann sein, dass das jeweilige USB Framework sowas nicht 
unterstützt. Am Cypress FX3 jedenfalls ging das erst mit einem API 
Update.

von Peter (Gast)


Lesenswert?

Ich finde bis jetzt nicht wie ich das überhaupt eintragen soll.

Also weder den Discriptor noch auf welche Anforderung ich den senden 
soll oder wie der wo abgehangen werden muss.

von Christian R. (supachris)


Lesenswert?

Wo trägst du denn die anderen USB Descriptoren wie z.B. SerialNumber 
ein? Was für ein Controller ist das denn eigentlich? Windows fragt dann 
das Device, ob es einen Descriptor an 0xEE hat, da muss dann dein Device 
bzw. das USB Framework drauf antworten und den OS Descriptor 
liefern.....vereinfacht ausgedrückt.

von Peter (Gast)


Lesenswert?

Wo hast Du das mit 0xEE her?

Das hier wäre ja das was ich senden will.
Field               Value
dwSize              0x00000042 (66 Bytes for this property)
dwPropertyDataType  0x00000004 (REG_DWORD_LITTLE_ENDIAN)
wPropertyNameLength 0x0030
bPropertyName       “SelectiveSuspendEnabled” (Unicode string)
dwPropertyDataLength 0x00000004 (Sizeof(DWORD))
bPropertyData        0x00000000 (DWORD data)


In der Descriptor Liste ist zB.
0x0100   device discriptor
0x0200   Config
0x0302  Produkt string
0x2200 HID report

Und wie ist nun die Extended property ID?

Ich finde es einfach nicht.

von Christian R. (supachris)


Lesenswert?

Soweit ich das verstanden habe, muss an Index 0xEE erst mal der OS 
Descriptor, in dem dann steht, ob und wieviele solche Extendes property 
descriptoren wo stehen. So ganz bin ich da aber auch noch nicht 
durchgestiegen, ich hatte nur auf meinem FX3 mal den WinUSB Descriptor 
probiert, das ging so einigermaßen. So wie der StringDescriptor für die 
Seriennummer immer an Index 03 zu finden ist, muss der OS Descriptor an 
Index 0xEE. Da geht alles los, Windows fragt dort nach einem OS 
Descriptor.
Vielleicht nochmal hier als Einstieg: 
http://msdn.microsoft.com/en-us/library/windows/hardware/ff537430%28v=vs.85%29.aspx

von Peter (Gast)


Lesenswert?

Unter
https://github.com/pbatard/libwdi/wiki/WCID-Devices

wird einiges endlich mal vernünftig beschrieben.

Ob das allerdings dann auch so arbeitet wird sich zeigen.
Denn so richtig habe ich das immer noch nicht richtig Verstanden.

Peter

von Peter (Gast)


Lesenswert?

So nachdem ich alles eingebaut habe und auch darauf geachtet habe das 
ich USB Typ 2.0 sende passiert leider nichts.

Es wird kein String mit der ID 0xEE abgerufen und somit auch der andere 
Kram nicht.
Ich hatte erst vermutet das ich mit einer Abfrage was blockiere aber 
auch wenn ich alles umgehe und nur auf die 0xEE Info warte kommt nichts.

Habe das ganze auch in ein ATMEGA32u4 Projekt (Teensy) eingebunden, aber 
auch hier passiert nichts.

Ich könnte jetzt zwar den ganzen Code hier posten, aber der wäre im 
Moment nur eine Teensy RAWHID clone mit ein paar abfragen auf den String 
0xEE.

Hat jemand eine Idee warum es nicht zu der String Abfrage kommen könnte?

Peter

von Christian R. (supachris)


Lesenswert?

Ich hatte das hier aus dem Cypress Forum damals mal probiert: 
http://www.cypress.com/?app=forum&id=167&rID=63044

von Sebastian__ (Gast)


Lesenswert?

Lt. Micosoft ist das das neue Verhalten für alle Generic Hid Devices. 
Das kann man auch nicht deaktivieren.

Was aber bei Windows 8.1 hilft ist ein offenes Handle auf das Gerät.
Sobald man kein offenes Handle auf das Gerät hat wird der USB Port in 
den Suspend zustand versetzt.

Man kann das auch direkt für jedes Gerät in der Registry deaktivieren. 
Dazu muss man mit der Software sein Gerät in der Registry suchen und die 
Entspechenden Flags setzen. (Admin Rechte nötig)

Von diesem Problem sind im moment recht viele Geräte betroffen.

von Christian R. (supachris)


Lesenswert?

Sebastian__ schrieb:
> Man kann das auch direkt für jedes Gerät in der Registry deaktivieren.

Genau das macht (laut MS Doku) der Eintrag in dem erweiterten OS 
Descriptor. Damit umgeht man das Problem. Allerdings muss man halt die 
neuen Descriptoren erst mal bei der Enumeration passend bereitstellen.

Ich denke (nach dem nachmaligen Lesen des Forums bei Cypress), dass der 
TE auf den entsprechenden Vendor Request mit bRequest = 0x06 und 
wValue = 0x03EE reagieren muss. Das ist offenbar der Unterschied zu den 
Standard Descriptoren. Dann könnte es funktionieren, den Regitry Eintrag 
durch den OS Descriptor setzen zu lassen.

von Peter (Gast)


Lesenswert?

Ich habe normalerweise ständig einen offen Handle, aber bis das Programm 
läuft ist es zuspät und der Suspend kram ist angelaufen.

Habe heute eine Debugversion gebaut und ich glaube was gefunden zu 
haben.
Muss ich aber noch prüfen.
Melde mich wenn es was neues gibt.

Irgendwie ist es beruhigend das ich nicht der einzige bin.

Peter

von Peter (Gast)


Lesenswert?

Da war jemand schneller.

Im Teensy Projekt wird der String noch auf WIndex geprüft und ich 
vermute auch in meinem STM32 Code ist das so.
Und da vermute ich jetzt einen Fehler.

von Peter (Gast)


Lesenswert?

Wenn man die wIndex abfrage auf == 0x0000 setzt geht es.
Der String wird abgerufen und anscheinend auch die weiteren Daten.

Nur etwas ist noch faul, weil ich den registry Eintrag nicht finde.

Da der abgerufen wird sollte der Fehler zu finden sein.

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.