STM32 USB CDC Rx 中断

Posted

技术标签:

【中文标题】STM32 USB CDC Rx 中断【英文标题】:STM32 USB CDC Rx Interrupt 【发布时间】:2021-02-28 20:58:36 【问题描述】:

我已经在 STM32-F446re(Nucleo) 上实现了 USB CDC (VCP)。我在循环中使用int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) 来接收数据。但是很多数据也被发送过来了,因此我想要基于接收中断。

谁能帮我了解如何设置 USB CDC Rx 中断?

【问题讨论】:

它已经是基于中断的,这个函数是一个回调函数。只需使用数据。 【参考方案1】:

正如所评论的,CDC_Receive_FS 是一个由 USB 堆栈中断处理程序调用的回调,并且它已经在中断上下文中运行。您不应该在循环中调用它 - 它由堆栈调用,并且您应该实现处理数据的函数。

实现可能如下所示:

static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)

    // Process Len bytes from Buf
    YOUR_CODE_HERE

    // Set the RX buffer
    USBD_CDC_SetRxBuffer(hUsbDevice_0, &Buf[0]);
    
    // Ready to receive the next packet
    USBD_CDC_ReceivePacket(hUsbDevice_0);

    return USBD_OK ;

那么在YOUR_CODE_HERE 要做的最明显的事情就是将数据放入 FIFO 队列或环形缓冲区,然后在主线程上下文中使用。或者,如果您使用的是 RTOS,则将数据放入队列中以便在任务上下文中进行处理。

至关重要的是,您应该尽快获取数据并返回,因为在您这样做之前将阻止更多数据,并且它是一个中断上下文,因此您不想闲逛 - ST 代码已经有点ISR IMO 的重量级人物。在他们早期的(STM32Cube 之前的)USB 库中,我将整个堆栈移到了 RTOS 任务中,因此 ISR 只是触发了任务接收到的事件。这对于防止时间关键任务被 USB 中断延迟是必要的。

【讨论】:

【参考方案2】:

如果未调用 USBD_CDC_ReceivePacket 且端点 fifo 已满,控制器将自动向主机发送 NAK。不幸的是,STM HAL 会锁定 Transmit,直到发生这种情况。因此,您可以将指针和长度保存在某个变量中,从 CDC_Receive_FS 返回并在您的硬件/fifo/队列准备好时调用 USBD_CDC_ReceivePacket,但在调用 USBD_CDC_ReceivePacket 之前 Tx 被锁定。

【讨论】:

以上是关于STM32 USB CDC Rx 中断的主要内容,如果未能解决你的问题,请参考以下文章

如何在 STM32F1 上使用 HAL 库永久启用 uart RX 中断

Stm32L151RCxxx USART 挂起问题,同时基于中断的 TX/RX

STM32F103在RX中断时无法通过UART接收数据

USB的中断说明

stm32 usb数据接收与数据发送程序流程分析

STM32 FreeRTOS - UART延迟中断问题