zachmetzinger wrote on Wednesday, May 04, 2016:
vTaskSwitchContext is called
By what? Is this the idle task calling taskYIELD()?
Yes, in the (configUSE_PREEMPTION == 0) block, taskYIELD() is being called.
The scheduler is not suspended, so the else case is taken, and this function exits
…so presumably when it exits it returns to the Idle task, so no context switch was performed. Is that correct?
Correct. According to my trace, the next bit of code that runs after vTaskSwitchContext is xTaskIncrementTick, which then resumes execution within the idle task before TickType_t xExpectedIdleTime.
xNextTaskUnblockTime = portMAX_DELAY;
Presumably because there are no tasks in the Blocked state. At this point do you just have the Idle task and the task that was unblocked in the tick interrupt executing?
Yes, only the idle task and the task just unblocked.
If the Idle task is still running is it right that the task that was unblocked by the tick interrupt is also running at the idle priority?
The “other” task, which is not the idle task, is called ‘Task1’. It has tskIDLE_PRIORITY+1.
…or if the task that unblocked has a priority above the idle priority (in which case the idle task should not even be executing):
Task1 was suspended for 500ms, which expired, and it was put on the pxReadyTasksLists[tskIDLE_PRIORITY+1] list. However, the scheduler did not switch to it, so the idle task carried along and tried to sleep. This only happens when configSYSTICK_CLOCK_HZ is defined – it has the value 32768. If this is not defined and the CPU clock is also SYSTICK clock, this condition does not happen. I believe it to be a race condition exacerbated by the slow SysTick clock.
What do you have the configUSE_PORT_OPTIMISED_TASK_SELECTION and configEXPECTED_IDLE_TIME_BEFORE_SLEEP set to?
I’m using the default GCC/ARM_CM4F/portmacro.h defines.
/* Architecture specific optimisations. */
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#endif
#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
#endif