打印
[应用相关]

USB发送数据时出现迟滞现象

[复制链接]
25834|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
问题描述

客户反馈,使用STM32F446的高速USB外设,即USB_OTG_HS外设,且使用内置全速PHY。客户的产品USB用做device,自定义HID类,当连接带UOS操作系统的HOST时,会发现当前数据并没有成功发送,但是会发送上一次的数据,即发送数据出现”迟滞”现象。但在Windows下却没有出现此类问题。另外,客户同时还使用了STM32F446上的USB_OTG_FS外设,且此外设做同样的事一切正常,目前此问题只出现在USB_OTG_HS外设上。

问题查找

刚开始猜测是长度问题,即发送最大包长需要再发送一次空包。但客户反馈他们的发送长度为62个字节。于是去客户现场使用USB协议分析仪采数分析,发现一切通信正常。

通过查看客户演示重现问题的过程,发现在正常时是一切OK的,只在进行USB拔插时才发送问题。应用程序不断发送数据的过程中拔掉USB线,然后再次插上,在此过程中应用程序一直尝试发送数据。当USB线重新连接上且重新枚举成功后,“迟滞”现象则重现了,即每次应用程序调用发送接口实现发送的是上一次尝试发送的内容。

调试客户的程序,发现当USB线拔掉后,应用程序还会往USB IP对应的发送FIFO内写入数据,这其实是不对的。按理USB线拔掉后USB的状态应该恢复到默认状态,

即pdev->dev_state=USBD_STATE_DEFAULT. 但实际上,通过调试发现此状态在USB线拔掉后是suspend状态。

那么为什么会是这样的呢?

于是立即想到Vbus sensing功能。马上与客户硬件工程师核对,原来客户产品的USB_OTG_HS的Vbus_sensing脚是悬空的,并没有连接Vbus,但是客户的USB_OTG_FS外设却又是连接了。于是客户的产品两个USB口,同样的工作,一个USB口 正常,另一个USB口却会出现问题。

问题分析

差异找到了,接下来就是分析由此如何造成问题的。

由于USB_OTG_HS并没有真正实现Vbus sensing功能(因为没有硬件连接),于是当USB线断开时,应用程序并不能准确地检测到断开事件(Disconnected),只会出现suspend,应用程序是无法直接的区分真正的suspend和USB线断开连接的。当应用程序有数据需要通过USB口发送时,如果当前是suspend状态,那么它会首先唤醒USB总线然后再发送数据:
Figure1

而这样发送远程唤醒信号时,device本身会产生一个resume中断,于是在resume中断回调函数内:
Figure 2

如上所示,程序会将dev_state错误地恢复到上一次状态,即正常状态USBD_STATE_CONFIGURED, 如此一来,程序就错误地往USB IP的内的发送FIFO写入数据了,即使此时由于USB线已经断开而导致无法真正发送成功,但USB IP的内置发送FIFO此时是有了数据的。

通过调试,查看OTG_DTXFSTS1寄存器相应端点1对应的发送FIFO的剩余空间可知,这个时候的发送FIFO的确实有数据的。接下来是USB线插上重新枚举,那么为什么USB重新枚举后还会再现问题呢?通过设置断点发现,在USB成功重新枚举过后,通过OTG_DTXFSTS1寄存器指示,发送FIFO内容并没有清空,于是在接下来发送数据时,永远都是实际上发送的是上一次写入到FIFO中的数据。

问题已经找到

问题解决
▼于是解决方法就很容易找到了▼

在USB重新枚举过后在合适的地方将端点1对应的发送FIFO清空一下即可。
Figure 3

问题总结

在客户的这个案子中,由于USB_OTG_FS连接了VBUS SENSING脚,当USB线拔掉后,会产生正确的disconnect中断,USB device的状态也会正确地切换到default状态,从而过滤掉应用程序想要发送的数据,因此并不会出现类似问题,因此,在客户的产品设计中,建议硬件千万不要忘了连接vbus引脚,即使在想省IO引脚的情况下,这样容易造成对软件的开发诸多不便.

在USB的状态处于非configured状态时,最好不要往发送FIFO写入数据,应用程序应该想办法将这些数据过滤掉。

使用特权

评论回复
沙发
AIsignel| | 2022-10-17 17:57 | 只看该作者
这解决问题的思路非常清晰!一看就是大佬!

使用特权

评论回复
板凳
shizaigaole| | 2022-10-17 18:34 | 只看该作者
有价值帖子!

使用特权

评论回复
地板
icecut| | 2022-10-17 19:05 | 只看该作者
这是嵌入式工程师的通病. 搞什么都是试一下. 出问题以后就遍地找原因.

使用特权

评论回复
评论
liaojihua2010 2022-10-18 09:23 回复TA
凡事皆有两面性,虽然是错误的设计,但分析解决这个错误设计带来的异常还是有价值的。 
5
asmine| | 2022-10-17 20:47 | 只看该作者
说白了,不是硬件设计没按标准进行么

使用特权

评论回复
6
SPR——| | 2022-10-18 09:11 | 只看该作者
强!!

使用特权

评论回复
7
szt1993| | 2022-10-19 21:38 | 只看该作者
确实这种问题会有发生,还是芯片使用不太了解导致的,硬件工程师设计必须了解外设的使用方法

使用特权

评论回复
8
51xlf| | 2022-10-23 21:13 | 只看该作者
电源供电不足造成传输数据丢失      

使用特权

评论回复
9
sdlls| | 2022-10-23 21:27 | 只看该作者
当前数据并没有成功发送,但是会发送上一次的数据

使用特权

评论回复
10
mollylawrence| | 2022-10-24 17:12 | 只看该作者
USB配置描述符中有关于接收中断和发送中断时间间隔参数,默认的好像是0x20,就是32ms,可以将此值改为0x01。速度会快很多。

使用特权

评论回复
11
51xlf| | 2022-10-24 17:42 | 只看该作者
上位机发送的数据本身就很慢,也会造成USB的速度慢。

使用特权

评论回复
12
jtracy3| | 2022-10-24 18:28 | 只看该作者
猜测是USB发送数据长度问题的。            

使用特权

评论回复
13
modesty3jonah| | 2022-10-24 19:30 | 只看该作者
usb设备接口是usb1.0还是1.1或2.0,2.0最快

使用特权

评论回复
14
minzisc| | 2022-10-24 20:50 | 只看该作者
可考虑到STM32的USB在发送大于最大包长

使用特权

评论回复
15
jonas222| | 2022-10-24 22:02 | 只看该作者
中断频率很高(10ms以内),就会影响USB的速度。         

使用特权

评论回复
16
stormwind123|  楼主 | 2022-10-25 09:40 | 只看该作者
AIsignel 发表于 2022-10-17 17:57
这解决问题的思路非常清晰!一看就是大佬!

哈哈哈哈,多谢大佬赞赏

使用特权

评论回复
17
stormwind123|  楼主 | 2022-10-25 09:41 | 只看该作者

使用特权

评论回复
18
abotomson| | 2022-10-25 18:44 | 只看该作者
可是假如跑的是HID之类慢速设备的协议,那么速度就没有那么快了  

使用特权

评论回复
19
sesefadou| | 2022-10-25 19:40 | 只看该作者
应该是系统问题,USB驱动不稳定。

使用特权

评论回复
20
MessageRing| | 2022-11-4 18:40 | 只看该作者
是不是硬件设计的问题啊?

使用特权

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

本版积分规则

297

主题

1206

帖子

1

粉丝