Hard Fault encountered after vTaskStartScheduler is invoked

Hello there,

I am using Ozone debugger tool from Segger for my project. I am new to this tool and still in learning phase.

My project deals with ARM Cortex M4 + M0 (SOC) with hardware floating point enabled.
System uses FreeRTOS as the operating system. I am running into following issue at the start up. I instantiated 3 threads and start the scheduler and run into hard fault.

I have attached a screen shot above to indicate the exact line where the hard fault occurs (tasks.c, #2037 xPortStartScheduler( ) ) this is invoked from vTaskStartScheduler( ) API.

Please let me know what could be the reason. Below is the set up details.

Overall Settings

  • Ozone version number : V3.28e

  • Target Hardware : SOC (Cortex M4 + M0)

  • Debug probe employed : J-Link Plus

  • Operating System : FreeRTOS v10.1.1

  • Host PC OS Version : Windows 10 Pro

Debug Probe Settings

  • SWD

  • 4MHz

  • Host Interface : USB

  • Program File Format : XXXX.axf (ARM)

Thank you in advance.

Can you put a breakpoint near the beginning of your task(s) to see if control is reaching them? With some debuggers, the hard fault only looks like it happens in xPortStartScheduler() but really is happening in a task.

Thanks @jefftenney.
I tired your suggestion, it doesn’t reach the beginning of any task.

OK, a few additional suggestions:

  • Be sure configASSERT() is defined, and be sure you have a vApplicationMallocFailedHook() installed to catch out-of-memory and/or heap configuration errors.

  • Check the priority of the SVC exception. See here.

  • Does your FreeRTOSConfig.h have these lines:

#define vPortSVCHandler     SVC_Handler
#define xPortPendSVHandler  PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
  • If all of that fails, can you step through the code and isolate the statement that is causing the hard fault? Note that you will need to put a breakpoint at the beginning of the vPortSVCHandler() to step into that function.
  • ConfigAssert() - Is defined.
  • vApplicationMallocFailedHook() is installed to catch the memory failures.
  • Check the priority of the SVC exception - I read the post but never got to that point in code execution. Image attached. However, I reviewed the register value and it was set to 0.
  • Yes, my freeRTOSConfig.h file has those things defined.
  • Image attached to show where the execution fails. I have highlighted it.

At least we’ve ruled out the common causes of startup faults on CM4.

That code is attempting to read the initial stack pointer (MSP) from the vector table. Can you check your linker file for where the vector table resides? Based on your screenshot, the vector base register is pointing to 0x00008000. Maybe the vector base register (SCB->VTOR) has been set wrong?

1 Like

Thanks @jefftenney .
I think that was the cause of the issue. I manually modified the value of SCB->VTOR to the address we are using in linker, I see the issue went away.

However, I would assume this information to be part of the symbol table so I don’t have to manually update the register value. Right? If not how do I let the ozone debugger know about this change.

I suspect ozone doesn’t care about the location of the vector table nor the value in SCB->VTOR.

Normally, the silicon vendor provides startup code that matches the basic linker files they provide, and so the startup code sets SCB->VTOR. You’d have to look at their code to see how they determine the value to write to SCB->VTOR to understand where things went wrong. For example, maybe you modified their linker file in an unexpected way. Maybe they anticipate you will use a bootloader but you don’t. Etc etc. Regardless, if you set SCB->VTOR early in main(), after all the C startup code is finished and before enabling any interrupts or trying to start FreeRTOS, you should be all set.

1 Like

Got it. Thank you.
I exactly did that, just added the line of code in main function and things started to work as expected. SCB->VTOR = XXXX;

1 Like

Hi @TCK, I had the same issue as yours, Can you please help me understand your solution step by step as I am still new in this field. Thank you!

Hi @bnina-ayoub ,

On my hardware platform, the interrupt vector table is relocated to a different address from its default address. Due to this change, when I used a debugger (ozone in my case) I was hitting a hard fault.

As mentioned above I just had to include the statement (SCB->VTOR = NEW_ADDRESS OF interrupt vector table) in main routine to resolve the issue.

Hope this helps. Good luck!