Task stuck in ready state on cortex-M33

Hi,

The cause of problem is exactly the same with

We both use Cortex-M33 core and here’s the implementation of sys tick irq:

void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION /
{
uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
/
Increment the RTOS tick. /
if( xTaskIncrementTick() != pdFALSE )
{
/
Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
}

Although Sys tick irq suspends task scheduler, it is not run under critical section which can be interrupted by a higher IRQ(i2c irq). The problem is exactly the same as described by Yueming:

configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is performed in a generic way. There might be a racing condition on uxTopReadyPriority.
Please check this failed case:

  1. Tick IRQ is a low priority IRQ.
  2. When Tick IRQ finished this line “UBaseType_t uxTopPriority = uxTopReadyPriority;” , let’s assume uxTopReadyPriority and uxTopPriority is 5 now.
    {
    ==> UBaseType_t uxTopPriority = uxTopReadyPriority;
    /* Find the highest priority queue that contains ready tasks. /
    while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) )
    {
    configASSERT( uxTopPriority );
    –uxTopPriority;
    }
    /
    listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of
  3. the same priority get an equal share of the processor time. /
    listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) );
    uxTopReadyPriority = uxTopPriority;
    } /
    taskSELECT_HIGHEST_PRIORITY_TASK */
  4. A higher priority IRQ occurs, tick IRQ is switched out. The higher priority IRQ adds a ready task into the ready list and sets uxTopReadyPriority to this task’s priority, let’s assume it is 6.
  5. The higher priority IRQ finished and tick IRQ contine it’s code. uxTopReadyPriority will be set to a value <= 5.
  6. The task scheduler cannot call priority 6 task on next tick IRQ. That would cause some issues.

uxTopReadyPriority is written twice and the last time it is written by tick IRQ and set as the priority of idle task. If I use taskSELECT_HIGHEST_PRIORITY_TASK(), the task scheduler will only check the ready list for priority 0(idle task).Unless there is another task trigger event that rewrite uxTopReadyPriority back to the overridden value, the task will always be stuck in ready list and never run.

Therefore, my solution is to abandon uxTopReadyPriority and taskSELECT_HIGHEST_PRIORITY_TASK(). I instead search all the ready list. Since there are not too many tasks, the cost is affordable. And the porblem is solved in this way.