请教一个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-11 22:20
yayagepei 发表于 2019-5-18 19:55
但我用的是高速模式啊,在外还挂了一个PHY,手册上说是到489Mb/s

高速最大480Mbps
飞天558
2楼-- · 2019-12-12 00:40
本帖最后由 飞天558 于 2019-5-22 16:58 编辑

接收时是不是要等到接收状态完成,再做其他操作
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,j=0;

   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);

一周热门 更多>