Cortex-M0+ hard fault issue with RTOS Integration

Hi Team,

I am working on S32K116 micro which is Cortex M0+ core.
After Integration of FreeRTOS(V10.0.1), I am getting a hard fault. I have gone through some of the forums here and added an asm code as below to capture the register values before control goes to hard fault handler.

void vHardFaultHandler( void ) attribute( ( naked ) );

/* The fault handler implementation calls a function called
prvGetRegistersFromStack(). */
void vHardFaultHandler(void)
{
__asm volatile
(
“mrs r0, msp \n”
“movs r1, #4 \n”
“mov r2, lr \n”
“tst r2, r1 \n”
“beq jump_debugHardfault \n”
“mrs r0, psp \n”
“jump_debugHardfault: \n”
“ldr r1, =debugHardfault \n”
“bx r1 \n”
);
}

void debugHardfault(UINT32 *sp)
{
UINT32 r0 = sp[0];
UINT32 r1 = sp[1];
UINT32 r2 = sp[2];
UINT32 r3 = sp[3];
UINT32 r12 = sp[4];
UINT32 lr = sp[5];
UINT32 pc = sp[6];
UINT32 psr = sp[7];
while(1);
}

Attached the screen shot that has register values and PC value. It shows that while executing the function “xTaskIncrementTick(void)”, control went to hard fault.

Please suggest where I am going wrong. Also, let me know if you need more details.

Are you asking what is wrong with the fault handler, or what is wrong with your code that is generating the fault? I think the fault handler on the FreeRTOS.org site is for the Cortex-M3 and I’m not sure how compatible it is with the Cortex-M0.

Hi Richard,

Before the RTOS integration, I did not see any Hard fault. After integration, I am seeing a hard fault first and after I did reset manually in the debugger and run, then I am seeing a reset this time. Then I hit the run again, it is executing normally. All the tasks are executing.

I don’t know why the first two times, after I hit run, hard fault and reset are happening. Is there any possible areas I need to see. Please suggest.

Note: Very few times this pattern is not occurring. Those times after flash, I am seeing only reset first time and then If I hit run, it is executing normally.

How are you resetting the board? Through the debugger? What happens if you remove the debugger and perform a hard reset?

If I remove debugger and do a hard reset, I see module is communicating. With debugger also, I see the normal execution after initial hard fault and reset.

It sounds like if you do a hard reset things are running ok, but if you do a reset through the debugger then you get the issue you describe. If that is the case then I suggest looking at how your debugger is performing the reset. Normally there are several reset options, not all of which will put the processor back to a clean state.

But debugger is not throwing any issue before integration of RTOS. After integrating the RTOS, I am getting the hard fault and reset. Also, I am seeing the place where hard fault is happening. While executing the function xTaskIncrementTick(void), I am seeing this fault (As shown in the above attachment). Would there be any FreeRTOSConfiguration issue? Or improper interrupt handling? Is there any way to verify these conditions?
Thanks.

If my understanding is correct, it works without the debugger but not with the debugger. Without any further information my conclusion would be that there is something about the environment when connected to the debugger that is causing the problem. From experience that is most likely one of two things - the chip is not being reset correctly (for example, an interrupt may remain enabled after a debugger reset and fire before the RTOS structures are initialised and therefore cause a crash), or that the debugger is configured to use semihosting which conflicts with the kernel’s own use of the necessary hardware functionality. I’m not saying this is definitely the problem, but with the information I have, my judgement would be it is the most likely.

Does the configuration change when you use the debugger compared to when you don’t?

I’ve been using FreeRTOS for the LPC1114 chip, which is Cortex-M0 through the included port without any issues. I debug my programs using an Eclipse IDE from NXP.

All Cortex-M0 (or M0+) cores are the same for any brand. Why don’t you take a look at the LPC1114 port?