ZLP的判断逻辑
2026-08-13
本文链接为:http://www.usbzh.com/article/detail-1789.html ,欢迎转载,转载请附上本文链接。
ZLP 条件详解
if ((ep->total_data_len % ep->maxpacket == 0) && // 条件①
(ep->total_data_len >= ep->maxpacket) && // 条件②
(ep->total_data_len < ep->ctl_data_len)) // 条件③
先理解三个变量的含义:
| 变量 | 含义 | 来源 |
|---|---|---|
total_data_len |
设备实际要发送的数据长度 | 比如描述符的真实长度 |
ctl_data_len |
主机请求的数据长度 | SETUP 包中的 wLength 字段 |
maxpacket |
EP0 最大包长 | FS=64, HS=64 |
三个条件逐一分析
条件① total_data_len % maxpacket == 0
实际数据长度刚好是 maxpacket 的整数倍
这意味着所有包都是满包(64字节),没有”短包”来自然终止传输。
条件② total_data_len >= maxpacket
实际数据至少有 1 个满包
防御性条件,如果数据不足一个包,本身就是短包,不需要 ZLP。
条件③ total_data_len < ctl_data_len
实际数据少于主机请求的数量
这是最关键的条件。 主机期待的数据比设备实际有的多,设备需要”提前终止”传输。
为什么需要 ZLP?
USB 规范规定:控制传输的 DATA IN 阶段,主机靠”短包”或”收到恰好 wLength 字节”来判断传输结束。
举一个具体例子:
主机请求: 获取设备描述符,wLength = 255 字节
设备实际: 只有 18 字节的描述符
maxpacket: 64 字节
| 场景 | 实际数据 | 会发生什么 |
|---|---|---|
| 普通情况(18字节) | 不是 64 的倍数 | 最后一包 18 字节(短包),主机自然知道结束了 |
| ZLP 情况(128字节) | 128 = 2×64,刚好是倍数 | 发完 2 个满包后,主机不知道已经结束了,还在等! |
设备实际有 128 字节,主机请求了 255 字节:
包1: [64字节] → 主机收到,满包,继续等
包2: [64字节] → 主机收到,满包,继续等
包3: [0字节] ← ZLP!主机收到 0 长度包,明白了:设备发完了
一张图总结 ZLP 的判断逻辑
实际数据(total_data_len) < 主机请求(ctl_data_len)?
│
┌──────────┴──────────┐
│ 是 │ 否
▼ ▼
total_data_len 是 主机知道确切字节数
maxpacket 整数倍? 收到 wLength 字节就停
│ → 不需要 ZLP
┌────────┴────────┐
│ 是 │ 否
▼ ▼
需要 ZLP 终止! 最后一包是短包
否则主机永远等 自然终止
→ 不需要 ZLP
一句话:ZLP 只在”设备实际数据少于主机请求,且实际数据碰巧是满包的整数倍”时才需要。 它就是一个”句号”,告诉主机:我发完了,别等了。
本文链接为:http://www.usbzh.com/article/detail-1789.html ,欢迎转载,转载请附上本文链接。
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936 USB技术交流3:1031974172
STM32-USB





