Hello!
I am currently working with both FreeRTOS 9 and 10, and have uncovered something that I suspect is a bug concerning the global variable “xNumOfOverflows” defined and managed by tasks.c.
During tick increments in:
BaseType_t xTaskIncrementTick( void )
I notice that there is very explicit handling for overflow detection.
if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */
{
taskSWITCH_DELAYED_LISTS();
}
This macro appears to be the only location that increments the overflow counter; however, it’s not the only place where the overflow counter is used.
#define taskSWITCH_DELAYED_LISTS() \
{ \
List_t *pxTemp; \
\
/* The delayed tasks list should be empty when the lists are switched. */ \
configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \
\
pxTemp = pxDelayedTaskList; \
pxDelayedTaskList = pxOverflowDelayedTaskList; \
pxOverflowDelayedTaskList = pxTemp; \
xNumOfOverflows++; \
prvResetNextTaskUnblockTime(); \
}
I cannot find evidence that tickless idle is taking the same care to detect and increment xNumOfOverflows.
void vTaskStepTick( const TickType_t xTicksToJump )
{
/* Correct the tick count value after a period during which the tick
was suppressed. Note this does *not* call the tick hook function for
each stepped tick. */
configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime );
xTickCount += xTicksToJump;
traceINCREASE_TICK_COUNT( xTicksToJump );
}
It looks like xTickCount is just naively incrementing by ticks.
Other than what may be going on in the kernel due to xNumOfOverflows potentially being inaccurate, it also calls in the question of whether the following function is safe to use.
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut )
{
/* For internal use only as it does not use a critical section. */
pxTimeOut->xOverflowCount = xNumOfOverflows;
pxTimeOut->xTimeOnEntering = xTickCount;
}
Have I uncovered a situation where overflow is incorrectly being handled when in tickless idle? If not, can some explanation be provided to explain what I may be missing?