Hi!
I have been chasing a crash for the past weeks and I’m hoping to get some help here. My problem is that I’m getting a usage-fault upon returning from the xPortPendSVHandler after I sent a notification from an ISR. I’m running this on an XMC4800, using the ARM-GCC port. I managed to reduce it to the example below:
#include "FreeRTOS.h"
#include "task.h"
#include "XMC4800.h"
#include "core_cm4.h"
// the specific vector is not important, just that the notifications comes from an IRQ
static const IRQn_Type irq_n = SCU_0_IRQn;
static TaskHandle_t waiting_task, trigger_task;
void Error_Handler() { while (1) {} }
void HardFault_Handler() { Error_Handler(); }
void MemManage_Handler() { Error_Handler(); }
void BusFault_Handler() { Error_Handler(); }
void UsageFault_Handler() { Error_Handler(); }
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { Error_Handler(); }
void SCU_0_IRQHandler() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(waiting_task, 1, eSetBits, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} // UsageFault after returning from xPortPendSVHandler
void my_waiting_task(void *unused) {
uint32_t notification = 0;
// crash occurs only if task is blocked
xTaskNotifyWait(0, 0xFFFFFFFF, ¬ification, portMAX_DELAY);
while (1) {}
}
// not strictly necessary, original project had the interrupt coming in from hardware
void my_trigger_task(void *unused) {
NVIC_SetPendingIRQ(irq_n);
while (1) {}
}
int main() {
xTaskCreate(
my_waiting_task, "Waiting Task", 512,
NULL, 2, &waiting_task
); // higher priority, so it is blocked by the time the notification arrives
xTaskCreate(
my_trigger_task, "Trigger Task", 512,
NULL, 1, &trigger_task
);
// IRQ must be less important than any FreeRTOS IRQs, since it uses the FreeRTOS API
// watch out for ARM Cortex priority pitfalls (inverted numerical priority)
NVIC_SetPriority(irq_n, configMAX_SYSCALL_INTERRUPT_PRIORITY + 10);
NVIC_EnableIRQ(irq_n);
vTaskStartScheduler();
return 0;
}
As far as I can see, I’m not doing anything wrong or unusual. I’m using the ISR-safe API calls, I’m yielding at the end of it, I’m aware of the pitfalls with ISR priorities on CM4s. I have updated FreeRTOS to the latest LTS-version, including the ARM-GCC-port, got a fresh FreeRTOSConfig.h
, updated CMSIS & XMCLib, updated to the latest GCC-ARM toolchain. I am far away from a stackoverflow, assertions are of course enabled. This was orignally running on a custom board, I have since moved to the XMC48 Relax Kit from Infineon, which reproduces the same problem.
When I break inside the PendSVHandler, just before the return, the stack looks like so:
0x1ffe87a0 | 24 9a fe 1f fd ff ff ff 01 00 00 00 01 00 00 00
0x1ffe87b0 | 00 00 00 10 04 ed 00 e0 a5 a5 a5 a5 4f 19 00 08
0x1ffe87c0 | 36 09 00 08 10 00 00 21 00 00 00 00 d4 87 fe 1f
0x1ffe87d0 | c8 91 fe 1f 01 00 00 00 74 9a fe 1f fd ff ff ff
0x1ffe87e0 | 00 00 00 00 00 00 f0 00 34 ef 00 e0 00 00 00 c0
0x1ffe87f0 | 00 00 00 00 e7 2d 00 08 c8 2c 00 08 00 00 00 61
...
Here, $sp = 0x1ffe87a4
. The address at 0x1ffe87bc
lies inside vPortValidateInterruptPriority
, the one after lies at the end of my interrupt. From my (very limited) understanding, this looks fine as well. At least I can’t make out a difference to any other working case.
Some final notes:
- The port mentions a workaround for XMC4000 specific errata, namely
WORKAROUND_PMU_CM001
. It replacesbx lr
with push & pop. I’m somewhat confused by that, my errata sheet mentionsCPU_CM.001
but that adresses interrupted loads for$sp
, not$pc
. Either way, the workaround does not influence the outcome. - The
FreeRTOSConfig.h
had an unused#define xPortPendSVHandler PendSV_Handler_Veneer
, hidden behind anENABLE_CPU_CM_001_WORKAROUND
. I could not find any reference to that, except for an old forum post, which didn’t really clear things up for me. - For some reason, if I step over the
PendSVHandler
with my debugger, everythong works just fine. If I let it run without it, or even if I single-step the assembly, it crashes…
Thanks for reading so far, I appreciate your help