Context switching issue with ARM cortex M4 device


I have TI Cortex M4 controller. I have an Ethernet ISR that is working fine and no issues when it performs context switching by calling vTaskNotifyGiveFromISR(xEMACTaskHandle, &xHigherPriorityTaskWoken); and then portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

However I am struggling with configuring another Interrupt handler.
I am trying to call that same task handler as mentioned above i.e. xEMACTaskHandle whenever the Timer0 Interrupt handler is triggered.
Please see the image bellow;

The issue is when the Timer0 interrupt handler is triggered, it would reach out to vTaskNotifyGiveFromISR(xEMACTaskHandle, &xHigherPriorityTaskWoken); and from there it would go to configASSERT( xTaskToNotify ); and which will ASSERT and end up in calling void vAssertCalled( const char *pcFile, uint32_t ulLine ).

One thing you may notice the xEMACTaskHandle is holding 0x00.

Now, if I debug same code at a breakpoint for the Ethernet ISR handler (keep in mind Ethernet ISR handler is working fine and I am using it for comparison purpose), you may notice the xEMACTaskHandle is holding 0x20006280 and the context switching happens successfully.
See image bellow for the Good context switching in case of Ethernet ISR handler.

I am not sure what could be wrong with Timer0 Interrupt handler ?
The xEMACTaskHandle is defined bellow;

TaskHandle_t xEMACTaskHandle;

Ethernet ISR Handler and Timer0 Interrupt priority is defined as;


where configETHERNET_INT_PRIORITY is defined in FreeRTOSConfig.h as shown bellow;

/* Be ENORMOUSLY careful if you want to modify these two values and make sure
 * you read first!
#define configKERNEL_INTERRUPT_PRIORITY         ( 7 << 5 )  /* Priority 7, or 0xE0 as only the top three bits are implemented.  This is the lowest priority. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( 5 << 5 )  /* Priority 5, or 0xA0 as only the top three bits are implemented. */

#define configETHERNET_INT_PRIORITY             ( 6 << 5 )  /* Priority 6, or 0xC0 as only the top three bits are implemented. */

#define configTIMER_TASK_PRIORITY               ( 3 )

I am thinking of following two possible reasons for the issue;

The xEMACTaskHandle is 0x000000 in case when vTaskNotifyGiveFromISR(xEMACTaskHandle, &xHigherPriorityTaskWoken); is called from Timer0 ISR and it would be 0x20006280 when it is called from Ethernet ISR. But why it is 0x000000 in case of Timer0 ISR ?

Or It could be interrupt priority related ? If yes what should be the value for MAP_IntPrioritySet(INT_TIMER0A, configETHERNET_INT_PRIORITY+1);

I thank you for your time and cooperation.

I rather think that the task wasn‘t successfully created when the timer interrupt occurs. Or in other words the timer interrupt is armed too early. Ensure that all FreeRTOS resources like the handler task etc. are created before enabling the interrupts you want to handle using FreeRTOS API like it’s done right with the ethernet interrupt.

1 Like

I just moved the line that enables Timer0 Interrupt Timer0Enable(); inside a FreeRTOS task, so that once everything is setup the task will enable Timer0. However, I still see same issue i.e. xEMACTaskHandle reads 0x0000.

Going off @hs2’s idea which matches my initial thought that the task was somehow not created…

I just moved the line that enables Timer0 Interrupt Timer0Enable(); inside a FreeRTOS task,

This task creation occurs after the xEMACTaskHandle task is created, right? It would be helpful to know the order of task creation + timer creations.

1 Like


So it turned out to be both issues as I was guessing in my thread i.e.

  1. The xEMACTaskHandle was holding 0x00000. And Yes @hs2 was very right. However when I moved the Timer0Enable(); inside a task, it would still not work. This brought it down to the 2nd problem as mentioned in my post related to the interrupt priority.
  2. I changed the interrupt priority for Timer0 and it is now working as expected.

Thank you for your help. @hs2 and @kstribrn . You have a good one.