Если задача входит в состояние Blocked и выходит из него больше одного раза, то бывает нужно подстроить время таймаута таким образом, чтобы время, затраченное в состоянии Blocked, не превышало изначального запланированного значения. Функция xTaskCheckForTimeOut() выполняет такую настройку, учитывая случаи переполнения счетчика тиков. Ручная настройка таймаута может привести к слишком большой ошибке.
Возвратит pdTRUE, если не осталось времени блокировки, произошел таймаут. Иначе будет возвращено pdFALSE - осталось некоторое время блокировки, и таймаут не произошел.
/* Библиотечная функция драйвера используется для приема uxWantedBytes из
буфера Rx, который заполняется прерыванием UART. Если в буфере недостаточно
байт, то задача входит в состояние Blocked до тех пор, пока не поступит
оповещение, что в буфер помещено больше данных. Если данных все еще
недостаточно, то задача снова войдет в состояние Blocked, и функция
xTaskCheckForTimeOut() используется в пересчете времени блокировки
для гарантии, чтобы общее время, которое задача проводит в состоянии
Blocked, не превышало MAX_TIME_TO_WAIT. Это продолжается до тех пор,
пока в буфере не окажется как минимум uxWantedBytes байт, или общее
количество времени, потраченное на состояние Blocked, достигло значения
MAX_TIME_TO_WAIT. */
size_t xUART_Receive (uint8_t *pucBuffer, size_t uxWantedBytes)
{
size_t uxReceived = 0;
TickType_t xTicksToWait = MAX_TIME_TO_WAIT;
TimeOut_t xTimeOut;
/* Инициализируется xTimeOut. Это действие записывает время, на
котором был вход в функцию. */
vTaskSetTimeOutState( &xTimeOut );
/* Цикл, пока в буфере не окажется желаемое количество байт, или
пока не произойдет таймаут. */
while (UART_bytes_in_rx_buffer(pxUARTInstance) < uxWantedBytes)
{
/* В буфере недостаточно данных, поэтому задача входит в состояние
Blocked. Подстраивается xTicksToWait для учета любого времени,
потраченного в состоянии Blocked на этой функции, чтобы общее
время, потраченное в состоянии Blocked, не превышало
MAX_TIME_TO_WAIT. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) != pdFALSE )
{
/* Таймаут до того, как стало доступным желаемое количество
байт, выход из цикла. */
break;
}
/* Ожидание максимум xTicksToWait для получения оповещения,
что прерывание приема поместило больше данных в буфер. */
ulTaskNotifyTake( pdTRUE, xTicksToWait );
}
/* Попытка чтения uxWantedBytes из буфера приема в буфер pucBuffer.
Будет возвращено реальное количество прочитанных байт (которое
может быть меньше чем uxWantedBytes). */
uxReceived = UART_read_from_receive_buffer (pxUARTInstance,
pucBuffer,
uxWantedBytes);
return uxReceived;
}