谢谢大家的回复,不好意思,有些没说清楚。
程序会死在usbhostenum.c中的USBHCDPipeWrite或USBHCDPipeRead函数如下位置
// Wait for a status change.
while(g_sUSBHCD.USBOUTPipes[ulPipeIdx].eState == PIPE_WRITING)
{
}
while(g_sUSBHCD.USBINPipes[ulPipeIdx].eState == PIPE_READING)
{
}
我的拔插速度大概在每秒3~4次左右。U盘用的是Kingstone的8G,联想的也试过。都是大厂的。山寨U盘死得更快。
库用的是7243,切换到最新的8555测试,代码不变只用最新的库没想到所有的U盘都不认识了。
下面是硬件连接,DM、DP、USB_EPEN、USB_PFLT接MCU。开发工具是MDK4.22。
每秒3-4次插拔确实有些快了,M3毕竟是MCU,处理USB协议栈时候需要些时间。个人分析了下,有可能是之前拔出U盘时,这个循环还没退出来,又被中断,g_sUSBHCD.USBOUTPipes[ulPipeIdx].eState状态被改回,或者g_ulUSBHIntEvents状态又被冲掉了。
楼主可以试着在if(g_ulUSBHIntEvents & INT_EVENT_DISCONNECT)把USB中断关了,在while(g_sUSBHCD.USBOUTPipes[ulPipeIdx].eState == PIPE_WRITING)循环中再打开。看看是不是g_sUSBHCD.USBOUTPipes[ulPipeIdx].eState状态被改了。
如果不是可能就要更深入地研究下USB库了。。。
确实,源代码中就是触发DMA传送再中断刷新eState状态,快速插拔时没处理完成U盘就不存在了,eState一直保持在PIPE_WRITING或PIPE_READING状态造成死机。多次的快速插拔显示是不允许的,但情况是单次的快速插拔也会死,没办法保证别人不这么做呀。
if(g_ulUSBHIntEvents & INT_EVENT_DISCONNECT)中关中断的方式我还没有试过,明天再试试。
类似于USB拔插,程序中控制USB供电也会带来同样的问题(用户进入某个面页操作启动USB供电,退出时撤掉USB供电),当多次快速的操作进入该页面时CPU死机重启。后面在软件中增加上下电延时才解决该问题。但拔插的隐患还是无法消除。
看来USB库还是要改进呀,希望新的版本能解决这些问题才好。
这几天一直在尝试解决这个问题,现在已经完全解决了,高速插拔已经完全没有问题了,山寨也不会死了。
结论就是7243的库稳定性不行,必须使用最新的8555。
项目中的代码是按7243的例程改写的,7243的例程在处理USBHCDEvents事件时与8555有差异造成所有U盘无法识别。
非常感谢大家的热情回复与关注!!!