2

我一次有多个WinUsb_ReadIsochPipeAsap飞行,并且总是在第一个成功后立即排队下一个WinUsb_GetOverlappedResult。根据文档

WinUsb_ReadIsochPipeAsap 允许 USB 驱动程序堆栈选择传输的起始帧号。如果端点上已经有一个或多个传输处于待处理状态,则传输将被安排为紧跟在当前最后一个待处理传输的最后一个帧号之后的帧号

(重点补充)

当我测量主机上的数据速率(读取完成率)时,我只看到 6ms 的轮询速率(每 6 帧),即使描述符bInterval1,并且 6ms 甚至不是同步端点的可能轮询间隔. 该文档让我认为我应该在每一帧上看到一次传输,因为我总是有多个待处理的传输。

如果我用 USB 分析器查看总线,我看不到任何IN-NAK设备,所以我怀疑 Windows 甚至没有发出请求。

为什么我看不到完整的 1000Hz 传输速率?

4

1 回答 1

1

的论点WinUsb_ReadIsochPipeAsap

BOOL __stdcall WinUsb_ReadIsochPipeAsap(
  _In_     PWINUSB_ISOCH_BUFFER_HANDLE BufferHandle,
  _In_     ULONG                       Offset,
  _In_     ULONG                       Length,
  _In_     BOOL                        ContinueStream,
  _In_     PULONG                      NumberOfPackets,
           PUSBD_ISO_PACKET_DESCRIPTOR IsoPacketDescriptors,
  _In_opt_ LPOVERLAPPED                Overlapped
);

根据文档,的含义ContinueStream是:

ContinueStream [in]

表示只有在可以安排在最后一次挂起传输之后的第一帧中时才应提交传输。

(重点补充)

这是真的。例如,如果你第一次调用WinUsb_ReadIsochPipeAsappass TRUE,你会得到ERROR_INVALID_PARAMETER,因为没有什么可以继续了。如果您允许超过 1 帧的时间(全速 1 毫秒)并通过TRUE,您将得到ERROR_INVALID_PARAMETER因为“最后一次挂起传输后的第一帧”不再可用。

然而,尽管关于“最后一次挂起传输后的第一帧”是默认行为的语言非常相似,但Windows 实际将传输安排在连续帧中的唯一方法是将 ifContinueStream设置为TRUE. WinUsb_ReadIsochPipeAsap无论您拨打多快或拨打多少重叠电话都无关紧要。

解决方案是始终尝试ContinueStream,但如果出现故障,则退回到不继续(否则在第一次失败后您将永远失败ContinueStream):

ContinueStream = FALSE;

while (...)
{
    if ( !WinUsb_ReadIsochPipeAsap( ..., ContinueStream, ... ) )
    {
        DWORD lastError = GetLastError();

        if ( lastError == ERROR_INVALID_PARAMETER && ContinueStream)
        {
            ContinueStream = FALSE;
            continue;
        }
    }
    ContinueStream = TRUE;
    ...
}

或者,您可以重写循环以使用WinUsb_ReadIsochPipe(非 ASAP 版本),但这只需要您自己管理顺序帧号。

于 2017-05-26T00:47:53.410 回答