Consider this:
int main()
{
Init();
vTaskStartScheduler();
}
SemaphoreHandle_t bar;
bool Init()
{
xTaskCreate(&fooBarTask,
"fooBar",
configMINIMAL_STACK_SIZE,
NULL,
1,
NULL);
bar = xSemaphoreCreateCounting(10, 3); //3 events immediately available
}
bool foo(TickType_t xTicksToWait)
{
//record time of entry
TimeOut_t xTimeOut;
vTaskSetTimeOutState( &xTimeOut );
//wait for 3 events and process them
for(size_t i = 0; i < 3; i++){
//wait for event
if(pdFALSE == xSemaphoreTake(bar, xTicksToWait)){ //if the event didn't come in time
return false; //signal failure
}
//process event
//...
//get remaining time allowance
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdTRUE ) //if we timed out
{
return false; //signal failure
}
}
return true; //signal success
}
void fooBarTask(void* pvParam)
{
bool OK = foo(0); //try to process 3 events or as many as immediately available
//OK will be false and only one event will be processed, even though 3 was available, no wait was needed, xTaskCheckForTimeOut incorrectly indicated a timeout
//...
}
All three necessary events for completing foo
without delay is immediately available, nonetheless xTaskCheckForTimeOut
will return pdTRUE
signaling a non-existent timeout.
Similar faults will occur for all cases where (xTickCount - pxTimeOut->xTimeOnEntering) == *pxTicksToWait
, such as the quiet typical xTickCount == pxTimeOut->xTimeOnEntering && *pxTicksToWait == 0
.
Just because the allowed time elapsed, that does not mean that there was a time out. It can very well be, that we are just in time to finish everything, which we can do, if everything is immediately available.
The documentation specifically says:
“If pdTRUE is returned then no block time remains, and a timeout has occurred.”
This is not the case though at present time. Right now it should read: If pdTRUE is returned then no block time remains
However, it should behave as the documentation suggest, otherwise it is of limited use…
So it is the function that requires fixing, not the documentation!