STM32 USB CDC Rx 中断

STM32 USB CDC Rx Interrupt

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

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

如评论所述,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,请将数据放入队列中以在任务上下文中进行处理。

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

如果没有调用USBD_CDC_ReceivePacket并且端点fifo变满,控制器会自动发送NAKs给主机。不幸的是,STM HAL 锁定传输直到发生这种情况。因此,您可以将指针和长度保存在某些变量中,return 来自 CDC_Receive_FS 并在 hardware/fifo/queue 准备就绪时调用 USBD_CDC_ReceivePacket,但 Tx 被锁定直到 USBD_CDC_ReceivePacket被调用。