if(PIN_FPGA_DRDY_ID == id && PIN_FPGA_DRDY_MASK == mask)
{
xResult = xEventGroupSetBitsFromISR(xDigitalSensorFlag, 1, xHigherPriorityTaskWoken);
if( xResult != pdFAIL )
{
//analogue_acquisition_handler_xfer();
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a context
switch should be requested. The macro used is port specific and will
be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
the documentation page for the port being used. */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
}
}
Things Ive Tried
Interrupt Priority
Note that the fpga_handler is given a numerical priority of 6:
pio_handler_set_priority(PIN_FPGA_DRDY_PIO,(IRQn_Type)PIN_FPGA_DRDY_ID, 6);
Which is higher than: #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
If I make it lower it causes CONFIG ASSERT to be called so I’m fairly confident I have it the right way around.
Silly code by me
Can’t see any NULLs or anything that has not been initialised. i.e the xDigitalSensorFlag is the same address as its creation and structure members look good.
Reason why I’ve come here for help
The reason I think its in the FreeRTOS Kernel is that:
If I comment out the xEventGroupSetBitsFromISR no hardfault issue occurs.
The hardfault does not occur straight away. Stepping through it seems to happen when I next context switch which differs every time.
When I use the FreeRTOS viewer to see the state of the tasks its always running the “Tmr Svc”. Which is FreeRTOS’ internal task.
Any advice of what to try or any pointers would be appreciated.
Because xEventGroupSetBitsFromISR might need to walk a list to wake multiple tasks it doesn’t do the operation inside the ISR, but sends a message to the TmrSvc Task to have it do the operation as a task.
It might be that you have done something to make that task not work correctly, perhaps not giving it enough stack or having done something to corrupt some memory it is using.
I can see this being created correctly and given reasonable memory allocations, and two minutes later the interrupt fires and the variable contents are the same during the interrupt as it is on creation.
One thought I’ve had is that the receiving task (i.e where my xEventGroupWaitBits function is called) is called a fair bit (i.e quite an aggressive schedule) and could the interrupt and the task have some sort of collision? I don’t think the xDigitalSensorFlag needs a mutex protection but maybe something like that is the cause?
No, should not… Another thing to check for is the size of the startup stack which FreeRTOS reuses to run its ISRs on once the OS is launched. Maybe the stack is too small (I believe Richard Damon suggested something similar)? Normally the startup stack size is defined in your linker command file.
Thanks for the suggestion, I wouldn’t have thought about that. I have increased the stack and no difference but I’ll investigate other things to negate the TmrSvc as the cause of the issue.
So it looks like the issue may have been solved through increasing the stack size of the Receiving task (i.e where my xEventGroupWaitBits function is called).
Maybe it worked before as the stack corruption occurred but the TmrSvc code wasn’t called. But now with an fromISR function executed. The TmrSvc now executes a few more co-routines (this is what Richard mentions) and uses the corrupted area.
Or increasing the stack size has just moved the problem elsewhere.
Either way its a stack issue and not a freertos issue, so I would like to thank you both for your help.