Hi Team,
I am facing a random HardFault issue on an S32K358 running FreeRTOS.
The application runs normally for a long duration and then suddenly hangs. After the system stops executing, the Software Watchdog (SWT) is not serviced and eventually resets the controller.
The failure is not immediate—it occurs after approximately 1 to 2 hours of continuous execution
When halted after the failure, the call stack shows:
PendSV_Handler()
↓
HardFault_Handler()
Register values:
LR = 0xA5A5A5A5
PC = 0x00407BD9
Other registers:
R0 = 0x204011A8
R3 = 0x2040012C
R12 = 0x20400010
Any suggestions or debugging recommendations would be greatly appreciated.
It looks like the task context saved during the FreeRTOS context switch has been corrupted.
PendSV is used by FreeRTOS for context switching, therefore, if the HardFault occurs inside PendSV_Handler(), it often means the scheduler is attempting to restore an invalid task context.
One possible root cause is a task stack overflow. I would recommend increasing the stack size of the tasks and enabling FreeRTOS stack overflow detection:
configCHECK_FOR_STACK_OVERFLOW
Implement: vApplicationStackOverflowHook().
Additionally, you can periodically monitor the remaining stack space of each task using uxTaskGetStackHighWaterMark(). This can help identify tasks that are running close to their stack limits before the fault occurs.
Regards,
Daniel
Hello @danielmartynek ,
Thank you for response,
I already tried increased stack size, enabled stack overflow hook.
Added debug CAN msg in overflow hook, I am not receiving that message when fault occur.
Also monitoring uxTaskGetStackHighWaterMark(), when fault occur
Task 1 : 1977 × 4 ≈ 7908 bytes free
Task 2: 1971 × 4 ≈ 7884 bytes free
Task 3: 3988 × 4 ≈ 15952 bytes free
So we can probably exclude a stack overflow as the root cause.
However, the task context is still getting corrupted. The processor is restoring LR = 0xA5A5A5A5, which results in a UsageFault. 0xA5A5A5A5 is the pattern generated from tskSTACK_FILL_BYTE (0xA5U) and is used by FreeRTOS to fill task stacks when they are created.
Therefore, if LR becomes 0xA5A5A5A5, the context is restored from a location that still contains the original stack fill pattern rather than a valid register value.
This could happen if the SP gets corrupted. In that case, PendSV_Handler() would restore the task context from a wrong location in RAM.
You should be able to identify the SRAM region from the stack pointer address.
I would recommend that you properly protect the region by MPUs and XRDC.
Also, are any interrupts calling FreeRTOS APIs? If so, are they using the FromISR() variants, and are their priorities configured correctly with respect to configMAX_SYSCALL_INTERRUPT_PRIORITY?
Regards,
Daniel