USB 主机何时需要在控制读传输结束时使用零长度 IN 数据包?

发布于 2024-09-24 06:39:58 字数 849 浏览 2 评论 0原文

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

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

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

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

我想我从 usb.org 阅读了 USB 2.0 和 USB 3.0 规范的相关部分,但我没有发现这个问题得到解决。如果有人能指出我在这些文档中的正确部分,我将不胜感激。

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

我知道我可以使我的代码足够灵活来处理这两种情况,但我希望我不必这样做。

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

I am writing code for a USB device. Suppose the USB host starts a control read transfer to read some data from the device, and the amount of data requested (wLength in the Setup Packet) is a multiple of the Endpoint 0 max packet size. Then after the host has received all the data (in the form of several IN transactions with maximum-sized data packets), will it initiate another IN transaction to see if there is more data even though there can't be more?

Here's an example sequence of events that I am wondering about:

  1. USB enumeration process: max packet size on endpoint 0 is reported to be 64.
  2. SETUP-DATA-ACK transaction starts a control read transfer, wLength = 128.
  3. IN-DATA-ACK transaction delivers first 64 bytes of data to host.
  4. IN-DATA-ACK transaction delivers last 64 bytes of data to host.
  5. IN-DATA-ACK with zero-length DATA packet? Does this transaction ever happen?
  6. OUT-DATA-ACK transaction completes Status Phase of the transfer; transfer is over.

I tested this on my computer (Windows Vista, if it matters) and the answer was no: the host was smart enough to know that no more data can be received from the device, even though all the packets sent by the device were full (maximum size allowed on Endpoint 0). I'm wondering if there are any hosts that are not smart enough, and will try to perform another IN transaction and expect to receive a zero-length data packet.

I think I read the relevant parts of the USB 2.0 and USB 3.0 specifications from usb.org but I did not find this issue addressed. I would appreciate it if someone can point me to the right section in either of those documents.

I know that a zero-length packet can be necessary if the device chooses to send less data than the host requested in wLength.

I know that I could make my code flexible enough to handle either case, but I'm hoping I don't have to.

Thanks to anyone who can answer this question!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦里人 2024-10-01 06:39:58

仔细阅读 USB 规范:

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

  • 已传输完全在设置阶段指定的数据量
  • 传输有效负载大小小于 wMaxPacketSize 的数据包或传输零长度数据包

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

如果wLength>传输大小,并且 (传输大小 % ep0 size) == 0 答案是 YES,您需要 ZLP。

Read carefully USB specification:

The Data stage of a control transfer from an endpoint to the host is complete when the endpoint does one of
the following:

  • Has transferred exactly the amount of data specified during the Setup stage
  • Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet

So, in your case, when wLength == transfer size, answer is NO, you don't need ZLP.

In case wLength > transfer size, and (transfer size % ep0 size) == 0 answer is YES, you need ZLP.

惯饮孤独 2024-10-01 06:39:58

一般来说,USB 使用小于最大长度的数据包来划分传输结束。因此,如果传输是最大数据包长度的整数倍,则使用 ZLP 进行划分。

您在散装管道中经常看到这种情况。例如,如果您有 4096 字节的传输,它将被分解为整数个最大长度数据包加上一个零长度数据包。如果软件驱动程序设置了足够大的接收缓冲区,则当 ZLP 发生时,更高级别的软件会立即接收整个传输。

控制传输是一种特殊情况,因为它们具有 wLength 字段,因此 ZLP 并不是严格必要的。

但我强烈建议软件对两者都灵活,因为您可能会看到不同 USB 主机芯片或低级 HCD 驱动程序的变化。

In general, USB uses a less-than-max-length packet to demarcate an end-of-transfer. So in the case of a transfer which is an integer multiple of max-packet-length, a ZLP is used for demarcation.

You see this in bulk pipes a lot. For example, if you have a 4096 byte transfer, that will be broken down into an integer number of max-length packets plus one zero-length-packet. If the SW driver has a big enough receive buffer set up, higher-level SW receives the entire transfer at once, when the ZLP occurs.

Control transfers are a special case because they have the wLength field, so ZLP isn't strictly necessary.

But I'd strongly suggest SW be flexible to both, as you may see variations with different USB host silicon or low-level HCD drivers.

寄风 2024-10-01 06:39:58

我想扩展 MBR 的答案。 USB 规范 2.0 在第 5.5.3 节中表示:

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

  • 已准确传输设置阶段指定的数据量
  • 传输负载大小小于 wMaxPacketSize 的数据包或传输零长度数据包

当数据阶段完成时,主机控制器前进到
状态阶段而不是继续另一个数据事务。
如果主机控制器没有进入状态阶段
数据阶段完成,端点停止管道,如中所述
第 5.3.2 节。
如果从
端点,控制传输的 IRP 将是
中止/退休。

我强调了该引用中的其中一个句子,因为它似乎具体说明了设备应该做什么:如果主机在完成后尝试继续数据阶段,则它应该“停止”管道,并且如果全部完成,则完成请求的数据已传输(即传输的字节数大于或等于wLength)。我认为停止是指发送一个 STALL 数据包。

换句话说,在这种情况下,设备不需要零长度数据包,事实上 USB 规范规定它不应该提供零长度数据包。

I would like to expand on MBR's answer. The USB specification 2.0, in section 5.5.3, says:

The Data stage of a control transfer from an endpoint to the host is
complete when the endpoint does one of the following:

  • Has transferred exactly the amount of data specified during the Setup stage
  • Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet

When a Data stage is complete, the Host Controller advances to the
Status stage instead of continuing on with another data transaction.
If the Host Controller does not advance to the Status stage when the
Data stage is complete, the endpoint halts the pipe as was outlined in
Section 5.3.2.
If a larger-than-expected data payload is received from
the endpoint, the IRP for the control transfer will be
aborted/retired.

I added emphasis to one of the sentences in that quote because it seems to specifically say what the device should do: it should "halt" the pipe if the host tries to continue the data phase after it was done, and it is done if all the requested data has been transmitted (i.e. the number of bytes transferred is greater than or equal to wLength). I think halting refers to sending a STALL packet.

In other words, the device does not need a zero-length packet in this situation and in fact the USB specification says it should not provide one.

爱冒险 2024-10-01 06:39:58

你不必这样做。 (*)

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

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

You don't have to. (*)

The whole point of wLength is to tell the host the maximum number of bytes it should attempt to read (but it might read less !)

(*) I have seen devices that crash when IN/OUT requests were made at incorrect time during control transfers (when debugging our host solution). So any host doing what you are worried about, would of killed those devices and is hopefully not in the market.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文