From 1a500f1a7418588c4b3f88edd221891ee99d27cd Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:39:31 +0800 Subject: [PATCH] Support reset kernel state for restarting scheduler (#944) * Adding the following functions to reset kernel state. These functions are only required for application which needs to restart the scheduler. - void vTaskResetState( void ) - void vTimerResetState( void ) - void vPortHeapResetState( void ) - void vCoRoutineResetState( void ) --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Chris Morgan Co-authored-by: Soren Ptak Co-authored-by: Rahul Kar <118818625+kar-rahul-aws@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- croutine.c | 27 ++++++++++++++++-- include/croutine.h | 7 +++++ include/portable.h | 6 ++++ include/task.h | 14 ++++++++++ include/timers.h | 6 ++++ portable/MemMang/heap_1.c | 15 +++++++++- portable/MemMang/heap_2.c | 17 +++++++++++- portable/MemMang/heap_3.c | 12 ++++++++ portable/MemMang/heap_4.c | 24 +++++++++++++--- portable/MemMang/heap_5.c | 29 +++++++++++++++++--- tasks.c | 58 +++++++++++++++++++++++++++++++++++++++ timers.c | 12 ++++++++ 12 files changed, 215 insertions(+), 12 deletions(-) diff --git a/croutine.c b/croutine.c index daa88275f0..4d210b7321 100644 --- a/croutine.c +++ b/croutine.c @@ -52,8 +52,10 @@ /* Other file private variables. --------------------------------*/ CRCB_t * pxCurrentCoRoutine = NULL; - static UBaseType_t uxTopCoRoutineReadyPriority = 0; - static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + static UBaseType_t uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U; + static TickType_t xCoRoutineTickCount = ( TickType_t ) 0U; + static TickType_t xLastTickCount = ( TickType_t ) 0U; + static TickType_t xPassedTicks = ( TickType_t ) 0U; /* The initial state of the co-routine when it is created. */ #define corINITIAL_STATE ( 0 ) @@ -378,5 +380,26 @@ return xReturn; } +/*-----------------------------------------------------------*/ + +/* + * Reset state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ + void vCoRoutineResetState( void ) + { + /* Lists for ready and blocked co-routines. */ + pxDelayedCoRoutineList = NULL; + pxOverflowDelayedCoRoutineList = NULL; + + /* Other file private variables. */ + pxCurrentCoRoutine = NULL; + uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U; + xCoRoutineTickCount = ( TickType_t ) 0U; + xLastTickCount = ( TickType_t ) 0U; + xPassedTicks = ( TickType_t ) 0U; + } +/*-----------------------------------------------------------*/ #endif /* configUSE_CO_ROUTINES == 0 */ diff --git a/include/croutine.h b/include/croutine.h index 40ac9765b1..7888863e58 100644 --- a/include/croutine.h +++ b/include/croutine.h @@ -746,6 +746,13 @@ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, */ BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ); + +/* + * This function resets the internal state of the coroutine module. It must be + * called by the application before restarting the scheduler. + */ +void vCoRoutineResetState( void ) PRIVILEGED_FUNCTION; + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/include/portable.h b/include/portable.h index c4b350abfc..da1d7ad492 100644 --- a/include/portable.h +++ b/include/portable.h @@ -194,6 +194,12 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; #define vPortFreeStack vPortFree #endif +/* + * This function resets the internal state of the heap module. It must be called + * by the application before restarting the scheduler. + */ +void vPortHeapResetState( void ) PRIVILEGED_FUNCTION; + #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) /** diff --git a/include/task.h b/include/task.h index 69d61a7b46..33d9d4c071 100644 --- a/include/task.h +++ b/include/task.h @@ -3438,6 +3438,20 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, */ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; +/** + * task.h + * @code{c} + * void vTaskResetState( void ); + * @endcode + * + * This function resets the internal state of the task. It must be called by the + * application before restarting the scheduler. + * + * \defgroup vTaskResetState vTaskResetState + * \ingroup SchedulerControl + */ +void vTaskResetState( void ) PRIVILEGED_FUNCTION; + /*----------------------------------------------------------- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES diff --git a/include/timers.h b/include/timers.h index f526fdedd3..34dc406e45 100644 --- a/include/timers.h +++ b/include/timers.h @@ -1417,6 +1417,12 @@ BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer, #endif +/* + * This function resets the internal state of the timer module. It must be called + * by the application before restarting the scheduler. + */ +void vTimerResetState( void ) PRIVILEGED_FUNCTION; + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/portable/MemMang/heap_1.c b/portable/MemMang/heap_1.c index 19f695b200..93538362fa 100644 --- a/portable/MemMang/heap_1.c +++ b/portable/MemMang/heap_1.c @@ -64,7 +64,7 @@ #endif /* configAPPLICATION_ALLOCATED_HEAP */ /* Index into the ucHeap array. */ -static size_t xNextFreeByte = ( size_t ) 0; +static size_t xNextFreeByte = ( size_t ) 0U; /*-----------------------------------------------------------*/ @@ -150,3 +150,16 @@ size_t xPortGetFreeHeapSize( void ) { return( configADJUSTED_HEAP_SIZE - xNextFreeByte ); } + +/*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + xNextFreeByte = ( size_t ) 0U; +} +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_2.c b/portable/MemMang/heap_2.c index fffcb9ca3d..6f77f08692 100644 --- a/portable/MemMang/heap_2.c +++ b/portable/MemMang/heap_2.c @@ -113,6 +113,9 @@ PRIVILEGED_DATA static BlockLink_t xStart, xEnd; * fragmentation. */ PRIVILEGED_DATA static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; +/* Indicates whether the heap has been initialised or not. */ +PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE; + /*-----------------------------------------------------------*/ /* @@ -155,7 +158,6 @@ void * pvPortMalloc( size_t xWantedSize ) BlockLink_t * pxBlock; BlockLink_t * pxPreviousBlock; BlockLink_t * pxNewBlockLink; - PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE; void * pvReturn = NULL; size_t xAdditionalRequiredSize; @@ -384,3 +386,16 @@ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ pxFirstFreeBlock->pxNextFreeBlock = &xEnd; } /*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + + xHeapHasBeenInitialised = pdFALSE; +} +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_3.c b/portable/MemMang/heap_3.c index d174a57e9f..2240068e83 100644 --- a/portable/MemMang/heap_3.c +++ b/portable/MemMang/heap_3.c @@ -92,3 +92,15 @@ void vPortFree( void * pv ) ( void ) xTaskResumeAll(); } } +/*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + /* No state needs to be re-initialised in heap_3. */ +} +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_4.c b/portable/MemMang/heap_4.c index 507bf48b99..ea1e422dad 100644 --- a/portable/MemMang/heap_4.c +++ b/portable/MemMang/heap_4.c @@ -163,10 +163,10 @@ PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL; /* Keeps track of the number of calls to allocate and free memory as well as the * number of free bytes remaining, but says nothing about fragmentation. */ -PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; -PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; -PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; -PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; +PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U; /*-----------------------------------------------------------*/ @@ -608,3 +608,19 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats ) taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + pxEnd = NULL; + + xFreeBytesRemaining = ( size_t ) 0U; + xMinimumEverFreeBytesRemaining = ( size_t ) 0U; + xNumberOfSuccessfulAllocations = ( size_t ) 0U; + xNumberOfSuccessfulFrees = ( size_t ) 0U; +} +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_5.c b/portable/MemMang/heap_5.c index 18234626a0..4e14373930 100644 --- a/portable/MemMang/heap_5.c +++ b/portable/MemMang/heap_5.c @@ -187,10 +187,10 @@ PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL; /* Keeps track of the number of calls to allocate and free memory as well as the * number of free bytes remaining, but says nothing about fragmentation. */ -PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; -PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; -PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; -PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; +PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U; #if ( configENABLE_HEAP_PROTECTOR == 1 ) @@ -707,3 +707,24 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats ) taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vPortHeapResetState( void ) +{ + pxEnd = NULL; + + xFreeBytesRemaining = ( size_t ) 0U; + xMinimumEverFreeBytesRemaining = ( size_t ) 0U; + xNumberOfSuccessfulAllocations = ( size_t ) 0U; + xNumberOfSuccessfulFrees = ( size_t ) 0U; + + #if ( configENABLE_HEAP_PROTECTOR == 1 ) + pucHeapHighAddress = NULL; + pucHeapLowAddress = NULL; + #endif /* #if ( configENABLE_HEAP_PROTECTOR == 1 ) */ +} +/*-----------------------------------------------------------*/ diff --git a/tasks.c b/tasks.c index 6c399dbf5c..217cc62012 100644 --- a/tasks.c +++ b/tasks.c @@ -8694,3 +8694,61 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) */ /*-----------------------------------------------------------*/ + +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ +void vTaskResetState( void ) +{ + BaseType_t xCoreID; + + /* Task control block. */ + #if ( configNUMBER_OF_CORES == 1 ) + { + pxCurrentTCB = NULL; + } + #endif /* #if ( configNUMBER_OF_CORES == 1 ) */ + + #if ( INCLUDE_vTaskDelete == 1 ) + { + uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; + } + #endif /* #if ( INCLUDE_vTaskDelete == 1 ) */ + + #if ( configUSE_POSIX_ERRNO == 1 ) + { + FreeRTOS_errno = 0; + } + #endif /* #if ( configUSE_POSIX_ERRNO == 1 ) */ + + /* Other file private variables. */ + uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + uxTopReadyPriority = tskIDLE_PRIORITY; + xSchedulerRunning = pdFALSE; + xPendedTicks = ( TickType_t ) 0U; + + for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ ) + { + xYieldPendings[ xCoreID ] = pdFALSE; + } + + xNumOfOverflows = ( BaseType_t ) 0; + uxTaskNumber = ( UBaseType_t ) 0U; + xNextTaskUnblockTime = ( TickType_t ) 0U; + + uxSchedulerSuspended = ( UBaseType_t ) 0U; + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ ) + { + ulTaskSwitchedInTime[ xCoreID ] = 0U; + ulTotalRunTime[ xCoreID ] = 0U; + } + } + #endif /* #if ( configGENERATE_RUN_TIME_STATS == 1 ) */ +} +/*-----------------------------------------------------------*/ diff --git a/timers.c b/timers.c index a432e74c29..a3d0d0abe1 100644 --- a/timers.c +++ b/timers.c @@ -1322,6 +1322,18 @@ #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ +/* + * Reset the state in this file. This state is normally initialized at start up. + * This function must be called by the application before restarting the + * scheduler. + */ + void vTimerResetState( void ) + { + xTimerQueue = NULL; + xTimerTaskHandle = NULL; + } +/*-----------------------------------------------------------*/ + /* This entire source file will be skipped if the application is not configured * to include software timer functionality. If you want to include software timer * functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */