请教一个STMCUBE CDC类 USB端点异常停止的问题

2019-12-10 18:33发布

本帖最后由 jjj 于 2018-11-4 22:24 编辑

   我有一个项目在STM32F437  USB HOST上使用了CDC类,代码大部分都是 CUBE自动生成的,发现了个问题,
static void CDC_ProcessReception(USBH_HandleTypeDef *phost)
{
  CDC_HandleTypeDef *CDC_Handle =  (CDC_HandleTypeDef*) phost->pActiveClass->pData;
  USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
  uint16_t length;

  switch(CDC_Handle->data_rx_state)
  {
  case CDC_RECEIVE_DATA:
    USBH_BulkReceiveData (phost,
                          CDC_Handle->pRxData,
                          CDC_Handle->DataItf.InEpSize,
                          CDC_Handle->DataItf.InPipe);
   
    CDC_Handle->data_rx_state = CDC_RECEIVE_DATA_WAIT;
    break;
  case CDC_RECEIVE_DATA_WAIT:   
    URB_Status = USBH_LL_GetURBState(phost, CDC_Handle->DataItf.InPipe);     
    /*Check the status done for reception*/
    if(URB_Status == USBH_URB_DONE )
    {  
      length = USBH_LL_GetLastXferSize(phost, CDC_Handle->DataItf.InPipe);
      
      //if(((CDC_Handle->RxDataLength - length) > 0) && (length > CDC_Handle->DataItf.InEpSize))
          if(((CDC_Handle->RxDataLength - length) > 0) && (length == CDC_Handle->DataItf.InEpSize))       

      {
        CDC_Handle->RxDataLength -= length ;
        CDC_Handle->pRxData += length;
        CDC_Handle->data_rx_state = CDC_RECEIVE_DATA;
      }
      else
      {
        CDC_Handle->data_rx_state = CDC_IDLE;
        USBH_CDC_ReceiveCallback(phost);
      }      
    }
    break;   
  default:
    break;
  }
上面标颜 {MOD}的位置,我把大于号改成“==”等于号了,因为我调试过程中,这个地方不可能大于,也就是说上次接收的数据大小不可以大于端点的SIZE,如果是大于的话,永远也不成立,所以我改成了“==”,调试通过程序正常运行,且提高了效率。
由于我的数据量非常大,改过之后USB端点非常容易异常停止,在OTG_HS_HCINT 的CHH通道停止经常置1,然后就收不到此端点的任何数据了。
  我开始以为是CDC_ProcessTransmission, CDC_ProcessReception这两个函数冲突,我就加了个判断,只有在发送空闲时才启动接收,如下:
static void CDC_ProcessReception(USBH_HandleTypeDef *phost)
{
  CDC_HandleTypeDef *CDC_Handle =  (CDC_HandleTypeDef*) phost->pActiveClass->pData;
  USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
  uint16_t length;

  switch(CDC_Handle->data_rx_state)
  {
   
  case CDC_RECEIVE_DATA:
        if(CDC_Handle->data_tx_state == CDC_IDLE)       
          {
                USBH_BulkReceiveData (phost,
                                                          CDC_Handle->pRxData,
                                                          CDC_Handle->DataItf.InEpSize,
                                                          CDC_Handle->DataItf.InPipe);

               
                CDC_Handle->data_rx_state = CDC_RECEIVE_DATA_WAIT;
        }
    break;
.....}
经过上面修改了,大大提高了稳定性,能做到连续工作几小时,不出错,但长时间运行后,还是有问题,还会出现CHH通道停止,
这个问题已经困扰了很久了……
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
jjj
1楼-- · 2019-12-10 23:53
有人用过CDC这个类吗?
wye11083
2楼-- · 2019-12-11 05:45
cdc是转串口的?windows超级终端上能收最长16字节的小包,再多就崩了。换securecrt没事。stm32上没用过。
jjj
3楼-- · 2019-12-11 06:28
wye11083 发表于 2018-11-5 10:44
cdc是转串口的?windows超级终端上能收最长16字节的小包,再多就崩了。换securecrt没事。stm32上没用过。 ...

谢谢回复,
我说的是CDC HOST  ,我想你说的应该是CDC DEVICE,接电脑的
yayagepei
4楼-- · 2019-12-11 07:52
 精彩回答 2  元偷偷看……
jjj
5楼-- · 2019-12-11 12:24
yayagepei 发表于 2019-5-3 14:27
楼主现在调通了吗?速度能达到多少啊,我也刚开始做,用HS +USB3300速度只能到500kB ...

差不多500KB左右,不可能再大了, 理论最大也就12Mb, 但是还需要除掉一些开销,
yayagepei
6楼-- · 2019-12-11 17:58
jjj 发表于 2019-5-5 11:10
差不多500KB左右,不可能再大了, 理论最大也就12Mb, 但是还需要除掉一些开销, ...

但我用的是高速模式啊,在外还挂了一个PHY,手册上说是到489Mb/s

一周热门 更多>