Describe the bug
If the targeted wake-up time is already in the past, i.e. xTaskDelayUntil( &previousWakeUpTime, xTimeIncrement ) == pdFALSE then previousWakeUpTime is incremented by the specied delay ticks, and goes out of sync with the actual ticks.
Target
To Reproduce
Call the function in a way that the specified deadline is missed.
Expected behavior
After a call to xTaskDelayUnitl(&previousWakeUpTime, xTimeIncrement ) the variable previousWakeUpTime holds the current ticks.
according to the functions documentation:
/**
* @param pxPreviousWakeTime Pointer to a variable that holds the time at which the
* task was last unblocked. The variable must be initialised with the current time
* prior to its first use (see the example below). Following this the variable is
* automatically updated within xTaskDelayUntil ().
*/
OR
The documentation clearly describes the current behavior.
Additional context
Relevant section in source code
|
xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; |
|
|
|
if( xConstTickCount < *pxPreviousWakeTime ) |
|
{ |
|
/* The tick count has overflowed since this function was |
|
* lasted called. In this case the only time we should ever |
|
* actually delay is if the wake time has also overflowed, |
|
* and the wake time is greater than the tick time. When this |
|
* is the case it is as if neither time had overflowed. */ |
|
if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) |
|
{ |
|
xShouldDelay = pdTRUE; |
|
} |
|
else |
|
{ |
|
mtCOVERAGE_TEST_MARKER(); |
|
} |
|
} |
|
else |
|
{ |
|
/* The tick time has not overflowed. In this case we will |
|
* delay if either the wake time has overflowed, and/or the |
|
* tick time is less than the wake time. */ |
|
if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) |
|
{ |
|
xShouldDelay = pdTRUE; |
|
} |
|
else |
|
{ |
|
mtCOVERAGE_TEST_MARKER(); |
|
} |
|
} |
|
|
|
/* Update the wake time ready for the next call. */ |
|
*pxPreviousWakeTime = xTimeToWake; |
/* Generate the tick time at which the task wants to wake. */
xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
/*...
Lines omitted for clarity
...*/
*pxPreviousWakeTime = xTimeToWake;
it is clear that the update of *pxPreviousWakeTime is the same irregardless of if the deadline is missed or not.
Example
This causes in the following example the previousWakeTime and xTaskGetTickCount() to diverge.
void exampleTaskFunction(void)
{
TickType_t previousWakeUpTime = xTaskGetTicks();
const TickType_t cDelayTicks = 5;
while(true)
{
vTaskDelay(10*cDelayTicks) /*Simple way to force a deadline miss*/
if(!xTaskDelayUntil(&previousWakeUpTime, cDelayTicks) )
{ /*Always true*/
assert(xTaskGetTicks() != previousWakeUpTime);
}
}
Describe the bug
If the targeted wake-up time is already in the past, i.e.
xTaskDelayUntil( &previousWakeUpTime, xTimeIncrement ) == pdFALSEthenpreviousWakeUpTimeis incremented by the specied delay ticks, and goes out of sync with the actual ticks.Target
To Reproduce
Call the function in a way that the specified deadline is missed.
Expected behavior
After a call to
xTaskDelayUnitl(&previousWakeUpTime, xTimeIncrement )the variablepreviousWakeUpTimeholds the current ticks.according to the functions documentation:
OR
The documentation clearly describes the current behavior.
Additional context
Relevant section in source code
FreeRTOS-Kernel/tasks.c
Lines 1231 to 1265 in 151fb04
it is clear that the update of
*pxPreviousWakeTimeis the same irregardless of if the deadline is missed or not.Example
This causes in the following example the
previousWakeTimeandxTaskGetTickCount()to diverge.