Skip to main content
Associate
July 21, 2023
Question

USB HOST CDC USBH_CDC_Receive frequent interrupts problem

  • July 21, 2023
  • 3 replies
  • 2849 views

Hi!

I'm using stm32f105vct6, project generated with CubeMx, Usb Host CDC with FreeRTOS (cmsis v2)

usb_cdc.c

USBH_FindInterface(phost, COMMUNICATION_INTERFACE_CLASS_CODE, ABSTRACT_CONTROL_MODEL, COMMON_AT_COMMAND);

was changed to

USBH_FindInterface(phost, COMMUNICATION_INTERFACE_CLASS_CODE, ABSTRACT_CONTROL_MODEL, NO_CLASS_SPECIFIC_PROTOCOL_CODE);

otherwise there was no enumeration

 

#define CDC_RX_BUFFER_SIZE 512

uint8_t CDC_RxBuffer[CDC_RX_BUFFER_SIZE];

After Appli_state == APPLICATION_READY I set

memset(CDC_RxBuffer, 0, CDC_RX_BUFFER_SIZE);

USBH_CDC_Receive(&hUsbHostFS, CDC_RxBuffer, CDC_RX_BUFFER_SIZE);

 

and USBH_CDC_ReceiveCallback:

// Handles the data recived from the USB CDC host

rx_size = USBH_CDC_GetLastReceivedDataSize(phost);

for (int i = 0; i < rx_size; i++)

{

      pp_circle_buf[pp_iend++] = CDC_RxBuffer[i];

      if(pp_iend >= PP_CIRCLE_BUF_SIZE) pp_iend = 0;

}

USBH_CDC_Receive(phost, CDC_RxBuffer, CDC_RX_BUFFER_SIZE);

osSemaphoreRelease(semUSBDataReadyHandle);

 

Transmission and reception (including packets of several kilobytes) work fine.

But there is a problem. When not issuing USBH_CDC_Receive interrupts are with period ~1ms.

But if prepare receiving buffer with USBH_CDC_Receive interrupts become more frequent, so many tasks in FreeRTOS got freezed (including watchdog task). System almost hang up except USB (all communication with paypass device works fine, USB task has normal priority)

Executing USBH_CDC_Stop(&hUsbHostFS); returns to normal interrupt rate (with no receiving)

PayPass device may transfer at any time, so I need to wait packets all the time while processing transaction

May be I do something wrong in receiving?

Thanks for help

    This topic has been closed for replies.

    3 replies

    Ghofrane GSOURI
    Technical Moderator
    July 21, 2023

    Hello @VitalyTolochanov 

    First let me thank you for posting.

    It seems like the issue might be related to the way you are using the semaphore to signal that USB data is ready. It's possible that the semaphore is being released too frequently, causing other tasks to get blocked.

    One suggestion would be to use a flag instead of a semaphore to signal that USB data is ready. You can set the flag in the USBH_CDC_ReceiveCallback function, and then check the flag in your main task loop to determine if there is new data to process. This way, you can avoid releasing the semaphore too frequently and potentially causing other tasks to get blocked.

    Another suggestion would be to increase the priority of the USB task to ensure that it has enough processing time to handle incoming data. You can do this by setting the priority of the USB task higher than the other tasks in your system.

    Finally, you may want to consider using a circular buffer to store incoming data instead of copying it to a fixed-size buffer. This can help to avoid buffer overflows and ensure that incoming data is processed in a timely manner.

    Thx

    Ghofrane

    To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
    Associate
    July 21, 2023

    Thanks for replying
    Now I’m just trying to ping paypass device (sending ping and getting answer 6 bytes)

    Removed semaphore from USBH_CDC_ReceiveCallback and PayPass task with osDelay(ms_200) -> same situation
    I’m already using circular buffer
    rx_size = USBH_CDC_GetLastReceivedDataSize(phost);
    for (int i = 0; i < rx_size; i++)
    {
          pp_circle_buf[pp_iend++] = CDC_RxBuffer[i];
          if(pp_iend >= PP_CIRCLE_BUF_SIZE) pp_iend = 0;
    }

    As I mentioned above, the problem is in very high rate of interrupts after calling USBH_CDC_Receive

    Setting usb task to highest priority leads to all system hang up

    Only HAL_HCD_IRQHandler is continious working

    Following flags are active

    /* Handle Host SOF Interrupt */
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))

    /* Handle Rx Queue Level Interrupts */
    if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)

    /* Handle Host channel Interrupt */
    if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))

    Thanks

    Associate
    July 21, 2023

    Setting usb task to highest priority leads to all system hang up
    Interrupt calls USBH_CDC_Process, after processing next USB interrupt is called and so on...
    As usb task has highest priority, none of other tasks gets control

    Thx

    Associate
    July 22, 2023

    so, what i did up to this moment
    this topic makes smth clear for me
    https://community.st.com/t5/stm32cubemx-mcu/bug-cubemx-usb-otg-sof-flag-causing-interrupt-flood-fixed/m-p/176647

    1. Remove SOF interrupt
    2. Set USB task to the lowest priority
    3. Increase clk to 72MHz
    4. When Paypass device is in idle state, I don't set USBH_CDC_Receive after receiving ping answer
    USB_OTG_GINTSTS_RXFLVL is