STM32 使用回调从 USB CDC VCP 检索数据

Posted

技术标签:

【中文标题】STM32 使用回调从 USB CDC VCP 检索数据【英文标题】:STM32 using callbacks to retrive data from USB CDC VCP 【发布时间】:2017-09-05 11:52:46 【问题描述】:

我已经使用 CubeMX 和 HAL 为 USB CDC VCP 生成了一个项目,现在我想弄清楚如何实现这两个弱功能:

void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)

这些函数将在 HAL_PCD_IRQHandler 内部调用。我想要做的是在其中放置一些代码,以便我可以从主机检索接收到的数据并了解事务结束。

我已经看到 CubeMX 在 usbd_conf.c 中重新实现了这些弱函数,如下所示:

    /**
  * @brief  Data Out stage callback.
  * @param  hpcd: PCD handle
  * @param  epnum: Endpoint Number
  * @retval None
  */
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)

  USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);


/**
  * @brief  Data In stage callback..
  * @param  hpcd: PCD handle
  * @param  epnum: Endpoint Number
  * @retval None
  */
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)

  USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);

我想知道这两个函数(USBD_LL_DataOutStage 和 USBD_LL_DataInStage)是做什么的?以及如何编辑它们以实现我的目标。

【问题讨论】:

我不是 STM32 专家,但根据我的经验,我相信您应该使用的功能位于 usbd_cdc_if.c。在该文件中,您将找到函数 CDC_Receive_FSCDC_Transmit_FS。我相信这些是在大多数情况下将您的自定义代码添加到 USB 堆栈之上的要点。你看到那些功能了吗? @user2027202827:您提到的这两个功能是向您展示如何实现它们的示例。它们可用于提取和发送数据。我上面提到的函数是用于操作完成时的中断回调。 您介意我问使用这些特定功能的动机是什么,而不是 CubeMX 为您生成的界面? @user2027202827,CubeMX 只生成初始化。您可以在 usbd_cdc_if 中找到的这些功能只是您可以使用它们的一些示例,但建议您改进它们。而且我的应用程序对时间要求很高,因此我应该使用中断而不是拉取寄存器或变量来找出操作的结束。 感谢您回答我的问题 :) 抱歉,我对您的帮助不大。我假设您已经阅读了 USB 堆栈的设备库手册? 【参考方案1】:

我在 STM32Cube_FW_L4_V1.10.0 中遇到了同样的问题,在查看了这个问题和其他一些讨论后,我决定通过将 CDC DataIn 处理程序替换为添加对 CDC_TransmitReady_CB() 的调用以唤醒传输任务的替代实现来解决这个问题:

// Modified CDC DataIn handler to invoke a callback (CDC_TransmitReady_CB) on TX ready
uint8_t altDataInHandler(USBD_HandleTypeDef *pdev, uint8_t epnum) 
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
  if (hcdc == NULL) return USBD_FAIL;
  hcdc->TxState = 0;
  CDC_TransmitReady_CB();
  return USBD_OK;


void hackCdcClass() 
  USBD_CDC.DataIn = altDataInHandler;
 

丑陋,但它就像一个魅力。

【讨论】:

以上是关于STM32 使用回调从 USB CDC VCP 检索数据的主要内容,如果未能解决你的问题,请参考以下文章

STM32 双 CDC (VCP) 类

STM32 USB使用记录:使用CDC类虚拟串口(VCP)进行通讯

STM32 USB VCP(虚拟串口)

STM32 USB CDC Rx 中断

STM32 USB CDC 长包接收

STM32 VCP驱动——指针失效只有优化