打印

关于USB发送0长度数据包的问题

[复制链接]
8632|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kokoromi|  楼主 | 2013-5-6 19:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 kokoromi 于 2013-5-6 19:59 编辑

之前看 《圈圈教你玩USB》这本书,里面有段程序没看明白,大概是这样:
....

if(wLength > SendLength)
{
  if(SendLength % DeviceDescriptor[7] == 0) //并且刚好是整数个数据包时
    NeedZeroPacket = 1;//需要返回0长度数据包
}
else
{
  SendLength = wLength;
}
//将数据通过EP0返回
UsbEp0SendData();

....


我现在很不明白的是,如果请求的长度(wLength)大于实际返回的数据长度(SendLength),并且返回的数据包长度是端点最大包长的整数倍时,需要返回0长度数据包,否则不返回0长度数据包,这个是什么原因?没明白。

也就是说,在端点最大包长为8字节的前提下,如果USB请求里要求要返回18字节数据,但是我要返回的数据只有12字节,那么只返回12字节的数据即可,但是如果我要返回的数据有16字节,或者8字节,那么就要在返回这些字节后再返回一个0长度数据包,这是为什么?

后来我在TI的官网上下载了MSP430F5529的USB例程,里面的程序也是这样,是USB协议规定的吗?为什么在请求长度大于实际返回长度并且实际返回长度还是端点最大包长整数倍时,就要额外返回0长度包?求真相~~~

相关帖子

沙发
john_lee| | 2013-5-6 20:48 | 只看该作者
这个问题很容易理解的,你从 host 的角度来看,要求了 18 字节,这是在 setup 阶段,而实际的数据传输在 data 阶段,我们来分析一下 data 阶段:
transcation 1、host 发出 in token,device 收到后发出 8 字节数据(第 0 ~ 7 字节)。
transcation 2、host 收到数据后,继续发出 in token,device 收到后发出 8 字节数据(第 8 ~ 15 字节)。
到此,device 已把 16 字节数据全部发送完毕,但 host 要求的是 18 字节,而收到了 16 字节,显然 host 认为数据没有传输完,于是:
transcation 3、host 继续发出 in token,device 收到 in token,好,我们在此停住。
你认为应该现在 device 应该如何响应?忽略这个 in token?好,先这样假设吧,那么 host 会重试数次,然后报错。这样显然不行。
如何通知 host 数据已经完成呢?为此,USB 协议规定,device 必须发一个 zero length packet,host 收到后,就会知道没有更多的数据了。

使用特权

评论回复
板凳
kokoromi|  楼主 | 2013-5-6 20:52 | 只看该作者
john_lee 发表于 2013-5-6 20:48
这个问题很容易理解的,你从 host 的角度来看,要求了 18 字节,这是在 setup 阶段,而实际的数据传输在 da ...

原来如此! 如果这样的话,那是不是如果收到一个不足端点最大包长的数据包也会认为数据过程结束?

使用特权

评论回复
地板
john_lee| | 2013-5-6 21:00 | 只看该作者
是的。
还有,如果 device 发出的数据长度等于 host 请求的数据长度,host 在收到了全部的数据后,即使数据长度是 max packet length 的整数倍,host 也不会再发出 in token,,device 也就不用发 zero length packet 了。

使用特权

评论回复
5
kokoromi|  楼主 | 2013-5-6 21:12 | 只看该作者
john_lee 发表于 2013-5-6 21:00
是的。
还有,如果 device 发出的数据长度等于 host 请求的数据长度,host 在收到了全部的数据后,即使数据 ...

非常感谢!彻底明白了~

PS:USB协议真是太庞大了,中文的资料也不多,尤其是各种设备类的内容,还有HID的报告描述符..... 平时用USB用的这么多,真研究这个了,发现太难了...

使用特权

评论回复
6
zook0k| | 2014-11-1 20:38 | 只看该作者
:)

使用特权

评论回复
7
McuPlayer| | 2014-11-11 17:59 | 只看该作者
这个问题,当年也困扰我,那时用汇编写usb而且是8bit的台系MCU,调试工具比较难用
这个零长度的数据包,可以理解为防呆,正常不会出现的,但要防止HOST万一发神经,要完了数据,还来要(IN Token)的情况

使用特权

评论回复
8
zbc888| | 2014-11-12 16:39 | 只看该作者
厉害 赞一个

使用特权

评论回复
9
zzkjliu| | 2015-11-24 09:14 | 只看该作者
本帖最后由 zzkjliu 于 2015-11-24 10:40 编辑

对于通过USB口发送数据端的程序,通常这样处理(android的ADB就是这样的):
/// Mask for determining when to use zero length packets
  unsigned zero_mask=最大包尺寸-1;
If (zero_mask && (发数据长度 & zero_mask))==0)
       发0长度包


PC usb host to PC usb host通讯API:
搜“About USB DataLink Cable API”

提供各种MCU的各种USB驱动,以及MCU和PC通讯API:扣扣:1561724180
tel:13803113171

使用特权

评论回复
10
liumuxiao| | 2017-9-11 14:58 | 只看该作者
john_lee 发表于 2013-5-6 20:48
这个问题很容易理解的,你从 host 的角度来看,要求了 18 字节,这是在 setup 阶段,而实际的数据传输在 da ...

您好,我想问您个问题,如果主机需要18个字节的设备描述符,而设备只有15个字节的设备描述符,而端点包长8字节,15%8不为0,不发0长度状态包,但是15个字节不够主机需要的18个字节,主机也就一直会in token,但是设备又不发0长度的状态包,那么这怎么办?

使用特权

评论回复
11
liumuxiao| | 2017-9-11 15:23 | 只看该作者
john_lee 发表于 2013-5-6 20:48
这个问题很容易理解的,你从 host 的角度来看,要求了 18 字节,这是在 setup 阶段,而实际的数据传输在 da ...

难道说:host当发现设备返回的描述符不够一个端点包长的时候,就判断为数据已经接收完?

使用特权

评论回复
12
john_lee| | 2017-9-12 19:17 | 只看该作者
liumuxiao 发表于 2017-9-11 15:23
难道说:host当发现设备返回的描述符不够一个端点包长的时候,就判断为数据已经接收完? ...

是的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

344

帖子

3

粉丝