代码如下:关注点标注为红色,标记为 再继续分析-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();
}
}