diff --git a/include/task.h b/include/task.h index 007900f2a..f35a8d703 100644 --- a/include/task.h +++ b/include/task.h @@ -3079,7 +3079,7 @@ void vTaskSetTaskNumber( TaskHandle_t xTask, * to date with the actual execution time by being skipped forward by a time * equal to the idle period. */ -void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; +void vTaskStepTick( TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; /* * Only available when configUSE_TICKLESS_IDLE is set to 1. diff --git a/tasks.c b/tasks.c index 88e699ca6..917b1986e 100644 --- a/tasks.c +++ b/tasks.c @@ -2592,12 +2592,34 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char * 1. */ #if ( configUSE_TICKLESS_IDLE != 0 ) - void vTaskStepTick( const TickType_t xTicksToJump ) + void vTaskStepTick( TickType_t xTicksToJump ) { /* Correct the tick count value after a period during which the tick * was suppressed. Note this does *not* call the tick hook function for * each stepped tick. */ configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); + + if( ( xTickCount + xTicksToJump ) == xNextTaskUnblockTime ) + { + /* Arrange for xTickCount to reach xNextTaskUnblockTime in + * xTaskIncrementTick() when the scheduler resumes. This ensures + * that any delayed tasks are resumed at the correct time. */ + configASSERT( uxSchedulerSuspended ); + configASSERT( xTicksToJump != ( TickType_t ) 0 ); + + /* Prevent the tick interrupt modifying xPendedTicks simultaneously. */ + taskENTER_CRITICAL(); + { + xPendedTicks++; + } + taskEXIT_CRITICAL(); + xTicksToJump--; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + xTickCount += xTicksToJump; traceINCREASE_TICK_COUNT( xTicksToJump ); } @@ -2616,7 +2638,13 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) /* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occurring when * the scheduler is suspended so the ticks are executed in xTaskResumeAll(). */ vTaskSuspendAll(); - xPendedTicks += xTicksToCatchUp; + + /* Prevent the tick interrupt modifying xPendedTicks simultaneously. */ + taskENTER_CRITICAL(); + { + xPendedTicks += xTicksToCatchUp; + } + taskEXIT_CRITICAL(); xYieldOccurred = xTaskResumeAll(); return xYieldOccurred;