Skip to main content
Explorer
December 2, 2024
Question

Problem with sending more than 16Kbytes of data with CDC_Transmit_FS.

  • December 2, 2024
  • 2 replies
  • 1706 views

We are trying to send serial data from an ST microcontroller to a PC using CDC_Transmit_FS.
We can send data less than 16Kbyte (4096 * 4byte) without any problem, but when we try to send larger size, sometimes we get USBD_STATUS_CANCELED (confirmed by Wireshark + USBpcap).
Could you please tell us why the above behavior occurs?

    This topic has been closed for replies.

    2 replies

    Technical Moderator
    December 3, 2024

    Hi @pass3master 

    For bulk transfer in full speed, max packet size is 64. It is preferable to share your trace to understand better the error. Instead of sending a large chunk of data at once, split it into smaller chunks that fit within the endpoint buffer size (64bytes in FS mode).

    Explorer
    December 3, 2024

    Thank you for your response. I see.
    So, if I want to transfer 40Kbytes of data, I need to call CDC_Transmit_FS 625 times (40000 ÷ 64)?

    Technical Moderator
    December 3, 2024

    Hi @pass3master 

    As explained in this article How to select suitable endpoints for your STM32 US... - STMicroelectronics Community, you can implement double buffering if available, to improve data throughput. Also, FIFO sizes can be adjusted to optimize performance and reduce CPU overhead. For example, to handle more data and reduce the frequency of FIFO overflows, bulk endpoints require large FIFOs to handle large data transfers efficiently. Otherwise, you can implement a timer to manage the transmission of large data chunks by generating periodic interrupts. Using this timer, you allow your STM32 perform other tasks in between transmission and reduce the risk of overwhelming the USB stack.

    Graduate
    December 5, 2024

    Right, it's enough to disable USB int. Use NVIC_DisableIRQ() and NVIC_EnableIRQ().

    Super User
    December 5, 2024

    Except of one small thing: chance of priority inversion. If you raise the interrupt priority to the level of USB, all interrupts of lower priority will be blocked. If you just disable the USB interrupt, you remain at background/thread priority and can be preempted by interrupts of lower priority than the USB.

     

    Graduate
    December 6, 2024

    I did not suggest any dynamic priority changes. In my projects, for starting USB In transfers I always use a software-generated interrupt of the same priority as USB hw one. Anyway, to interact with this interrupt, the interface routine called from lower priority must disable all ints for 2 lines of C code.