.. _usb_ext:

USB 知识点拓展
===========================

什么是分包
-------------

由于 USB 协议中规定了每个包的最大长度，所以当我们发送的数据长度超过了最大包长度时，就需要分包发送，这就是分包。比如 ep mps 为 64，数据长度为 129，则 USB 会按照 64 + 64 + 1 的形式传输。
而对于 USB IP 来说，分包分为软件分包和硬件分包，软件分包就是用户代码自行分包，这种 ip 一般都使用 FIFO 来进行，因为 FIFO 深度是有限的；第二种
则是使用硬件分包，这种 USB IP 一般带 DMA 或者描述符 DMA 功能，那么这种 IP 的效率无疑是最高的，cherryusb 中充分利用了这点，使得 USB 速度能够达到最高。

对于软件分包来说，一次发送的长度即使是 16K， **内部也是通过软件分包的，在这种情况下，发送长度的多少不会对速度有任何提升**。
对于硬件分包来说，发送的长度会影响速度，因为硬件分包是通过 DMA 来进行的， **一次发送的长度越大，DMA 的效率就越高，速度也就越快**。（当然，其他协议栈虽然使用了 dma，但是部分代码实现还是按照一个包进行，等于没用，这也是速度低的一个原因）

什么是短包
----------------

在上面我们讲了分包之后，短包就是分包的最后一个包（并且长度小于 EP MPS）.比如发送 129 字节的数据，那么 USB 会按照 64 + 64 + 1 的形式传输，最后一个包是1个字节，这1个字节就是短包。

什么是 ZLP
-------------

ZLP，顾名思义，零长度数据包，也就是数据长度为0 的短包。是 USB 设备在数据传输结束时，如果数据长度正好是最大包长度的整数倍，那么就需要发送一个 ZLP 数据包，用来告诉对方数据传输结束。

.. caution:: ZLP 功能仅限于 CONTROL 和 BULK 传输

什么时候算中断完成
--------------------

从机接收：接收的长度与设置的长度相等；接收的最后一个包为短包。
从机发送：发送的长度与设置的长度相等，如果发送的长度是 EP MPS 的整数倍， **通常** 需要再发送一个 ZLP（仅限 control 和 bulk 传输）。

.. note:: 对于从机接收，并且是 bulk 传输，接收长度通常设计为 EP MPS，以下三种情况可以修改为多个 EP MPS: 固定长度；自定义协议并携带长度（例如 MSC）; 主机手动发送 ZLP 或者短包（例如 RNDIS）

.. note:: 对于从机发送，并且是 bulk 传输，发送长度没有限制，但是如果是 EP MPS 整数倍，通常需要发送 ZLP。自定义协议则不需要发送 ZLP，例如 MSC。

主机接收：同从机接收
主机发送：发送的长度与设置的长度相等
