本帖最后由 tanmingjin 于 2020-7-8 18:06 编辑
问题描述:将ST103的HAL USB程序库移植到AT32F403上运行,发现有时候不能正常识别USB设备。
分析的结果:在枚举阶段USB 的IN和OUT事件没有及时处理,程序中有其它中断,导致USB的IN和OUT事件同时来,对于本来要先处理IN再处理OUT的情况,此时会变成先处理OUT,在处理IN,后处理IN的时候会将端点0的接收缓冲区配置为0,导致后续不能正常通信。
问题解决方法:在设置端点0接收缓冲区时加上判断,如果为0,就不需要配置,修改之后USB枚举正常
如下是分析过程: 将ST103的HAL USB程序库移植到AT32F403上运行,发现有时候不能正常识别USB设备。通过抓包来看,发现是有一个主机发的SETUP没有正常回复。 发现SETUP没有正常回复之后,首先查看了端点0的寄存器状态,端点状态都是正常的。然后查看端点0的接收缓冲区和发送缓冲区的配置,发现接收缓冲区大小被改成了0,也就是此时端点0不能接收数据了。
如下是端点0缓冲区此时配置的值:
文档上的描述;
此时分析一下异常SETUP之前的USB 数据,有一个IN和OUT的传输。猜测会不会是此处IN和OUT的事件处理有问题,因为程序里面还有其它中断,可能会导致IN和OUT事件不能及时处理。 查看文档发现,此USB对应端点0的IN事件和OUT时间是通过一个位来控制,表示传输向,如果IN(TX)和OUT(RX)同时来时,应该会先处理OUT在处理IN,这样如果原本的事件的顺序是IN,OUT会不会就有问题了。
HAL USB这部分的代码处理过程,果然和前面分析一样,IN和OUT同时来时USB_ISTR_DIR等于1,会先处理OUT,再处理IN:
IN事件的处理,发现代码里面会有两个地方会将端点0的接收缓冲区设置为0,此处将端点0的接收缓冲区设置为0之后,导致后续不能正常通信。
为了保证端点0接收缓冲区不被设置为0,在端点0设置接收长度的地方加上判断len!=0
|