romainht wrote on Thursday, January 25, 2018:
Hello everyone,
we are currently using FreeRTOS on a Blackfin processor and facing an issue when releasing a high-priority task from ISR. We may have made a mistake during porting but are unable to find where. I found several topics linked to this issue (uxTopReadyPriority variable in particular) but still do not understand the problem.
We have the following config :
configUSE_PREEMPTION = 1
configUSE_PORT_OPTIMISED_TASK_SELECTION = 0
We have sereral tasks running at low priority (3) and one task running at higher priority (5).
In the context switching interrupt subroutine (lowest IRQ priority), we call vTaskSwitchContext after enabling interrupts again, thus taskSELECT_HIGHEST_PRIORITY_TASK is called with interrupts on.
What we see
While we are in vTaskSwitchContext, we enter taskSELECT_HIGHEST_PRIORITY_TASK. At that time, the high-priority task is asleep and uxTopReadyPriority=3. uxTopPriority is loaded with this value.
At that point, an IRQ is triggered (priority higher than task switching ISR but lower than configMAX_SYSCALL_INTERRUPT_PRIORITY) and it calls sys_semaphore_releaseISR to release the high-priority task.
sys_semaphore_releaseISR calls xQueueGiveFromISR -> xTaskRemoveFromEventList -> prvAddTaskToReadyList -> taskRECORD_READY_PRIORITY and finally uxTopReadyPriority is set to 5.
When we are back in the context switching subroutine, we are still in taskSELECT_HIGHEST_PRIORITY_TASK and have uxTopPriority=3. We run the “uxTopReadyPriority = uxTopPriority;” command, that sets uxTopReadyPriority to 3 back again. As a result, the high-priority task will never be executed.
Thus, did we made a mistake with our interrupt priorities ? Is it a normal bahaviour that a task can call FromISR functions while the task switching interrupt is in taskSELECT_HIGHEST_PRIORITY_TASK ?
Task switching interrupt | Other interrupt |
---|---|
vTaskSwitchContext | |
taskSELECT_HIGHEST_PRIORITY_TASK |
UBaseTypet uxTopPriority = uxTopReadyPriority;
| sys_semaphore_releaseISR
| xQueueGiveFromISR
| xTaskRemoveFromEventList
|prvAddTaskToReadyList
| taskRECORD_READY_PRIORITY
| uxTopReadyPriority=5
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) |
… |
uxTopReadyPriority = uxTopPriority; |
Thanks for any comment that would help us understand how this should work.
Romain