如何从处于低功耗状态的 USB 设备获取字符串描述符?

Posted

技术标签:

【中文标题】如何从处于低功耗状态的 USB 设备获取字符串描述符?【英文标题】:How to get string descriptor from a USB device which is in low power state? 【发布时间】:2018-06-25 14:28:39 【问题描述】:

我正在尝试用 C++ 编写一个应用程序,其中列出了从 USB 设备获得的信息。我正在关注 USBView (Github) 实用程序的代码。

当设备处于D0 电源状态(完全供电)时,我可以获得字符串描述符,但是当设备进入低功耗状态(D2) 时,我不能。

IOCTL IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 返回错误“连接到系统的设备无法正常工作”。 USBView 实用程序显示,当设备处于低功耗状态时,字符串描述符不可用。

这种行为很奇怪,我在 USB 规范中没有找到对它的引用。 我已经检查了 2 台设备,我得到了相同的行为。即使在D2 状态下,我也能够获取其他描述符,例如设备描述符、BOS 描述符等。

当 USB 设备处于低功耗状态时,有没有办法获取字符串描述符? 如果没有,有没有办法暂时将其变为 D0 电源状态? 可能 ACPI 是答案,但它是一个非常低级的 API,我发现它难以理解。 Windows 是否提供任何高级 API 来设置电源状态?

【问题讨论】:

【参考方案1】:

USB 2.0 规范定义了暂停模式,即总线上没有流量并且设备进入睡眠以节省电力的状态。由于没有流量,您无法从处于挂起模式的设备请求字符串描述符。你必须先用特殊的信号唤醒它,然后才能这样做。

我能想到的唯一可能对您有所帮助的是禁用“USB 选择性挂起设置”,这是 Windows 的一项功能,通常在设备不使用时将其置于挂起模式。它在控制面板的电源设置部分非常深入,所以如果您找不到它,请告诉我。

在我看来,即使设备处于选择性挂起状态,您也应该能够唤醒设备,以便您可以从中获取信息,但我不确定该怎么做,这可能取决于什么您的设备使用的驱动程序。

【讨论】:

“允许计算机关闭此设备”-> 如果这是您所说的选择性挂起选项,我已为我设备的所有祖先集线器和相应的 USB 控制器关闭它。 奇怪的是,当其他描述符可用时,为什么只有字符串描述符不可用。它们是否消耗最多的传输功率? Windows 出于需要读取了其他描述符,因为它需要它们来确定要加载哪个驱动程序。它可能将它们缓存在某个地方。没有真正的能量差异。 在Windows 10中,全局选择性挂起设置可以通过:Windows键->输入“电源”->选择“电源和睡眠设置”->“其他电源设置”->“更改计划设置”->“更改高级电源设置”->“USB 设置”->“USB 选择性挂起设置”。我不知道这是否会奏效。通常,如果您的设备安装了驱动程序并且我不需要弄乱这些设置,Windows 会做正确的事情。 我使用的是 Microsoft Surfacebook,此选项在“更改高级电源设置”中不可用。问题仍然存在,要么我想将设备状态更改为 D0,要么找出为什么在低功耗状态下无法获取字符串描述符。这个问题,我的应用程序更多的是试图理解 USB。

以上是关于如何从处于低功耗状态的 USB 设备获取字符串描述符?的主要内容,如果未能解决你的问题,请参考以下文章

设备处于低功耗模式时 SystemClock.elapsedRealtime() 漂移

检测 ios11 设备是不是处于低功耗模式,以防止正常正确自动播放视频时出现不良 UX

获取蓝牙低功耗设备的设备句柄

低功耗蓝牙Ble的详细使用流程

Android 低功耗蓝牙 - 如何访问之前配对的设备?

FreeRTOS 低功耗之睡眠模式