cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 & STM32F7 USB Host Core (Interrupt flood)

Tim Michals
Associate II
Posted on May 19, 2017 at 01:02

Issue:

USB Core issing interrupt at a rate of 8.65us causing high CPU loading.

Software/Chip:

Using USB Host/CDC from STM32Cube V1.15 on a STM32F429 board. 

  USB interrupt sources:

- SOF Interrupts (It is not needed for CDC type transfers) turned this interrupt off and still getting high interrupt rate.

   This is configured in

HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)

.....

  /* Enable interrupts matching to the Host mode ONLY */

  USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM            | USB_OTG_GINTMSK_HCIM |\

                 

   USB_OTG_GINTMSK_SOFM

|USB_OTG_GINTSTS_DISCINT|\

                    USB_OTG_GINTMSK_PXFRM_IISOOXFRM  | USB_OTG_GINTMSK_WUIM);

 

  return HAL_OK;

}

- NAK interrupts from bulk in endpoint.  The issue is when the OTG USB gets enough NAKs from the bulk endpoint and issues an interrupt at a rate of 8.625us. 

Solutions

?

Is there a work around that does not degrade USB performance?  The STM32FH7 also has has the same code to re-enable the bulk in endpoint. 

static void HCD_HC_IN_IRQHandler   (HCD_HandleTypeDef *hhcd, uint8_t chnum)

  }

  else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NAK)

  {   

    if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)

    {

      __HAL_HCD_UNMASK_HALT_HC_INT(chnum);  

      USB_HC_Halt(hhcd->Instance, chnum);   

    }

    else if  ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||

         (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))

    {

      /* re-activate the channel  */

      tmpreg = USBx_HC(chnum)->HCCHAR;

      tmpreg &= ~USB_OTG_HCCHAR_CHDIS;

      tmpreg |= USB_OTG_HCCHAR_CHENA;

      USBx_HC(chnum)->HCCHAR = tmpreg;

    }

    hhcd->hc[chnum].state = HC_NAK;

    __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);

  }

}

There are several postings about this issue (The first posting is the best description of the issue)

https://community.st.com/0D50X00009XkYz2SAF

 

https://community.st.com/0D50X00009XkYSSSA3

 

https://community.st.com/0D50X00009Xked0SAB

 

null
37 REPLIES 37

@BJohn.1

I've zipped up the original fix as posted above plus my changes to port it to the STM32F745. I would suggest using a Diff tool like Beyond Compare so you can diff entire directories and subdirectories. Makes the work quicker.

Best

Dear Imen DAHMEN,

I know this thread is 2 months old, but is addresses this NAK interrupt flood problem.

I read current thread replays over and over, and even tried this work around file you suggested USB_NAK_Fix, unfortunately this won't fixed my CPU load overhead. (maybe I missed something)

I'm using FreeRTOS + ST HAL USB Host driver in FS mode (STM32Cube_FW_H7_V1.6.0) with NUCLEO-H743, and in case device usb doesn't answering to Host after "USBH_CDC_Receive" it causes this NAK interrupt flood which leads to USBH_Process_OS (usbh_core.h) to run repeatedly and load CPU to almost 100%.

The problem with "USB_NAK_Fix" that is based on old STM32Cube_FW_H7 drivers from mid 2018, it's almost 2 years ago, since than many releases were out with many bug fixes

That only fix which really did the trick was done by Kazmierczak.Jim  (Posted on May 25, 2018 at 18:17)

Hack to disable the NAK interrupt completely (it'll be re-enabled in SOF)

But I don't know it's side effects, is it really safe to use?

I hope you same day will eventually release proper software fix with STM32Cube_FW_H7 drivers to address this issue (although you said it's a limitation in the OTG peripheral).

Best regards

Igor

Jim Kaz
Associate II

Hi @IUcha.843​ ,

If it makes you feel any better, I ported my own change to an H743 Eval board with the H7 v1.5.0 and it seems to work properly (at least from what I can tell). I have a kind of unique set up where I have an eval board connecting to my computer as a USB device, which it then communicates over an CAN-FD bus to another Eval board connected as a USB host to a Rasberry Pie and I am able to send ethernet traffic to the Rasberry Pie and transfer a file via WinSCP (my USB nodes enumerate as RNDIS devices, which is a specialized form of CDC that makes it look like an ethernet connector). With this bizarre setup I am able to transfer a file from the Rasberry Pie, to the node acting as a USB host, over a CAN-FD network to a node acting as a USB device to my computer at rates of around 3 Mb. I suspect I could get this number higher by running the processor faster (only running at 100Mhz for power reasons) and further optimizations, but the project is still in it's infancy.

So, as far as I can tell, it does work without any undue side effects, though I'd love for the actual developers to take a look at it and let us know if it's safe 😀

Same here, also ran into this problem in a product that is already selling (read some data from USB stick). I applied the patch of Kazmierczak.Jim. This fixed the problem mostly but still I get situations where the NAK clear/mask/umask thing rotates forever, does not even recognise the stick disconnect event...

Although this thread is quite old, I would like to chime in with an adaptation of Jim's excellent and neat fix for the USB interrupts flood. For those really using the CubeMX to generate (and re-generate) code, all proposed patches require modification of certain files that during a subsequent code generation are overwritten. I am still puzzled by ST's decision after all this years NOT to include in the CubeMX one of the available fixes, including one proposed by ST themselves!

Anyway, my solution requires changes/additions in a single file, e.g. stm32f7xx_it.c (for the STM32F7xx family) which is generated by CubeMX, see example below:

/**
 * @brief This function handles USB On The Go FS global interrupt.
 */
void
OTG_FS_IRQHandler (void)
{
  /* USER CODE BEGIN OTG_FS_IRQn 0 */
 
  uint32_t ch_num;
  HCD_HandleTypeDef* hhcd = &hhcd_USB_OTG_FS;
  uint32_t USBx_BASE = (uint32_t) hhcd->Instance;
 
  if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF) && hhcd->Init.dma_enable == 0)
    {
      for (ch_num = 0; ch_num < hhcd->Init.Host_channels; ch_num++)
        {
          // workaround the interrupts flood issue: re-enable NAK interrupt
          USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINT_NAK;
        }
    }
 
  /* USER CODE END OTG_FS_IRQn 0 */
  HAL_HCD_IRQHandler (&hhcd_USB_OTG_FS);
  /* USER CODE BEGIN OTG_FS_IRQn 1 */
 
  if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT) && hhcd->Init.dma_enable == 0)
    {
      for (ch_num = 0; ch_num < hhcd->Init.Host_channels; ch_num++)
        {
          if (USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK)
            {
              if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL)
                  || (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
                {
                  // workaround the interrupts flood issue: disable NAK interrupt
                  USBx_HC(ch_num)->HCINTMSK &= ~USB_OTG_HCINT_NAK;
                }
            }
        }
    }
 
  /* USER CODE END OTG_FS_IRQn 1 */
}

Thus any subsequent code generations will not overwrite the changes/additions, as they are done in the special sections where the user may add his code.

Note that for the OTG_FS peripheral the DMA test is redundant (hhcd->Init.dma_enable == 0) and should be eliminated, as this peripheral has no DMA at all. Although my example refers to the OTG_FS peripheral, I included it for conformity. In fact, if using the OTG_HS peripheral you don't need any fix, the best way to go is to enable the DMA and the issue will be handled by the hardware.

ThomasK
Associate

Hi,

I observe the same problem using the NUCLEO-L496ZG board. The firmware hangs after a call to USBH_CDC_Receive until some data arrives. I use the FW_L4 V1.17.0 HAL. For testing, I talk to an MCP2221 USB/Serial converter. As soon as I send some data on the serial wire, the firmware continues.

Is there any plan to address this problem or a workaround?

Regards,

Thomas

I had the same problem on the STM32F4, and this solution resolved it. Thank you, sir.

laurentc
Associate II

ST teams, this issue has been pending for 7 ***ing years - have some respect for the life of your clients !!

Do you realize how many man days have been lost by your clients because of that ?

The patches provided by ST are now impractical.

It is impossible to do a proper winmerge with the latests fw because the files have changed everywhere.

Any update regarding this topic for H7 ?