HardFault_Handler triggered from xPortPendSVHandler

Hi All,

We are using FreeRTOS V10.2.1. We have observed that sometimes during osKernelStart call, HardFault_Handler occurs when xPortPendSVHandler is called.

void xPortPendSVHandler( void )
{
	/* This is a naked function. */

	__asm volatile
	(
	"	mrs r0, psp							\n"
	"	isb									\n"
	"										\n"
	"	ldr	r3, pxCurrentTCBConst			\n" /* Get the location of the current TCB. */
	"	ldr	r2, [r3]						\n"
	"										\n"
	"	tst r14, #0x10						\n" /* Is the task using the FPU context?  If so, push high vfp registers. */
	"	it eq								\n"
	"	vstmdbeq r0!, {s16-s31}				\n"
	"										\n"
	"	stmdb r0!, {r4-r11, r14}			\n" /* Save the core registers. */
	"	str r0, [r2]						\n" /* Save the new top of stack into the first member of the TCB. */
	"										\n"
	"	stmdb sp!, {r0, r3}					\n"
	"	mov r0, %0 							\n"
	"	cpsid i								\n" /* Errata workaround. */
	"	msr basepri, r0						\n"
	"	dsb									\n"
	"	isb									\n"
	"	cpsie i								\n" /* Errata workaround. */
	"	bl vTaskSwitchContext				\n"
	"	mov r0, #0							\n"
	"	msr basepri, r0						\n"
	"	ldmia sp!, {r0, r3}					\n"
	"										\n"
	"	ldr r1, [r3]						\n" /* The first item in pxCurrentTCB is the task top of stack. */
	"	ldr r0, [r1]						\n"
	"										\n"
	"	ldmia r0!, {r4-r11, r14}			\n" /* Pop the core registers. */
	"										\n"
	"	tst r14, #0x10						\n" /* Is the task using the FPU context?  If so, pop the high vfp registers too. */
	"	it eq								\n"
	"	vldmiaeq r0!, {s16-s31}				\n"
	"										\n"
	"	msr psp, r0							\n"
	"	isb									\n"
	"										\n"
	#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
		#if WORKAROUND_PMU_CM001 == 1
	"			push { r14 }				\n"
	"			pop { pc }					\n"
		#endif
	#endif
	"										\n"
	"	bx r14								\n"
	"										\n"
	"	.align 4							\n"
	"pxCurrentTCBConst: .word pxCurrentTCB	\n"
	::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
	);
}

After debugging the code HardFault_Handler is triggered in instruction
vstmdbeq r0!, {s16-s31} as r0 is zero. r0 is set to have value of psp, which is also zero.

psp is getting the value in vPortSVCHandler, but xPortPendSVHandler is called before vPortSVCHandler.

When everything works ok we can see that vPortSVCHandler is called before xPortPendSVHandler .

Is there some configuration or other cause why would xPortPendSVHandler be called before vPortSVCHandler.

Thanks,
Petar Kovacevic

Welcome to the forum.
First, I have a few questions about your configuration.
Which CPU are you using? Could you share the initialization code you use to bring up FreeRTOS?

Second, a theory to check. Is it possible that you have an interrupt enabled that makes a FreeRTOS call and that interrupt is enabled before you have started the scheduler?

As you point out - this is the problem.

Many years ago (maybe 17 years ago!) one of the most common causes of support requests was interrupts trying to use the scheduler before the scheduler had started. To alleviate that we updated the code to leave the interrupts used by FreeRTOS masked between the application starting to use the FreeRTOS API (for example, to create a task), and starting the scheduler. In your case, as you are using a Cortex-M, masking the interrupts means keeping the BASEPRI register at a value that prevents the tick interrupt executing. Evidently that is not working in your case.

What is the BASEPRI value when you are in the SVC handler?

My immediate thought would be an interrupt priority configuration issue. Are you familiar with this page: RTOS for ARM Cortex-M ?

How many priority bits does your device have, and what are your configMAX_SYSCALL_INTERRUPT_PRIORITY and configKERNEL_INTERRUPT_PRIORITY settings?

Also, do you have configASSERT() defined? That will help. In the latest FreeRTOS versions (maybe 10.2.1 also) it will catch most misconfigurations.