-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
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
- All
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
Lines 1231 to 1265 in 151fb04
| 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);
}
}