[STM32F4] USB的CDC中断数据异常

[复制链接]
 楼主| 穿西装的强子 发表于 2024-11-16 14:21 | 显示全部楼层 |阅读模式
CDC, USB, pc, ST, hp, HPC
虚拟了2个串口,一开始两个串口都能正常使用,过了几分钟,如果关了一个串口,再打开就打不开,像被占用了一样。
在HAL_PCD_IRQHandler中断内,能进中断,但是数据不对,有遇到这种情况吗?
  1. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  2. {
  3.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  4.   uint32_t USBx_BASE = (uint32_t)USBx;
  5.   USB_OTG_EPTypeDef *ep;
  6.   uint32_t i;
  7.   uint32_t ep_intr;
  8.   uint32_t epint;
  9.   uint32_t epnum;
  10.   uint32_t fifoemptymsk;
  11.   uint32_t temp;

  12.   /* ensure that we are in device mode */
  13.   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  14.   {
  15.     /* avoid spurious interrupt */
  16.     if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  17.     {
  18.       return;
  19.     }

  20.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  21.     {
  22.       /* incorrect mode, acknowledge the interrupt */
  23.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  24.     }

  25.     /* Handle RxQLevel Interrupt */
  26.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  27.     {
  28.       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);

  29.       temp = USBx->GRXSTSP;

  30.       ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];

  31.       if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
  32.       {
  33.         if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
  34.         {
  35.           (void)USB_ReadPacket(USBx, ep->xfer_buff,
  36.                                (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4));

  37.           ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  38.           ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  39.         }
  40.       }
  41.       else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_SETUP_UPDT)
  42.       {
  43.         (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
  44.         ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  45.       }
  46.       else
  47.       {
  48.         /* ... */
  49.       }
  50.       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  51.     }

  52.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  53.     {
  54.       epnum = 0U;

  55.       /* Read in the device interrupt bits */
  56.       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);

  57.       while (ep_intr != 0U)
  58.       {
  59.         if ((ep_intr & 0x1U) != 0U)
  60.         {
  61.           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);

  62.           if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  63.           {
  64.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  65.             (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
  66.           }

  67.           if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
  68.           {
  69.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  70.             /* Class B setup phase done for previous decoded setup */
  71.             (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
  72.           }

  73.           if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
  74.           {
  75.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
  76.           }

  77.           /* Clear Status Phase Received interrupt */
  78.           if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  79.           {
  80.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  81.           }

  82.           /* Clear OUT NAK interrupt */
  83.           if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
  84.           {
  85.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
  86.           }
  87.         }
  88.         epnum++;
  89.         ep_intr >>= 1U;
  90.       }
  91.     }

  92.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
  93.     {
  94.       /* Read in the device interrupt bits */
  95.       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);

  96.       epnum = 0U;

  97.       while (ep_intr != 0U)
  98.       {
  99.         if ((ep_intr & 0x1U) != 0U) /* In ITR */
  100.         {
  101.           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);

  102.           if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  103.           {
  104.             fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  105.             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;

  106.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);

  107.             if (hpcd->Init.dma_enable == 1U)
  108.             {
  109.               hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;

  110.               /* this is ZLP, so prepare EP0 for next setup */
  111.               if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
  112.               {
  113.                 /* prepare to rx more setup packets */
  114.                 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
  115.               }
  116.             }

  117. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  118.             hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
  119. #else
  120.             HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
  121. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  122.           }
  123.           if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  124.           {
  125.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  126.           }
  127.           if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  128.           {
  129.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  130.           }
  131.           if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  132.           {
  133.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  134.           }
  135.           if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  136.           {
  137.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  138.           }
  139.           if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  140.           {
  141.             (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
  142.           }
  143.         }
  144.         epnum++;
  145.         ep_intr >>= 1U;
  146.       }
  147.     }

  148.     /* Handle Resume Interrupt */
  149.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  150.     {
  151.       /* Clear the Remote Wake-up Signaling */
  152.       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;

  153.       if (hpcd->LPM_State == LPM_L1)
  154.       {
  155.         hpcd->LPM_State = LPM_L0;

  156. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  157.         hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
  158. #else
  159.         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
  160. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  161.       }
  162.       else
  163.       {
  164. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  165.         hpcd->ResumeCallback(hpcd);
  166. #else
  167.         HAL_PCD_ResumeCallback(hpcd);
  168. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  169.       }

  170.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  171.     }

  172.     /* Handle Suspend Interrupt */
  173.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  174.     {
  175.       if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  176.       {
  177. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  178.         hpcd->SuspendCallback(hpcd);
  179. #else
  180.         HAL_PCD_SuspendCallback(hpcd);
  181. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  182.       }
  183.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  184.     }
  185. #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
  186.     /* Handle LPM Interrupt */
  187.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
  188.     {
  189.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);

  190.       if (hpcd->LPM_State == LPM_L0)
  191.       {
  192.         hpcd->LPM_State = LPM_L1;
  193.         hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;

  194. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  195.         hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
  196. #else
  197.         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
  198. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  199.       }
  200.       else
  201.       {
  202. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  203.         hpcd->SuspendCallback(hpcd);
  204. #else
  205.         HAL_PCD_SuspendCallback(hpcd);
  206. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  207.       }
  208.     }
  209. #endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
  210.     /* Handle Reset Interrupt */
  211.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  212.     {
  213.       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  214.       (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);

  215.       for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  216.       {
  217.         USBx_INEP(i)->DIEPINT = 0xFB7FU;
  218.         USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
  219.         USBx_INEP(i)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
  220.         USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
  221.         USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
  222.         USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
  223.       }
  224.       USBx_DEVICE->DAINTMSK |= 0x10001U;

  225.       if (hpcd->Init.use_dedicated_ep1 != 0U)
  226.       {
  227.         USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
  228.                                    USB_OTG_DOEPMSK_XFRCM |
  229.                                    USB_OTG_DOEPMSK_EPDM;

  230.         USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
  231.                                   USB_OTG_DIEPMSK_XFRCM |
  232.                                   USB_OTG_DIEPMSK_EPDM;
  233.       }
  234.       else
  235.       {
  236.         USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
  237.                                 USB_OTG_DOEPMSK_XFRCM |
  238.                                 USB_OTG_DOEPMSK_EPDM |
  239.                                 USB_OTG_DOEPMSK_OTEPSPRM |
  240.                                 USB_OTG_DOEPMSK_NAKM;

  241.         USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
  242.                                 USB_OTG_DIEPMSK_XFRCM |
  243.                                 USB_OTG_DIEPMSK_EPDM;
  244.       }

  245.       /* Set Default Address to 0 */
  246.       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;

  247.       /* setup EP0 to receive SETUP packets */
  248.       (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable,
  249.                              (uint8_t *)hpcd->Setup);

  250.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  251.     }

  252.     /* Handle Enumeration done Interrupt */
  253.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  254.     {
  255.       (void)USB_ActivateSetup(hpcd->Instance);
  256.       hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);

  257.       /* Set USB Turnaround time */
  258.       (void)USB_SetTurnaroundTime(hpcd->Instance,
  259.                                   HAL_RCC_GetHCLKFreq(),
  260.                                   (uint8_t)hpcd->Init.speed);

  261. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  262.       hpcd->ResetCallback(hpcd);
  263. #else
  264.       HAL_PCD_ResetCallback(hpcd);
  265. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */

  266.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  267.     }

  268.     /* Handle SOF Interrupt */
  269.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  270.     {
  271. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  272.       hpcd->SOFCallback(hpcd);
  273. #else
  274.       HAL_PCD_SOFCallback(hpcd);
  275. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */

  276.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  277.     }

  278.     /* Handle Incomplete ISO IN Interrupt */
  279.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  280.     {
  281.       /* Keep application checking the corresponding Iso IN endpoint
  282.       causing the incomplete Interrupt */
  283.       epnum = 0U;

  284. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  285.       hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  286. #else
  287.       HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  288. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */

  289.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  290.     }

  291.     /* Handle Incomplete ISO OUT Interrupt */
  292.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  293.     {
  294.       /* Keep application checking the corresponding Iso OUT endpoint
  295.       causing the incomplete Interrupt */
  296.       epnum = 0U;

  297. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  298.       hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  299. #else
  300.       HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  301. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */

  302.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  303.     }

  304.     /* Handle Connection event Interrupt */
  305.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  306.     {
  307. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  308.       hpcd->ConnectCallback(hpcd);
  309. #else
  310.       HAL_PCD_ConnectCallback(hpcd);
  311. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */

  312.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  313.     }

  314.     /* Handle Disconnection event Interrupt */
  315.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  316.     {
  317.       temp = hpcd->Instance->GOTGINT;

  318.       if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  319.       {
  320. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  321.         hpcd->DisconnectCallback(hpcd);
  322. #else
  323.         HAL_PCD_DisconnectCallback(hpcd);
  324. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  325.       }
  326.       hpcd->Instance->GOTGINT |= temp;
  327.     }
  328.   }
  329. }
powerantone 发表于 2024-11-18 11:04 | 显示全部楼层
当关闭一个串口时,如果没有正确清理和释放相关资源可能会导致资源冲突或锁定
stormwind123 发表于 2024-11-18 13:00 | 显示全部楼层
检查资源释放包括缓冲区、中断、端点配置等。
probedog 发表于 2024-11-18 17:03 | 显示全部楼层
更新USB CDC类的驱动程序或HAL库到最新版本。
 楼主| 穿西装的强子 发表于 2024-11-18 18:50 | 显示全部楼层
powerantone 发表于 2024-11-18 11:04
当关闭一个串口时,如果没有正确清理和释放相关资源可能会导致资源冲突或锁定 ...

有时候不打开等一会也打不开了
classroom 发表于 2024-11-18 19:09 | 显示全部楼层
检查USB主机配置是否有误
flycamelaaa 发表于 2024-11-18 19:59 | 显示全部楼层
检查USB连接器和电缆是否完好。
laocuo1142 发表于 2024-11-18 20:23 | 显示全部楼层
增加日志记录功能,记录关闭和重新打开串口时的关键状态和事件。
使用调试器或逻辑分析仪来跟踪USB通信和中断处理过程。
kqh11a 发表于 2024-12-30 17:45 | 显示全部楼层
在关闭串口时,确保调用 HAL_UART_DeInit() 来清理串口的配置和资源。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

258

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部