请问原子的F4的U盘读写程序,综合例程与单独例程为啥不同?

2019-08-20 15:23发布

我用F107的USB OTG做U盘HOST,并且加上文件系统FATFS,运行正常,能够读写U盘文件了。但是,加上UCOS后,总是死机,仿真跟踪,发现总是死在DRESULT disk_read ( BYTE drv,BYTE *buff,DWORD sector,BYTE count ) 这个函数里,此函数里读U盘状态总是处于忙状态,死循环了。我也仿照原子的综合例程,加入了临界保护和8字节对齐,但还是不行。
于是我打开了原子的F4的实验53和综合例程,对比了一下有无UCOS时的代码,如下: 
首先是实验53的disk_read子程序,原子改名为如下:
u8 USBH_UDISK_Read(u8* buf,u32 sector,u32 cnt)
{
 u8 res=1;
 if(HCD_IsDeviceConnected(&USB_OTG_Core)&&AppState==USH_USR_FS_TEST)//??????????,????APP????×???
 {       
  do
  {
   res=USBH_MSC_Read10(&USB_OTG_Core,buf,sector,512*cnt);
   USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);       
   if(!HCD_IsDeviceConnected(&USB_OTG_Core))
   {
    res=1;//?????í?ó
    break;
   };  
  }while(res==USBH_MSC_BUSY);
 }else res=1;   
 if(res==USBH_MSC_OK)res=0; 
 return res;
}
然后是综合例程的代码:
u8 USBH_UDISK_Read(u8* buf,u32 sector,u32 cnt)
{
 u8 res=1;
 u32 retry=0;
 if(HCD_IsDeviceConnected(&USB_OTG_Core_dev)&&AppState==USH_USR_FS_TEST)//??????????,????APP????×???
 {       
  do
  {
   res=USBH_MSC_Read10(&USB_OTG_Core_dev,buf,sector,512*cnt);
   USBH_MSC_HandleBOTXfer(&USB_OTG_Core_dev ,&USB_Host);       
   if(!HCD_IsDeviceConnected(&USB_OTG_Core_dev))
   {
    res=1;//?????í?ó
    break;
   };
   retry++;
  }while(res==USBH_MSC_BUSY&&retry<0X7FFFFFF);
  if(retry==0X7FFFFFF)res=1;
 }else res=1;   
 if(res==USBH_MSC_OK)res=0; 
 return res;
}

比较一下,有两点不同。一是USB句柄名称由USB_OTG_Core改为USB_OTG_Core_dev,这个估计不是问题,只是个名字;二是原子在综合例程里对检测U盘状态的次数做了限制,使用了局部变量retry。而我恰巧就死在这里,总是检测U盘忙,也就是res==USBH_MSC_BUSY总是为真,因此就死循环了。那么原子为啥在综合例程里加上retry<0X7FFFFFF以便对循环次数做限制呢?  我试验了一下,在我的程序里也对循环次数做限制了,retry<3,则就不死循环了,但也无法读U盘内容了,直接跳过去了。
我想问的是,为啥裸奔都挺好的,完全正常,而加上UCOS后,虽然U盘枚举都正常,并且也能初始化文件系统了,if ( f_mount( 0, &fatfs ) != FR_OK ) 执行很正常,而且还读到了U盘容量,但只要一开始读U盘里的文件内容,使用到了DRESULT disk_read函数(原子改名为USBH_UDISK_Read),则立刻死在里面了。莫名其妙啊!弄了好几天了,请大侠帮忙,谢谢啦!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
15条回答
清风明月逍遥云
1楼-- · 2019-08-20 19:02
跟USB中断是否有关系?    USB的中断只有一个,我也加上UCOS的进入退出中断的函数啦。而且若中断有问题,则USB枚举和读U盘容量都不会成功吧,而我都成功了,只是在读U盘内容时死循环了。
正点原子
2楼-- · 2019-08-20 19:38
防止死机用的。。。
solo
3楼-- · 2019-08-20 21:23
STM的USB是用状态机制实现的,所以一定要让底层(USB事务处理函数)处理完数据再操作应用层(文件系统),要不然丢数据死机是很正常的。
solo
4楼-- · 2019-08-21 01:39
回复【2楼】清风明月逍遥云:
---------------------------------
USb中断作用在检测USB设备,枚举数据传输都不在中断里。换句话说STM的USB通讯的实现本来就是裸奔的,就算加上操作系统,对于USB这部分还是单机的。。。
void
5楼-- · 2019-08-21 06:48
 精彩回答 2  元偷偷看……
solo
6楼-- · 2019-08-21 11:54
回复【6楼】void:
---------------------------------
没说不能。例如,我现在的读写U盘的工作模式:USB处理是一个线程,数据操作是一个线程,两个线程通过队列通讯。而所有的文件操作都放在ST的“USBH_USR_MSC_Application”函数里,也就是说外边是没有文件操作的,数据只通过队列才能传进来。USB处理线程里是检测和处理,但是从头到尾不管是检测还是处理调的都是一个函数“USBH_Process”。如果你想文件操作一次导出一个大文件,而只执行一次“USBH_Process”的话,结果丢数。我是每512字节执行一次“USBH_Process”,写成线程时为了方便实现后台USB也能工作。不知道有没有更好的做法,如果USB部分能完全嵌入到操作系统的话谁管啥时候要执行一下“USBH_Process”。

一周热门 更多>