Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе описывается, как драйверы функций UMDF поддерживают выборочную приостановку USB.
Важные API
- IWDFUsbTargetDevice::SetPowerPolicy
- IWDFDevice2::AssignSxWakeSettings
- IWDFDevice2::AssignS0IdleSettings
Драйверы функций UMDF могут поддерживать выборочную приостановку USB двумя способами:
- При взятии на себя управления энергетической политикой и обработке режимов простоя и возобновления работы устройства.
- Используя драйвер WinUSB.sys, который предоставляет Microsoft, для управления выборочной приостановкой. WinUSB.sys устанавливается в составе стека устройств в режиме ядра во время установки USB-драйвера UMDF. WinUSB.sys реализует базовые механизмы приостановки и возобновления операции USB-устройства.
Оба подхода требуют только небольших объемов кода. Пример IdleWake, предоставленный в WDK, показывает, как поддерживать выборочную приостановку в USB-драйвере UMDF. Этот пример можно найти в %WinDDK%\BuildNumber\Src\Usb\OsrUsbFx2\ UMDF\Fx2_Driver\IdleWake. Папка содержит версии примера как с PPO, так и без PPO.
Драйверы UMDF, поддерживающие выборочную приостановку, должны соответствовать следующим рекомендациям:
- Драйвер UMDF может взять на себя ответственность за управление политикой энергопитания для своего стека устройств, но не обязан этого делать. По умолчанию базовый драйвер WinUSB.sys владеет политикой питания.
- Драйвер UMDF, поддерживающий выборочную приостановку и являющийся основным обработчиком питания (PPO), может использовать очереди с управлением питанием или очереди без управления питанием. Драйвер UMDF, который поддерживает выборочное приостановление, но не является PPO, не должен использовать управляемые энергией очереди.
Владение политикой питания в USB-драйверах UMDF
По умолчанию WinUSB.sys — это PPO для стека устройств, содержащего USB-драйвер UMDF. Начиная с WDF 1.9, USB-драйверы на основе UMDF могут претендовать на владение политикой питания. Так как только один драйвер в каждом стеке устройств может быть PPO, USB-драйвер UMDF, который является PPO, должен явно отключить владение политикой питания в WinUSB.sys.
Претендовать на право управления политикой питания в USB-драйвере UMDF
Вызовите IWDFDeviceInitialize::SetPowerPolicyOwnership и передайте true, как правило, из метода IDriverEntry::OnDeviceAdd в объекте обратного вызова драйвера. Рассмотрим пример.
FxDeviceInit->SetPowerPolicyOwnership(TRUE);Отключите владение политикой питания в WinUSB. В INF-файле драйвера добавьте директиву AddReg , которая задает значение WinUsbPowerPolicyOwnershipDisabled в реестре ненулевому значению. Директива AddReg должна отображаться в разделе DDInstall.HW. Рассмотрим пример.
[MyDriver_Install.NT.hw] AddReg=MyDriver_AddReg [MyDriver_AddReg] HKR,,"WinUsbPowerPolicyOwnershipDisabled",0x00010001,1
USB-драйверы UMDF, поддерживающие выборочную приостановку и созданные с использованием версий WDF до версии 1.9, не должны претендовать на владение политикой питания. При использовании этих более ранних версий WDF селективная приостановка USB работает правильно только в том случае, если WinUSB.sys является PPO.
Очереди ввода-вывода в USB-драйверах UMDF
Для драйвера UMDF, поддерживающего выборочную приостановку, то, владеет ли он политикой питания для своего устройства, определяет тип очередей ввода-вывода, которые могут быть использованы. Драйверы UMDF, поддерживающие выборочную приостановку и являясь PPO, могут использовать очереди, управляемые питанием или не управляемые питанием. USB-драйверы UMDF, поддерживающие выборочную приостановку, но не являются PPO, не должны использовать очереди ввода-вывода, управляемые питанием.
Если запрос ввода-вывода поступает для управляемой питанием очереди во время приостановки устройства, фреймворк не отображает запрос, если драйвер не является PPO, как показано на изображении в выборочной приостановке в USB-драйверах. Если драйвер UMDF не является PPO для устройства, платформа не может включить устройство от его имени. В результате запрос остается в очереди с управлением питанием. Запрос никогда не достигает WinUSB, поэтому WinUSB не может подключить устройство. Следовательно, стек устройств может заблокироваться.
Если очередь не управляется питанием, платформа предоставляет запросы ввода-вывода драйверу UMDF даже при отключении устройства. Драйвер UMDF форматирует запрос и пересылает его вниз по стеку устройств в целевой объект ввода-вывода по умолчанию обычным образом. Специальный код не требуется. Когда запрос достигает PPO (WinUSB.sys), WinUSB.sys включает устройство и выполняет требуемую операцию ввода-вывода.
Пример драйвера в %WinDDK%\BuildNumber\Src\Usb\OsrUsbFx2\umdf\Fx2_Driver\IdleWake определяет константу _NOT_POWER_POLICY_OWNER_ при сборке версии драйвера, отличной от PPO. Когда драйвер создает очередь для запросов на чтение и запись, определяет, следует ли создавать управляемую питанием очередь, проверяя константу.
Чтобы создать очередь, драйвер вызывает определяемый драйвером метод CMyQueue::Initialize , который принимает следующие три параметра:
- DispatchType— значение перечисления WDF_IO_QUEUE_DISPATCH_TYPE, указывающее, как очереди отправляют запросы.
- По умолчанию — это логическое значение, указывающее, является ли очередь очередью по умолчанию.
- PowerManaged— логическое значение, которое указывает, управляется ли питание очереди.
В следующем фрагменте кода показан вызов драйвера к методу CMyQueue::Initialize в рамках создания очереди чтения и записи:
#if defined(_NOT_POWER_POLICY_OWNER_)
powerManaged = false;
#else
powerManaged = true;
#endif
hr = __super::Initialize(WdfIoQueueDispatchParallel,
true,
powerManaged,
);
CMyQueue::Initialize затем вызывает IWDFDevice::CreateIoQueue , чтобы создать очередь следующим образом:
hr = m_FxDevice->CreateIoQueue(
callback,
Default,
DispatchType,
PowerManaged,
FALSE,
&fxQueue
);
Эта последовательность кода приводит к очереди по умолчанию, которая отправляет запросы параллельно. Если драйвер является PPO, очередь управляется питанием, и если драйвер не является PPO, очередь не управляется питанием.
Поддержка выборочной приостановки USB в PPO UMDF
Для поддержки выборочной приостановки USB-драйвер UMDF, который является PPO для стека устройств, должен выполнять следующие действия:
- Назначение ответственности за политику управления энергопотреблением для стека устройств обычно происходит в методе IDriverEntry::OnDeviceAdd на объекте обратного вызова драйвера, как описано ранее.
- Включите выборочную приостановку, вызвав метод IWDFDevice2::AssignS0IdleSettings на объекте устройства платформы.
Включение выборочной приостановки USB из PPO
- Вызовите IWDFDevice2::AssignS0IdleSettings, как правило, из метода OnPrepareHardware в объекте обратного вызова устройства. Установите параметры AssignS0IdleSettings следующим образом:
- IdleCaps в IdleUsbSelectiveSuspend.
- DxState в состояние спящего режима устройства, в которое фреймворк переводит неактивное устройство. Для выборочной приостановки USB укажите PowerDeviceMaximum, указывающее, что платформа должна использовать значение, указанное драйвером шины.
- IdleTimeout на количество миллисекунд, в течение которых устройство должно оставаться бездействующим, прежде чем фреймворк переведет его в состояние DxState.
- UserControlOfIdleSettings в IdleAllowUserControl, если драйвер разрешает пользователям управлять параметрами простоя, или иным образом в IdleDoNotAllowUserControl.
- Включен в WdfUseDefault , чтобы включить выборочную приостановку по умолчанию, но разрешить пользователю переопределить значение по умолчанию.
В следующем примере показано, как драйвер IdleWake_PPO вызывает этот метод во внутреннем методе CMyDevice::SetPowerManagement:
hr = m_FxDevice->AssignS0IdleSettings( IdleUsbSelectiveSuspend,
PowerDeviceMaximum,
IDLE_TIMEOUT_IN_MSEC,
IdleAllowUserControl,
WdfUseDefault);
Если оборудование устройства способно генерировать сигнал пробуждения, драйвер UMDF также может поддерживать пробуждение системы из состояний S1, S2 или S3. Дополнительные сведения см. в разделе "Пробуждение системы" в драйвере UMDF.
Поддержка селективной приостановки USB в UMDF-драйвере, не использующем PPO
Драйвер функции UMDF, который не является PPO, может поддерживать выборочное отключение, используя возможности базового драйвера WinUSB.sys. Драйвер UMDF должен уведомить WinUSB о том, что устройство и драйвер поддерживают выборочную приостановку и должны включить выборочную приостановку в INF-файле или задав политику питания на объекте USB-целевого устройства.
Если драйвер функции UMDF включает выборочную приостановку, базовый драйвер WinUSB.sys определяет время простоя устройства. WinUSB запускает счетчик времени ожидания простоя, когда нет ожидаемых передач или когда единственными ожидаемыми передачами являются передачи IN на конечной точке прерывания или массовой конечной точке. По умолчанию время ожидания простоя составляет 5 секунд, но драйвер UMDF может изменить это значение по умолчанию.
Когда WinUSB.sys определяет, что устройство неактивно, оно отправляет запрос на приостановку устройства в стеке устройств в режиме ядра. Драйвер шины изменяет состояние оборудования соответствующим образом. Если все функции устройства на порту приостановлены, порт вводит состояние выборочной приостановки USB.
Если запрос ввода-вывода поступает в WinUSB.sys во время приостановки устройства, WinUSB.sys возобновляет операцию устройства, если устройство должно быть подключено к обслуживанию запроса. Драйвер UMDF не требует никакого кода для возобновления устройства, пока система остается в S0. Если оборудование устройства может создать сигнал пробуждения, драйвер UMDF также может поддерживать пробуждение системы от S1, S2 или S3. Дополнительные сведения см. в разделе "Пробуждение системы" в драйвере UMDF.
Драйвер UMDF, который не является PPO, может поддерживать селективное приостановление, выполняя следующие два действия:
- Уведомляя WinUSB.sys, что устройство и драйвер поддерживают выборочную приостановку.
- Включение выборочной приостановки USB.
Кроме того, драйвер может дополнительно:
- Задайте значение времени ожидания для устройства.
- Разрешить пользователю включить или отключить выборочную приостановку.
Пример того, как реализовать выборочное отключение USB в UMDF-драйвере функционала USB, который не является PPO, смотрите в примере Fx2_Driver в WDK. Этот пример расположен в %WinDDK%\BuildNumber\Src\Usb\OsrUsbFx2\Umdf\Fx2_Driver\ IdleWake_Non-PPO.
Уведомить WinUSB о поддержке выборочного приостановления
Чтобы уведомить WinUSB.sys, что устройство способно поддерживать выборочную приостановку USB, INF-файл устройства должен добавить значение DeviceIdleEnabled в аппаратный ключ устройства и установить это значение на 1. В следующем примере показано, как пример Fx2_Driver добавляет и задает это значение в файле WUDFOsrUsbFx2_IdleWakeNon-PPO.Inx:
[OsrUsb_Device_AddReg]
...
HKR,,"DeviceIdleEnabled",0x00010001,1
Чтобы включить выборочную приостановку USB
USB-драйвер UMDF может включить выборочное отключение USB как во время работы, так и при установке в INF.
Чтобы включить поддержку во время выполнения, драйвер-функция вызывает IWDFUsbTargetDevice::SetPowerPolicy и задает параметр PolicyType для AUTO_SUSPEND, а параметр Value имеет значение TRUE или 1. В следующем примере показано, как образец кода Fx2_Driver реализует выборочную приостановку в файле DeviceNonPpo.cpp:
BOOL AutoSuspend = TRUE; hr = m_pIUsbTargetDevice->SetPowerPolicy( AUTO_SUSPEND, sizeof(BOOL), (PVOID) &AutoSuspend );Чтобы включить поддержку во время установки, INF включает директиву AddReg, которая добавляет значение DefaultIdleState к аппаратному ключу устройства и задает значение 1. Рассмотрим пример.
HKR,,"DefaultIdleState",0x00010001,1
Установка значения времени бездействия
По умолчанию WinUSB приостанавливает устройство через 5 секунд, если передачи не ожидаются или если единственные ожидаемые передачи — это IN передачи на прерывистом или пакетном конечном узле. Драйвер UMDF может изменить значение этого тайм-аута бездействия как во время установки в INF, так и во время выполнения.
Чтобы задать время ожидания простоя при установке, INF включает директиву AddReg, которая добавляет значение DefaultIdleTimeout к аппаратному ключу устройства и задает значение интервала времени ожидания в миллисекундах. В следующем примере задается время ожидания до 7 секунд:
HKR,,"DefaultIdleTimeout",0x00010001,7000Чтобы задать время ожидания простоя во время выполнения, драйвер вызывает IWDFUsbTargetDevice::SetPowerPolicy с параметром PolicyType, установленным в SUSPEND_DELAY, и параметром Value, установленным в значение времени ожидания простоя в миллисекундах. В следующем примере из файла Device.cpp пример Fx2_Driver задает время ожидания в 10 секунд:
HRESULT hr; ULONG value; value = 10 * 1000; hr = m_pIUsbTargetDevice->SetPowerPolicy( SUSPEND_DELAY, sizeof(ULONG), (PVOID) &value );
Для обеспечения возможности управления выборочным отключением USB пользователем
USB-драйверы UMDF, использующие выборочную приостановку WinUSB, могут при необходимости разрешить пользователю включить или отключить выборочную приостановку. Для этого добавьте директиву AddReg в INF, которая добавляет значение UserSetDeviceIdleEnabled к аппаратному ключу устройства и задает значение 1. Ниже показана строка, используемая для директивы AddReg:
HKR,,"UserSetDeviceIdleEnabled",0x00010001,1
Если задан параметр UserSetDeviceIdleEnabled, диалоговое окно "Свойства устройства" включает вкладку "Управление питанием", которая позволяет пользователю включить или отключить выборочную приостановку USB.
Пробуждение системы в драйвере UMDF
В драйвере UMDF поддержка пробуждения системы осуществляется независимо от поддержки выборочной приостановки. USB-драйвер UMDF может поддерживать как пробуждение системы, так и выборочную приостановку, ни пробуждение системы, ни выборочную приостановку, либо системное пробуждение или выборочную приостановку. Устройство, поддерживающее пробуждение системы, может проснуть систему из состояния спящего режима (S1, S2 или S3).
Драйвер UMDF USB PPO может поддерживать пробуждение системы, предоставляя сведения о пробуждении для объекта драйвера фреймворка. Когда внешнее событие активирует системное пробуждение, платформа возвращает устройство в рабочее состояние.
Драйвер USB, отличный от PPO, может использовать поддержку пробуждения системы, которую реализует драйвер WinUSB.sys.
Поддержка пробуждения системы в USB-драйвере UMDF, который является PPO**
Вызовите метод IWDFDevice2::AssignSxWakeSettings на объекте устройства платформы со следующими параметрами:
- DxState в состояние питания, в которое устройство переходит, когда система входит в способное к пробуждению состояние Sx. Для USB-устройств укажите PowerDeviceMaximum , чтобы использовать значение, указанное драйвером шины.
- UserControlOfWakeSettings на WakeAllowUserControl, если драйвер позволяет пользователям управлять параметрами пробуждения, или в противном случае - WakeDoNotAllowUserControl.
- Включено в WdfUseDefault , чтобы включить пробуждение по умолчанию, но разрешить пользователю переопределить значение по умолчанию.
В следующем примере показано, как драйвер IdleWake_PPO вызывает этот метод во внутреннем методе CMyDevice::SetPowerManagement :
hr = m_FxDevice->AssignSxWakeSettings( PowerDeviceMaximum,
WakeAllowUserControl,
WdfUseDefault);
Включение системного пробуждения через WinUSB в драйвере, отличном от PPO**
Чтобы включить системное пробуждение через WinUSB, INF драйвера добавляет значение реестра SystemWakeEnabled в аппаратный ключ устройства и задает для него значение 1. Образец IdleWake_Non-PPO предназначен для активации пробуждения системы следующим образом:
[OsrUsb_Device_AddReg]
...
HKR,,"SystemWakeEnabled",0x00010001,1
Задав это значение, драйвер включает системное пробуждение и позволяет пользователю управлять способностью устройства проснуть систему. В Диспетчере устройств страница свойств параметров управления питанием для устройства включает флажок, с помощью которого пользователь может включить или отключить системное пробуждение.