什么时候USB设备应该在散装管道上发送ZLP?

时间:2017-01-25 15:54:37

标签: windows usb winusb

我正在为与WinUSB主机通信的USB 2.0全速设备编写固件,每个方向都有一个Bulk Pipe。什么时候设备应该发送一个零长度数据包(ZLP)来终止IN传输,它怎么知道它应该?

USB 2.0 spec的第5.8.3节说:

  

当端点执行以下操作之一时,批量传输完成:

     
      
  • 已准确转移了预期的数据量
  •   
  • 传输有效负载大小小于wMaxPacketSize的数据包或传输零长度数据包[ZLP]
  •   

我将此解释为当传输大小是最大数据包大小的整数倍时,应该发送ZLP,"期望&# 34;传输大小大于实际大小(即可以发送的大小)。但收件人如何知道预期的内容?

例如,我在C#中使用WinUSBNet包装器。当我从这个管道读取时

int bytesRead;
buffer = new byte[128];
try
{
   bytesRead = m_PipeIN.Read(buffer);
   buffer = buffer.Take(bytesRead).ToArray();
}

图书馆像这样调用WinUsb_ReadPipe()

WinUsb_ReadPipe(InterfaceHandle(ifaceIndex),
   pipeID,
   pBuffer + offset,
   (uint)bytesToRead,
   out bytesRead,
   IntPtr.Zero);

假设设备正好要发送128个字节,最大数据包大小为64个字节。设备如何确定主机是什么"期待",从而是否应该发送ZLP来终止传输?

(类似于this question,但那个是关于控制管道。我问的是散装管道。)

2 个答案:

答案 0 :(得分:4)

规范说明:

<案例1
  

已准确转移了预期的数据量

这意味着如果主机期望X字节数,并且您发送完全 X字节量,则传输将在那里停止。 MPS和ZLP不参与其中。

<案例2
  

传输有效负载大小小于wMaxPacketSize的数据包或传输零长度数据包[ZLP]

这意味着如果主机期望X字节但是你想只发送Y字节,那么Y <1。 X,一旦你做了&#34;短&#34;转移就完成了。数据包,一个数据包少于MPS。如果Y字节是MPS的倍数,那么你必须做一个ZLP。

实施例1(无ZLP)

MPS = 512,主机需要 8192 字节。

您只想发送 1500 字节。有效载荷将在3个包中重复:

Packet 0: [512 bytes]  MPS
Packet 1: [512 bytes]  MPS
Packet 2: [476 bytes]  short packet

当主机获得短数据包时,它知道传输已完成,并且不再继续要求传输更多数据包。

实施例2(具有ZLP)

MPS = 512,主机需要 8192 字节。

您只想发送 2048 字节。有效载荷将在4个包中过去,如下所示:

Packet 0: [512 bytes]  MPS
Packet 1: [512 bytes]  MPS
Packet 2: [512 bytes]  MPS
Packet 3: [512 bytes]  MPS

此时,主机已收到4个MPS大小的数据包,因此它不知道传输已完成。因此它将继续请求来自设备的数据包。

Packet 4: [0 bytes]  short packet (ZLP)

当主机获得短数据包时,它知道传输已完成,并且不再继续要求传输更多数据包。

确定转移大小

您可能想知道如何确定&#34;预期&#34;自BULK传输以来没有像CTRL传输那样的长度的字节数。这完全由更高级别的协议决定,该协议指定如何在BULK管道上进行传输。主机和设备都遵循此协议,因此它们在任何给定时间同步传输多少数据。

此协议通常由类规范指定,如大容量存储类协议,或者它可能是您自己设计的一些非常简单的协议。

答案 1 :(得分:0)

  

传输有效负载大小小于wMaxPacketSize的数据包或传输零长度数据包[ZLP]

当有效载荷数据的长度恰好是wMaxPacketSize的整数倍时,必须发送ZLP

  

USB规范定义了批量传输的最后一个数据包   端点最大包大小的确切大小,整个传输   必须以零长度urb结束。

     

如果应用程序在这种情况下没有发送此消息,则libusb会超时   从不发送初始urb导致应用程序损坏。

     

所有内核驱动程序都使用URB_ZERO_PACKET来符合规范   正确。

来源:http://libusb.org/ticket/6

如果数据长度恰好是wMaxPacketSize的整数倍 第一个结束条件packetSize &lt; wMaxPacketSize不适用,因为在这种情况下packetSize = wMaxPacketSize。< / p>

所以要指出最后一个数据包已经发送的信息你需要一个ZLP,否则另一方会期望更多的数据

发送ZLP时还有其他几种情况,请参见USB in a nutshell website

相关问题