代碼如下:關注點標注為紅色,標記為 再繼續分析-20181108
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
{
TickType_t xTimeToWake;
BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;
{
TickType_t xTimeToWake;
BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;
configASSERT( pxPreviousWakeTime );
configASSERT( ( xTimeIncrement > 0U ) );
configASSERT( uxSchedulerSuspended == 0 );
configASSERT( ( xTimeIncrement > 0U ) );
configASSERT( uxSchedulerSuspended == 0 );
vTaskSuspendAll();
{
/* Minor optimisation. The tick count cannot change in this
block. */
const TickType_t xConstTickCount = xTickCount;
{
/* Minor optimisation. The tick count cannot change in this
block. */
const TickType_t xConstTickCount = xTickCount;
/* Generate the tick time at which the task wants to wake. */
xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
xTimeToWake = *pxPreviousWakeTime + xTimeIncrement;
/* 當前系統tick小於上次上次wakeup的時間點,即:當前系統tick計數發生了反轉 */
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. */
{
/* 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. */
/* xTimeToWake < *pxPreviousWakeTime,表示 待喚醒時間點 是指反轉后的時間點
xTimeToWake > xConstTickCount,表示 待喚醒時間點 比當前系統tick滯后,即 喚醒時間尚未到 */
if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
{
xShouldDelay = pdTRUE;
}
if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) )
{
xShouldDelay = pdTRUE;
}
/* xTimeToWake > *pxPreviousWakeTime,表示 待喚醒時間點 是指未反轉的時間點
xTimeToWake > xConstTickCount,表示 因系統tick未反轉,自然xTimeToWake應該比xCounstTickCount大
此種情況,也應該是要延遲的吧,為什么代碼中沒有體現到,是我分析不到位么? 標記,后續繼續查看 */
else if ( (xTimeToWake > *pxPreviousWakeTime) && ( xTimeToWake > xConstTickCount) )
{
/* xShouldDelay = pdTRUE;
該條件自行添加,不知合適否,需繼續分析,留爪*/
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/* 當前系統tick 大於/等於 上次wakeup的時間點,即:當前系統tick計數未發生反轉 */
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. */
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. */
/* 條件1:xTimeToWake < *pxPreviousWakeTime 表示系統tick未反轉,但待喚醒時間點發生反轉,即 喚醒時間未到
此條件下,xTimeToWake發生了反轉,而xConstTickCount未發生反轉,則
xTimeToWake - xConstTickCount可能是負數 【位置1】
條件2:xTimeToWake > xConstTickCount,結合xConstTickCount >= *pxPreviousWakeTime,即 喚醒時間未到
此條件下,xTimeToWake - xConstTickCount一定是非負的 */
if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) )
{
xShouldDelay = pdTRUE;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) )
{
xShouldDelay = pdTRUE;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/* Update the wake time ready for the next call. */
*pxPreviousWakeTime = xTimeToWake;
*pxPreviousWakeTime = xTimeToWake;
if( xShouldDelay != pdFALSE )
{
traceTASK_DELAY_UNTIL( xTimeToWake );
{
traceTASK_DELAY_UNTIL( xTimeToWake );
/* prvAddCurrentTaskToDelayedList() needs the block time, not
the time to wake, so subtract the current tick count. */
the time to wake, so subtract the current tick count. */
/* 此處,要求xTimeToWake - xConstTickCount必須非負數,但【位置1】就無法保證,如何解決的?后續繼續分析 */
prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
xAlreadyYielded = xTaskResumeAll();
prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
xAlreadyYielded = xTaskResumeAll();
/* Force a reschedule if xTaskResumeAll has not already done so, we may
have put ourselves to sleep. */
if( xAlreadyYielded == pdFALSE )
{
portYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
have put ourselves to sleep. */
if( xAlreadyYielded == pdFALSE )
{
portYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}