cancel
Showing results for 
Search instead for 
Did you mean: 

HardFault with USB CDC ??

matic
Associate III
Posted on July 21, 2016 at 20:32

Hi.

When I send data out via USB, the program goes to HardFault. I found out that this happens when the function below is executed:

USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
{
if(pdev->dev_state == USBD_STATE_CONFIGURED)
{
if(pdev->pClass->SOF != NULL)
{
pdev->pClass->SOF(pdev);
}
}
return USBD_OK;
}

This function is defined in usbd_core.c file. Has anyone an idea what could go wrong here? Thanks
6 REPLIES 6
Posted on July 21, 2016 at 21:10

Wouldn't it suggest thatpdev->pClass is NULL or at an inaccessible memory location? Or perhaps thatpdev->pClass->SOF isn't valid?

USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
{
if(pdev->dev_state == USBD_STATE_CONFIGURED)
{
if((pdev->pClass != NULL) && (pdev->pClass->SOF != NULL))
{
pdev->pClass->SOF(pdev);
}
}
return USBD_OK;
}

What does the Hard Fault state of the processor suggest is the problem?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
matic
Associate III
Posted on July 22, 2016 at 07:51

Hi Clive.

When Fault occurs. IBUSERR bit is set in CFSR register. The fault occurs when this

pdev->pClass->SOF(pdev);

is executed. The SOF is not NULL at that moment. If you look to the attached picture, you can see the exact instruction where it faults. This is when BLX is executed.

________________

Attachments :

Capture.JPG : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HtlX&d=%2Fa%2F0X0000000aWe%2FeEM7N61haXZXhzL3Qn7iw.gdKFfxUKXICAa3M7cflhw&asPdf=false
Posted on July 22, 2016 at 13:19

This really doesn't show the salient registers at the faulting instruction.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
kmnadler
Associate

I have inherited a legacy STM32F407 project using STD libraries, bare-bones, no RTOS, usbd_core.c version V1.2.1.

I am implementing a USB VCP interface. I am getting seemingly random hardfaults in USBD_SOF(). I start the debugger, USB is connected directly to a Windows 10 laptop, no Windows app has attempted to open the serial port. My app idles for up to 10 seconds or so then hardfaults. I have traced the fault to:

static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE *pdev)
{
  if(pdev->dev.class_cb->SOF)
  {
    pdev->dev.class_cb->SOF(pdev);
  }

  return USBD_OK;
}

I have verified that pdev and pdev->dev.class_cb are valid and SOF is zero. With SOF == zero this should just return without doing anything at all! Instead, I'm getting random hardfaults of CFSR.INVSTATE. I put in a counter to see how many times we've passed through USBD_SOF() successfully. Typically, it is in the neighborhood of 5880 passes before the hardfault.

After a day chasing this hardfault it magically cured itself. Two days ago, it was consistent. I haven't changed any code other than adding a counter and removing the counter.

I am getting a second hardfault in the same function. My Windows app opens the serial port and sends a heartbeat message that essentially asks: are you in bootloader or in the main app? This message is sent every second. This handshake message goes on for minutes or even hours. Eventually I get a hardfault on the USBD_SOF() return call and the stack is blasted.

Has anyone seen this before?

Pavel A.
Evangelist III

Check for stack overrun. Increase stack size if needed.

 

kmnadler
Associate

Solution found!

I used two examples for my implementation. One of them disabled the USB OTG interrupts and called the interrupt functions in the main while(1) loop. The other used proper interrupts. Digging into my higher level USB handling I found the call to USBD_SOF() was still in the main thread. So, it was called both by interrupt and by the main thread. My best guess is that the interrupt triggered while I was already in USBD_SOF(). I removed the call in the main thread and let the interrupt call USBD_SOF() as it was intended. So far, so good.

        -ken