搜索
bottom↓
回复: 8

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

[复制链接]

出0入0汤圆

发表于 2018-11-4 22:22:54 | 显示全部楼层 |阅读模式
本帖最后由 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;
  }
上面标颜色的位置,我把大于号改成“==”等于号了,因为我调试过程中,这个地方不可能大于,也就是说上次接收的数据大小不可以大于端点的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通道停止,
这个问题已经困扰了很久了……

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2018-11-5 08:00:21 | 显示全部楼层
有人用过CDC这个类吗?

出0入442汤圆

发表于 2018-11-5 10:44:32 来自手机 | 显示全部楼层
cdc是转串口的?windows超级终端上能收最长16字节的小包,再多就崩了。换securecrt没事。stm32上没用过。

出0入0汤圆

 楼主| 发表于 2018-11-5 11:11:55 | 显示全部楼层
wye11083 发表于 2018-11-5 10:44
cdc是转串口的?windows超级终端上能收最长16字节的小包,再多就崩了。换securecrt没事。stm32上没用过。 ...

谢谢回复,
我说的是CDC HOST  ,我想你说的应该是CDC DEVICE,接电脑的

出0入0汤圆

发表于 2019-5-3 14:27:42 | 显示全部楼层
楼主现在调通了吗?速度能达到多少啊,我也刚开始做,用HS +USB3300速度只能到500kB

出0入0汤圆

 楼主| 发表于 2019-5-5 11:10:28 | 显示全部楼层
yayagepei 发表于 2019-5-3 14:27
楼主现在调通了吗?速度能达到多少啊,我也刚开始做,用HS +USB3300速度只能到500kB ...

差不多500KB左右,不可能再大了, 理论最大也就12Mb, 但是还需要除掉一些开销,

出0入0汤圆

发表于 2019-5-18 19:55:01 | 显示全部楼层
jjj 发表于 2019-5-5 11:10
差不多500KB左右,不可能再大了, 理论最大也就12Mb, 但是还需要除掉一些开销, ...

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

出0入0汤圆

 楼主| 发表于 2019-5-22 16:40:30 | 显示全部楼层
yayagepei 发表于 2019-5-18 19:55
但我用的是高速模式啊,在外还挂了一个PHY,手册上说是到489Mb/s

高速最大480Mbps

出0入0汤圆

发表于 2019-5-22 16:56:59 | 显示全部楼层
本帖最后由 飞天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);
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-22 09:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表