diff --git a/croutine.c b/croutine.c index daa88275f01..264587d74ab 100644 --- a/croutine.c +++ b/croutine.c @@ -378,5 +378,32 @@ return xReturn; } +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + +/* + * Re-initialise internal variables in this file. FreeRTOS doesn't implement an init + * function. Some of the internal variables need to be initialised at declaration + * time. This function is added and only required for application needs to restart + * the FreeRTOS scheduler ( for example to restart the scheduler for each test case + * when running with a test framework ). + */ + void vCoRoutineReinitialiseVariables( void ) + { + /* Lists for ready and blocked co-routines. */ + pxDelayedCoRoutineList = NULL; + pxOverflowDelayedCoRoutineList = NULL; + + /* Other file private variables. */ + pxCurrentCoRoutine = NULL; + uxTopCoRoutineReadyPriority = 0; + xCoRoutineTickCount = 0; + xLastTickCount = 0; + xPassedTicks = 0; + } + +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ +/*-----------------------------------------------------------*/ #endif /* configUSE_CO_ROUTINES == 0 */ diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 23526bb0227..92b875e9c7f 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -551,6 +551,10 @@ #define portPOINTER_SIZE_TYPE uint32_t #endif +#ifndef configSUPPORT_REINITIALISE_INTERNAL_VARIABLES + #define configSUPPORT_REINITIALISE_INTERNAL_VARIABLES 0 +#endif + /* Remove any unused trace macros. */ #ifndef traceSTART diff --git a/include/croutine.h b/include/croutine.h index 40ac9765b13..9ae3cf82601 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 ); +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) +/* + * For internal use only. Re-initialise internal variables in croutine.c file. + */ + void vCoRoutineReinitialiseVariables( void ) PRIVILEGED_FUNCTION; +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/include/portable.h b/include/portable.h index ab8a26df08b..c77399b94d6 100644 --- a/include/portable.h +++ b/include/portable.h @@ -190,6 +190,10 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; #define vPortFreeStack vPortFree #endif +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + void vPortHeapReinitialiseVariables( void ) PRIVILEGED_FUNCTION; +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ + #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) /** diff --git a/include/timers.h b/include/timers.h index e874d2434b5..b67d9230274 100644 --- a/include/timers.h +++ b/include/timers.h @@ -1417,6 +1417,13 @@ BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer, #endif +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) +/* + * For internal use only. Re-initialise internal variables in timer.c file. + */ + void vTimerReinitialiseVariables( void ) PRIVILEGED_FUNCTION; +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/portable/MemMang/heap_1.c b/portable/MemMang/heap_1.c index 19f695b2000..97a2d6b1fff 100644 --- a/portable/MemMang/heap_1.c +++ b/portable/MemMang/heap_1.c @@ -150,3 +150,20 @@ size_t xPortGetFreeHeapSize( void ) { return( configADJUSTED_HEAP_SIZE - xNextFreeByte ); } + +/*-----------------------------------------------------------*/ +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + +/* + * Re-initialise internal variables in this file. FreeRTOS doesn't implement an init + * function. Some of the internal variables need to be initialised at declaration + * time. This function is added and only required for application needs to restart + * the FreeRTOS scheduler ( for example to restart the scheduler for each test case + * when running with a test framework ). + */ + void vPortHeapReinitialiseVariables( void ) + { + xNextFreeByte = ( size_t ) 0; + } +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_2.c b/portable/MemMang/heap_2.c index fffcb9ca3d1..13ddc7ad62d 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; +/* Indicate the heap has been initialised before 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,21 @@ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ pxFirstFreeBlock->pxNextFreeBlock = &xEnd; } /*-----------------------------------------------------------*/ + +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + +/* + * Re-initialise internal variables in this file. FreeRTOS doesn't implement an init + * function. Some of the internal variables need to be initialised at declaration + * time. This function is added and only required for application needs to restart + * the FreeRTOS scheduler ( for example to restart the scheduler for each test case + * when running with a test framework ). + */ + void vPortHeapReinitialiseVariables( void ) + { + xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + + xHeapHasBeenInitialised = pdFALSE; + } +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_3.c b/portable/MemMang/heap_3.c index d174a57e9f1..2cce6f4d68e 100644 --- a/portable/MemMang/heap_3.c +++ b/portable/MemMang/heap_3.c @@ -92,3 +92,20 @@ void vPortFree( void * pv ) ( void ) xTaskResumeAll(); } } +/*-----------------------------------------------------------*/ + +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + +/* + * Re-initialise internal variables in this file. FreeRTOS doesn't implement an init + * function. Some of the internal variables need to be initialised at declaration + * time. This function is added and only required for application needs to restart + * the FreeRTOS scheduler ( for example to restart the scheduler for each test case + * when running with a test framework ). + */ + void vPortHeapReinitialiseVariables( void ) + { + /* No internal variable is required to be re-initialised in heap_3. */ + } +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_4.c b/portable/MemMang/heap_4.c index 507bf48b992..a97b988fe34 100644 --- a/portable/MemMang/heap_4.c +++ b/portable/MemMang/heap_4.c @@ -608,3 +608,24 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats ) taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ + +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + +/* + * Re-initialise internal variables in this file. FreeRTOS doesn't implement an init + * function. Some of the internal variables need to be initialised at declaration + * time. This function is added and only required for application needs to restart + * the FreeRTOS scheduler ( for example to restart the scheduler for each test case + * when running with a test framework ). + */ + void vPortHeapReinitialiseVariables( void ) + { + pxEnd = NULL; + + xFreeBytesRemaining = 0U; + xMinimumEverFreeBytesRemaining = 0U; + xNumberOfSuccessfulAllocations = 0; + xNumberOfSuccessfulFrees = 0; + } +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/MemMang/heap_5.c b/portable/MemMang/heap_5.c index 18234626a07..a2b8c9cb595 100644 --- a/portable/MemMang/heap_5.c +++ b/portable/MemMang/heap_5.c @@ -707,3 +707,29 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats ) taskEXIT_CRITICAL(); } /*-----------------------------------------------------------*/ + +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + +/* + * Re-initialise internal variables in this file. FreeRTOS doesn't implement an init + * function. Some of the internal variables need to be initialised at declaration + * time. This function is added and only required for application needs to restart + * the FreeRTOS scheduler ( for example to restart the scheduler for each test case + * when running with a test framework ). + */ + void vPortHeapReinitialiseVariables( void ) + { + pxEnd = NULL; + + xFreeBytesRemaining = 0U; + xMinimumEverFreeBytesRemaining = 0U; + xNumberOfSuccessfulAllocations = 0; + xNumberOfSuccessfulFrees = 0; + + #if ( configENABLE_HEAP_PROTECTOR == 1 ) + pucHeapHighAddress = NULL; + pucHeapLowAddress = NULL; + #endif /* #if ( configENABLE_HEAP_PROTECTOR == 1 ) */ + } +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/tasks.c b/tasks.c index 279d4bdb300..ddd7c57400c 100644 --- a/tasks.c +++ b/tasks.c @@ -41,6 +41,11 @@ #include "timers.h" #include "stack_macros.h" +/* Include croutine.h to reinitilaize internal variables. */ +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) && ( configUSE_CO_ROUTINES == 1 ) + #include "croutine.h" +#endif + /* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined * for the header files above, but not in this file, in order to generate the * correct privileged Vs unprivileged linkage and placement. */ @@ -792,6 +797,19 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; size_t n ); #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ + +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) +/* + * Reinitialise internal variables in this file. FreeRTOS doesn't implement an init + * function. Some of the internal variables need to be initialised at declaration + * time. This function is added and only required for application needs to restart + * the FreeRTOS scheduler ( for example to restart the scheduler for each test case + * when running with a test framework ). + */ + static void prvTaskReinitialiseVariables( void ); + +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ + /*-----------------------------------------------------------*/ #if ( configNUMBER_OF_CORES > 1 ) @@ -3768,6 +3786,25 @@ void vTaskEndScheduler( void ) xSchedulerRunning = pdFALSE; vPortEndScheduler(); + #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + { + #if ( configUSE_CO_ROUTINES == 1 ) + { + vCoRoutineReinitialiseVariables(); + } + #endif /* #if ( configUSE_CO_ROUTINES == 1 ) */ + + #if ( configUSE_TIMERS == 1 ) + { + vTimerReinitialiseVariables(); + } + #endif /* #if ( configUSE_TIMERS == 1 ) */ + + vPortHeapReinitialiseVariables(); + prvTaskReinitialiseVariables(); + } + #endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ + traceRETURN_vTaskEndScheduler(); } /*----------------------------------------------------------*/ @@ -8697,3 +8734,58 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) + + static void prvTaskReinitialiseVariables( 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[ configNUMBER_OF_CORES ] = 0U; + } + } + #endif /* #if ( configGENERATE_RUN_TIME_STATS == 1 ) */ + } + +#endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/timers.c b/timers.c index df7f442c32e..5acfdf7a9cc 100644 --- a/timers.c +++ b/timers.c @@ -1322,6 +1322,23 @@ #endif /* configUSE_TRACE_FACILITY */ /*-----------------------------------------------------------*/ + #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) +/* + * Re-initialise internal variables in this file. FreeRTOS doesn't implement an init + * function. Some of the internal variables need to be initialised at declaration + * time. This function is added and only required for application needs to restart + * the FreeRTOS scheduler ( for example to restart the scheduler for each test case + * when running with a test framework ). + */ + void vTimerReinitialiseVariables( void ) + { + xTimerQueue = NULL; + xTimerTaskHandle = NULL; + } + + #endif /* #if ( configSUPPORT_REINITIALISE_INTERNAL_VARIABLES == 1 ) */ +/*-----------------------------------------------------------*/ + /* 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. */