mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 20:24:32 +02:00
fix(freertos): Fixed tickless idle tick count accounting
This commit fixes an issue where the FreeRTOS kernel does not account for the pended ticks occuring during automatic light-sleep mode and hence causing a jump in the tick count at a later stage in the application lifetime. Closes: https://github.com/espressif/esp-idf/issues/15642
This commit is contained in:
@@ -3063,19 +3063,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char
|
|||||||
/* Arrange for xTickCount to reach xNextTaskUnblockTime in
|
/* Arrange for xTickCount to reach xNextTaskUnblockTime in
|
||||||
* xTaskIncrementTick() when the scheduler resumes. This ensures
|
* xTaskIncrementTick() when the scheduler resumes. This ensures
|
||||||
* that any delayed tasks are resumed at the correct time. */
|
* that any delayed tasks are resumed at the correct time. */
|
||||||
#if ( configNUMBER_OF_CORES > 1 )
|
configASSERT( taskIS_SCHEDULER_SUSPENDED() == pdTRUE );
|
||||||
{
|
|
||||||
/* In SMP, the entire tickless idle handling block
|
|
||||||
* is replaced with a critical section, taking the kernel lock. */
|
|
||||||
configASSERT( taskIS_SCHEDULER_SUSPENDED() == pdFALSE );
|
|
||||||
}
|
|
||||||
#else /* configNUMBER_OF_CORES > 1 */
|
|
||||||
{
|
|
||||||
/* In single-core, the entire tickless idle handling block
|
|
||||||
* is done with scheduler suspended. */
|
|
||||||
configASSERT( taskIS_SCHEDULER_SUSPENDED() == pdTRUE );
|
|
||||||
}
|
|
||||||
#endif /* configNUMBER_OF_CORES > 1 */
|
|
||||||
configASSERT( xTicksToJump != ( TickType_t ) 0 );
|
configASSERT( xTicksToJump != ( TickType_t ) 0 );
|
||||||
|
|
||||||
xPendedTicks++;
|
xPendedTicks++;
|
||||||
@@ -4369,31 +4357,37 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
|
|||||||
|
|
||||||
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
|
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
|
||||||
{
|
{
|
||||||
prvENTER_CRITICAL_OR_SUSPEND_ALL( &xKernelLock );
|
/* In SMP mode, the entire tickless idle handling block
|
||||||
|
* must be done with the kernel lock held. */
|
||||||
|
prvENTER_CRITICAL_SMP_ONLY( &xKernelLock );
|
||||||
{
|
{
|
||||||
/* Now the scheduler is suspended, the expected idle
|
vTaskSuspendAll();
|
||||||
* time can be sampled again, and this time its value can
|
|
||||||
* be used. */
|
|
||||||
configASSERT( xNextTaskUnblockTime >= xTickCount );
|
|
||||||
xExpectedIdleTime = prvGetExpectedIdleTime();
|
|
||||||
|
|
||||||
/* Define the following macro to set xExpectedIdleTime to 0
|
|
||||||
* if the application does not want
|
|
||||||
* portSUPPRESS_TICKS_AND_SLEEP() to be called. */
|
|
||||||
configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime );
|
|
||||||
|
|
||||||
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
|
|
||||||
{
|
{
|
||||||
traceLOW_POWER_IDLE_BEGIN();
|
/* Now the scheduler is suspended, the expected idle
|
||||||
portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
|
* time can be sampled again, and this time its value can
|
||||||
traceLOW_POWER_IDLE_END();
|
* be used. */
|
||||||
}
|
configASSERT( xNextTaskUnblockTime >= xTickCount );
|
||||||
else
|
xExpectedIdleTime = prvGetExpectedIdleTime();
|
||||||
{
|
|
||||||
mtCOVERAGE_TEST_MARKER();
|
/* Define the following macro to set xExpectedIdleTime to 0
|
||||||
|
* if the application does not want
|
||||||
|
* portSUPPRESS_TICKS_AND_SLEEP() to be called. */
|
||||||
|
configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||||
|
|
||||||
|
if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
|
||||||
|
{
|
||||||
|
traceLOW_POWER_IDLE_BEGIN();
|
||||||
|
portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
|
||||||
|
traceLOW_POWER_IDLE_END();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
}
|
}
|
||||||
( void ) prvEXIT_CRITICAL_OR_RESUME_ALL( &xKernelLock );
|
prvEXIT_CRITICAL_SMP_ONLY( &xKernelLock );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user