cp.*_*ngr 3 windows usb winusb
我正在为与WinUSB主机通信的USB 2.0全速设备编写固件,每个方向都有一个Bulk Pipe。设备何时应该发送零长度数据包(ZLP)来终止IN传输,它如何知道应该这样做?
USB 2.0规范的第5.8.3节说:
当端点执行以下操作之一时,批量传输完成:
- 已准确传输了预期的数据量
- 传输有效载荷大小小于wMaxPacketSize的数据包或传输零长度数据包[ZLP]
我的解释是,当传输大小是最大数据包大小的整数倍,并且传输的“预期”大小大于实际大小(即可以发送的大小)时,应该发送ZLP 。但是接收者如何知道期望的呢?
例如,我在C#中使用WinUSBNet包装器。当我从这样的管道中读取时
int bytesRead;
buffer = new byte[128];
try
{
bytesRead = m_PipeIN.Read(buffer);
buffer = buffer.Take(bytesRead).ToArray();
}
Run Code Online (Sandbox Code Playgroud)
该库将这样调用WinUsb_ReadPipe():
WinUsb_ReadPipe(InterfaceHandle(ifaceIndex),
pipeID,
pBuffer + offset,
(uint)bytesToRead,
out bytesRead,
IntPtr.Zero);
Run Code Online (Sandbox Code Playgroud)
假设设备正好有128个字节要发送,最大数据包大小为64个字节。设备如何确定主机在“期待”什么,因此是否应发送ZLP来终止传输?
(类似于这个问题,但是那是关于控制管道的。我要问的是散装管道。)
规格说明:
已准确传输了预期的数据量
这意味着,如果主机期望X个字节的数量,而您恰好发送了 X个字节的数量,则传输就在那里停止。MPS和ZLP不起作用。
传输有效载荷大小小于wMaxPacketSize的数据包或传输零长度数据包[ZLP]
这意味着,如果主机期望X个字节,但您只想发送Y个字节(Y <X),则在完成“短”数据包(比MPS少的数据包)后,传输就完成了。如果Y字节是MPS的倍数,则必须执行ZLP。
MPS = 512,主机期望8192字节。
您只想发送1500个字节。有效负载将以3个数据包的形式经过:
Packet 0: [512 bytes] MPS
Packet 1: [512 bytes] MPS
Packet 2: [476 bytes] short packet
Run Code Online (Sandbox Code Playgroud)
当主机收到短数据包时,它知道传输已完成,并且不会继续请求更多数据包进行传输。
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
Run Code Online (Sandbox Code Playgroud)
此时,主机已收到4个MPS大小的数据包,因此它不知道传输已完成。因此它将继续从设备请求数据包。
Packet 4: [0 bytes] short packet (ZLP)
Run Code Online (Sandbox Code Playgroud)
当主机收到短数据包时,它知道传输已完成,并且不会继续请求更多数据包进行传输。
您可能想知道如何确定“预期的”字节数,因为BULK传输没有CTRL传输那样长。这完全由更高级别的协议决定,该协议指定如何在BULK管道上进行传输。主机和设备都遵循此协议,因此它们在任何给定时间都可以同步传输多少数据。
该协议通常由类规范(例如,大容量存储类协议)指定,或者可以是您自己设计的一些非常简单的协议。