什么时候USB主机在控制读传输结束时需要零长度的IN数据包?

Dav*_*son 7 usb protocols packets

我正在为USB设备编写代码.假设USB主机启动控制读取传输以从设备读取一些数据,并且请求的数据量(设置数据包中的wLength)是端点0最大数据包大小的倍数.然后在主机收到所有数据(以几个具有最大数据包的IN事务的形式)之后,它是否会启动另一个IN事务以查看是否有更多数据,即使没有更多数据?

以下是我想知道的一系列事件示例:

  1. USB枚举过程:端点0上的最大数据包大小报告为64.
  2. SETUP-DATA-ACK事务启动控制读传输,wLength = 128.
  3. IN-DATA-ACK事务将前64个字节的数据传送给主机.
  4. IN-DATA-ACK事务向主机提供最后64字节的数据.
  5. 带有零长度DATA包的IN-DATA-ACK?这笔交易是否会发生?
  6. OUT-DATA-ACK事务完成传输的状态阶段; 转移结束了.

我在我的计算机上测试了这个(Windows Vista,如果它很重要),答案是否定的:主机足够聪明,知道无法从设备接收到更多数据,即使设备发送的所有数据包都已满(端点0上允许的最大大小.我想知道是否有任何主机不够智能,并将尝试执行另一个IN事务并期望接收零长度数据包.

我想我从usb.org上读到了USB 2.0和USB 3.0规范的相关部分,但我没有发现这个问题.如果有人能指出我在其中任何一个文件中的正确部分,我将不胜感激.

我知道如果设备选择发送的数据少于wLength中请求的主机,则可能需要零长度数据包.

我知道我可以使我的代码足够灵活,以处理任何一种情况,但我希望我没有必要.

感谢任何能够回答这个问题的人!

小智 9

仔细阅读USB规范:

当端点执行以下操作之一时,从端点到主机的控制传输的Data阶段已完成:

  • 已准确传输在安装阶段指定的数据量
  • 传输有效负载大小小于wMaxPacketSize的数据包或传输零长度数据包

因此,在您的情况下,当wLength ==传输大小时,答案为否,您不需要ZLP.

如果wLength>传输大小,(传输大小%ep0大小)== 0回答为是,则需要ZLP.

  • 在第一种情况下,当没有必要时发送 ZLP 是否超出规范? (2认同)

Nil*_*ils 5

通常,USB使用小于最大长度的数据包来划分传输结束.因此,在传输是max-packet-length的整数倍的情况下,ZLP用于分界.

你在批量管道中看到了很多.例如,如果您有4096字节的传输,则会将其分解为整数个最大长度数据包加上一个零长度数据包.如果SW驱动器具有足够大的接收缓冲区设置,则当ZLP发生时,更高级别的SW立即接收整个传输.

控制传输是一种特殊情况,因为它们具有wLength字段,因此ZLP不是必需的.

但我强烈建议SW对两者都要灵活,因为您可能会看到不同USB主机芯片或低级别HCD驱动器的变化.


Bor*_*ris 1

你不必这样做。(*)

wLength 的全部目的是告诉主机它应该尝试读取的最大字节数(但它可能会读取更少!)

(*) 我见过在控制传输期间(调试我们的主机解决方案时)在不正确的时间发出 IN/OUT 请求时设备崩溃的情况。因此,任何主机做你担心的事情,都会杀死这些设备,并且希望不会出现在市场上。