完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近调了几个USB方面的问题,都是当传输数据长度在64的整数倍时,就出现了错误,因为STM32全速USB端点的最大长度为64Byte,STM32单片机的USB驱动在接收数据时,判断接收到的数据小于ENDSIZE时,才判断这次传输结束。 而当要传输的数据刚好是64的整数倍时,就有问题出现了,最后一包数据数据还是64,这时驱动就不会判断本次传输结束。如果当收到数据时,应该有两种情况来判断传输结束,一个是收到小于EPSIZE的数据,一个是超时。这样就不会出现这种情况。
既然STM32驱动会有这样的错误,其它USB设备当然也会犯这个错误,在我调试ME909的时候,果然当发送TCP的大小为64的整数倍时,TCP就发不出去了,由于TCP发送必须要求有ACK才会再发送下一包TCP数据,而ME909收到的是64的整数倍的数据,其驱动可能与STM32一样,认为本次传输没有完成,于是就等待下1包数据,TCP传输在没有收到对方的ACK包时,会一直等待直到超时重新发送这包TCP数据,但是重新发送的TCP数据仍是64的整数倍,结果ME909还是认为没有收到完整的数据,由于是单片机系统,除了这个TCP应用,系统不会再发送其它数据包。这样就陷入了死循环,直到死机。 在上面的过程中,如果你主动去PING一个公网IP,由于PING数据包刚好不是64的整数倍,这样ME909就被激活了,包括之前的数据一道发了出去,但是后续如果再遇到64整数倍的TCP数据包,就又会出现上面的死循环。 我的解决办法是,不管三七二十一,如果检测到一次传输的大小为64的整数倍时,会在驱动中自动的增加1个字节,正由于这多余的1个字节,就会把ME909激活。测试证明可以使用。 由于modem传输的数据格式是固定的“7E 长度 数据 CRC 7E”,中间多发一个字节也不会有任何影响。 后来才知道,在Linux驱动下,也有这个问题,好像叫做0包检测,看来不光是stm32下的问题!!!哈哈 0包检测无论针对USB主设备,还是USB从设备,都是要考虑的,USB主控制器要发送ENDSIZE整倍数数据时,一定要在最后增加一个0包数据, 如果是USB从设备要想向主控制器发送ENDSIZE整倍数数据时,也要把在最后增加一个0数据包,无论是主设备还是从设备,只要收到小于ENDSIZE的数据包,或者有效数据长度为0的数据包,都会认为此次传输结束。这就是0包检测的本质!! |
|
|
|
只有小组成员才能发言,加入小组>>
3308 浏览 9 评论
2988 浏览 16 评论
3490 浏览 1 评论
9049 浏览 16 评论
4083 浏览 18 评论
1167浏览 3评论
601浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
592浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2329浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1892浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 12:17 , Processed in 1.355060 second(s), Total 80, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号