Inside the function “prvProcessTimerOrBlockTask ()”,
after the function “vTaskSuspendAll()”,
called “prvSampleTimeNow()”.
Inside it can happen the function callback “pxTimer->pxCallbackFunction((TimerHandle_t) pxTimer)”.
It turns out that the callback function can block higher priority tasks.
Your question is not completely clear, but I will try and answer it.
pxCallbackFunction() is the software timer callback function - but it is just a C function being called from an RTOS task (in this case the Timer task http://www.freertos.org/RTOS-software-timer.html) so it can do the same as any other C function being called from a task. Generally, it can unblock a higher priority task, but it can’t really block a higher priority task. It can suspend a higher priority task, but that is a different thing.
Timer call back functions are called in the contex of the Timer task, which is high priority (I think the highest allowed), not the task that setup the time. Thus timer call backs will have higher priority than your moderate to sort of high priority tasks.
Function call “pxTimer->pxCallbackFunction((TimerHandle t) pxTimer)” stands between vTaskSuspendAll() and xTaskResumeAll().
If inside ISR will be called xTaskResumeFromISR () for more priority than the “Timer task”,
a context switch is blocked (vTaskSuspendAll()) while there is a execution the callback function. additional delay of switching.
it turns out you can not make the task more priority than “Timer task”?
You can make a task have a higher priority by changing the definition of configTIMER_TASK_PRIORITY which lives in FreeRTOSConfig.h
What you can’t do is force a task switch during a vTaskSuspendAll() block.
Looking at the code know, I see a
vTaskSuspendAll() call,
a test to see if we need to call the timer call back
vTaskResumeAll() call, then
prvPrcessExpiredTimer() call which will call pxTimer->psCallbackFunction()
so I don’t see the call back in the context of a SuspendAll() (it may be this is a recent change)
I think the path you are highlighting is a corner case that, although we
have tests to go through it, is very unlikely to be hit in a real
application. To execute that line you need to be in a situation whereby
the tick count has overflowed && for some reason there are timers in the
‘current’ timer list that have not been processed (maybe could occur if
there was a timer that expired as the tick count overflowed)
Even if that line was executed I don’t think it should cause a problem
as callback functions should not attempt to block, and if the callback
function resulted in a context switch then the context switch would just
be held pending and then performed when the scheduler was resumed.
unlikely, but possible. especially when using configUSE_16_BIT_TICKS - often overflows tickcount. it forces to take into account the execution of a callback function to meet real-time.
Why not put “xTimeNow = prvSampleTimeNow (& xTimerListsWereSwitched); (line 457)” before vTaskSuspendAll () (line 450)? It seems that it solves the problem.