SB 是一种非常可靠的网络介质,不会发生冲突。这意味着几乎没有数据包丢失或损坏。因此,互操作性测试从未在数据包丢失时检测到 cornercases。
然而,对于新兴的无线 USB 连接,情况有所不同。由于无线介质中存在冲突的可能性,因此在将应用程序从有线 USB 迁移到无线 USB 时必须小心。
本文解决了有线和无线 USB 中都可能发生的问题。但是因为在无线介质中丢失数据包的机会要大得多,所以问题更可能发生在无线 USB中而不是有线 USB中。问题是“丢失一个数据包的危险”。
当开发人员忽视这个问题时,即使丢失一个数据包也会导致严重的问题。本文旨在帮助无线 USB 开发人员了解问题并为实施解决方案提供一些线索。
它首先对问题进行了详细描述,然后分析了为什么它在无线 USB 中成为问题,而在有线 USB 中不是问题。文末会给出解决这个问题的一些线索。
图 1:当设备需要向主机发送完整的数据缓冲区,而主机为一个数据包发送的握手丢失时,可能会出现实现问题。
当它发生时当设备需要向主机发送完整的数据缓冲区并且主机为传输中的一个数据包(或突发中的几个数据包)发送的握手被破坏或在空中丢失时,就会出现这个特殊问题。
由于主机必须发送握手的短次数,因此设备端可能看不到那些包含数据包中一个批量(或突发中的几个数据包)的握手的微调度管理命令 (
MMC)。
在这种情况下,设备必须将那部分数据保存在缓冲区中,直到它看到握手(如果有的话)以保持数据完整性。这种情况将导致实施中出现问题,如上图 1 所示。
在这种情况下,设备将不会引发任何中断或任何事件来向更高层软件指示数据已被主机正确接收。事实上,它不应该,因为设备认为本次传输的一部分数据没有成功传输到主机端,主机可以再次轮询数据。
如果更高层协议的状态机(例如类驱动程序)需要这种显式的握手/中断才能进入下一阶段,那么整个状态机将被卡住。这将导致死锁情况,并且整个设备实现将无法处理这种情况。
请记住,丢失一个数据包的问题在无线 USB 中并不常见,在有线 USB 中也可能发生。设计师在设计有线 USB 时也必须注意这一点。不同之处在于,无线媒体的可靠性远低于有线媒体。
图 2:显示了一些轨迹以说明当设备未看到 IN 的握手时发生的大容量存储问题。
与数据包几乎从不丢失的有线 USB 相比,数据包会经常丢失。万一设计人员忽视了这个问题,在有线系统中发现的可能性非常低,但在无线 USB 中却相当高。让我们举一个实际的例子。在大容量存储设备实现的情况下,以下序列总是发生多次:
CBW—
BULKOUT—31 字节数据阶段—BULK IN或 BULK OUT—数据包大小的多个事务CSW – IN—13 字节特别是对于大容量存储,当设备未看到 IN – 13 字节的握手时,可能会出现此问题。上面的图 2中显示了一些轨迹 来说明这个问题。
在下面的图 3中,无线 USB 数据包 291 是来自主机的 MMC,其中包括一个 WdtCTA,用作对先前 In 数据包(无线 USB 数据包 288)的确认。只有当设备收到此 MMC 时,它才能声明特定的数据包已被主机接收。在这种特殊情况下,设备在接收到嵌入在数据包 291 中的确认之前,无法声称 CSW 数据包已成功传送到主机。但是如果此数据包在空中丢失怎么办?从这个特定的主机实现中,我们可以看到它只会发送带有确认的 MMC。在无线世界中,丢失此数据包的可能性不容忽视。
图 3:在无线世界中,丢失数据包 291 的可能性——来自主机的 MMC,其中包括一个 WdtCTA,用作对先前 In 数据包的确认——不可忽略。
在一些为大容量存储编写的传统 USB 类驱动程序中,类驱动程序内部的状态机只有在收到状态完成事件时才会被触发(在大多数情况下,它是来自设备
控制器的中断或来自较低级别堆栈的事件)。
更具体地说,在大容量存储状态机中,类驱动程序总是期望在 IN 管道上完成接收 CSW 的 13 个字节,然后再进行进一步的操作,例如,将状态机移至 CBW 阶段,并对设备控制器进行编程以在出管。
如果 CSW 的 ACK 被破坏,虽然它实际上被无线 USB 主机接收到,但主机端和设备端的类驱动程序状态机之间将存在不匹配。主机会将类状态机移至 CBW 阶段,如果发现特定的 OUT 管道处于活动状态,则随时准备发送 CBW。
但不幸的是,OUT 管道使能操作通常是由设备类状态机的 CBW 阶段的一些软件操作触发的。这意味着在
总线上不会有任何用于 EPxOUT 的 DN_EPRdy 被发送出去以指示管道处于活动状态。同时,设备类状态机将保持在 CSW 阶段,等待 CSW 完成(设备无法知道 CSW 数据包已被主机接收,除非已从设备安排进一步传输)。由于这种不匹配,产生了死锁。
设备端管理设备端的类驱动程序需要仔细管理这种情况,考虑到“丢包”的情况。大容量存储中此问题的典型解决方案是更改状态机,以便 CBW 的 OUT 管道将在设备类状态机的 CSW 阶段内激活,因此设备端不会阻塞下一个 CBW 的总线活动。该解决方案适用于解决大容量存储类和其他情况下 CSW 丢失的 ACK。
在无线 USB 世界 - 甚至是有线 USB 世界 - 设备端的任何类驱动程序定义了一个协议,该协议在 IN 端点传输完成后将数据包发送到 OUT 端点必须注意它在编程后启用 OUT 数据包的接收。在转移。它必须等到看到 IN 传输完成中断后才能启用 OUT 数据的接收。