Hi Leute,
Für ein aktuelles Projekt mit einem STM32F4 + SMSC3300 habe ich eine USB
2.0 Schnittstelle mittels CDC-ACM und dem Windows 7-internen Treiber
(usbser.sys) realisiert, die auch gut funktioniert.
Aus Gründen des Stromsparens (d.h. nicht nur der Controller, sondern
auch der SMSC3300 soll ebenfalls wenig Strom verbrauchen) möchte ich
gerne das Gerät in den USB Suspend (D3 power mode) versetzen.
Ich bin nun schon so weit gekommen, dass es ausreicht, wenn der USB Host
das Senden der SOF (für das Pollen der Daten vom Device) unterlässt.
Also schnell mal ausprobiert, PC in den Standby geschickt, und die 1ms
Impulse verschwinden vom Oszilloskop, das Gerät erkennt erfolgreich den
Suspend und alles funktioniert. Nun soll allerdings nur dieses eine
Gerät in den USB Suspend geschickt werden, das Ganze ist wohl unter dem
Namen "Selective Suspend" bekannt.
Die Frage, die sich mir jetzt stellt ist, wie kann ich (in diesem Falle)
Windows dazu animieren, ein USB Device in den Suspend zu schicken?
Dafür habe ich zu aller erst in der .INF Datei für Windows folgendes
hinzugefügt:
1 | [DriverInstall.HW]
|
2 | AddReg=SuspendAddReg
|
3 |
|
4 | [SuspendAddReg]
|
5 | HKR,,DeviceIdleEnabled,0x00010001,1
|
6 | HKR,,DeviceIdleIgnoreWakeEnable,0x00010001,1
|
7 | HKR,,UserSetDeviceIdleEnabled,0x00010001,1
|
8 | HKR,,DefaultIdleState,0x00010001,1
|
9 | HKR,,DefaultIdleTimeout,0x00010001,100
|
und den Treiber erneut installiert. Schaue ich in der Registry unter
HKLM/SYSTEM/CurrentControlSet/Enum/USB/VID_XYZ/Device Parameters nach,
dann sehe ich dort auch diese Schlüssel.
Soweit, so gut, vorsichtshalber mal das Gerät abgesteckt und wieder
angesteckt. Das erste, was ich sehe ist, dass in den Eigenschaften der
virtuellen COM-Schnittstelle kein neuer Tab bzgl. des Stromsparens
auftaucht (UserSetDeviceIdleEnabled) - Merkwürdig.
Naja, als nächstes einfach mal das Gerät deaktiviert. Schaue ich dann
in die Eigenschaften/Details/Energiedaten bestätigt mir Windows, dass
der aktuelle Energiestatus des Gerätes 'D3' ist. Klingt ja erst mal ganz
gut!
Allerdings weiß das Gerät davon nichts. Es befinden sich immer noch die
1ms SOF Pulse auf den USB Datenleitungen.
Eventuell kann der USB Hub kein Selective Suspend? Wenn ich mir die Hubs
im Gerätemanager anschaue, dann besitzt jeder der Hubs ein Tab für
"Energieverwaltung" und dort ist die Checkbox, die bestätigt dass
Windows das Gerät ausschalten darf auch angehakt.
Habe testweise das Gerät noch mal direkt an den Root-Hub angeschlossen,
ohne jede Veränderung.
Ist Selective Suspend bei Hubs irgendwas neumodisches? Zugegebenermaßen
sind die Rechner, die ich hier zur Verfügung habe > 5 Jahre alt.
Meine zweite Frage bezüglich der Sache ist, folgende. Laut Microsoft,
unterstützt die Device Class "USB Modem" (was vermutlich CDC ist)
Selective Suspend(1). Angeblich versetzt der Windows CDC Treiber das
Gerät in den Betriebszustand "Idle", wenn kein Handle auf die
Schnittstelle geöffnet ist. Mit den oben von mir vorgenommenen
Einstellungen in der INF Datei müsste demnach das Gerät nach 100ms Idle
automatisch in den Suspend Modus wechseln. Leider zeigt Windows im
Geräte Manager immer den Energiezustand D0 für das Gerät an, egal ob
ein Handle geöffnet ist oder nicht.
Hat hier jemand einen Tipp, wie man da weiter vorgehen könnte zwecks
Diagnose? Oder wo das Problem sein könnte?
Es wäre für meinen Anwendungszweck super hilfreich, wenn das Gerät immer
nur beim Öffnen des Handles resumed wird und nach dem Schließen wieder
suspended wird. Das wäre sozusagen der Idealfall.
Falls usbser.sys kein Selective Suspend unterstützt. Gibt es eine andere
Möglichkeit sich um den Treiber drumherum zu mogeln? Irgendwo las ich,
dass man selbst einen WinUSB Treiber schreiben könnte, der dann die
Daten an den CDC Stack weiterleitet. Wie auch immer, CDC ist ja nicht
sonderlich kompliziert. Möglicherweise würde es schon reichen, wenn ich
einen einfachen Treiber mit WinUSB selber schreiben könnte. Ist dies
realistisch? Benötigt man dafür irgendwelche kostenpflichtige Software
oder funktioniert das beispielsweise mit dem VS-Express und einem
Development Kit von MS?
(1)
http://msdn.microsoft.com/en-us/library/windows/hardware/dn423379%28v=vs.85%29.aspx#selsuspend
EDIT: Achja, der "Stromsparplan" von Windows 7 lässt Selective Suspend
übrigens zu. Kann das sein, dass man mein Problem sogar damit lösen
kann, indem man Windows 8.1 installiert? ;-)
Viele Grüße und im Voraus schon mal Danke für jegliche Hinweise