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

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

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

最新更新