diff --git a/.github/lexicon.txt b/.github/lexicon.txt index 751013504dc..68a28eb0c5f 100644 --- a/.github/lexicon.txt +++ b/.github/lexicon.txt @@ -3090,6 +3090,7 @@ xtimerstartfromisr xtimerstop xtimerstopfromisr xtimertaskhandle +xtlsblock xtos xtriggerlevel xtriggerlevelbytes diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 5ce4e28b294..35bef0b6d41 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -71,9 +71,60 @@ /* Required if struct _reent is used. */ #if ( configUSE_NEWLIB_REENTRANT == 1 ) + +/* Note Newlib support has been included by popular demand, but is not + * used by the FreeRTOS maintainers themselves. FreeRTOS is not + * responsible for resulting newlib operation. User must be familiar with + * newlib and must provide system-wide implementations of the necessary + * stubs. Be warned that (at the time of writing) the current newlib design + * implements a system-wide malloc() that must be provided with locks. + * + * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html + * for additional information. */ #include + + #define configUSE_C_RUNTIME_TLS_SUPPORT 1 + + #ifndef configTLS_BLOCK_TYPE + #define configTLS_BLOCK_TYPE struct _reent + #endif + + #ifndef configINIT_TLS_BLOCK + #define configINIT_TLS_BLOCK( xTLSBlock ) _REENT_INIT_PTR( &( xTLSBlock ) ) + #endif + + #ifndef configSET_TLS_BLOCK + #define configSET_TLS_BLOCK( xTLSBlock ) _impure_ptr = &( xTLSBlock ) + #endif + + #ifndef configDEINIT_TLS_BLOCK + #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) + #endif +#endif /* if ( configUSE_NEWLIB_REENTRANT == 1 ) */ + +#ifndef configUSE_C_RUNTIME_TLS_SUPPORT + #define configUSE_C_RUNTIME_TLS_SUPPORT 0 #endif +#if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) + + #ifndef configTLS_BLOCK_TYPE + #error Missing definition: configTLS_BLOCK_TYPE must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. + #endif + + #ifndef configINIT_TLS_BLOCK + #error Missing definition: configINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. + #endif + + #ifndef configSET_TLS_BLOCK + #error Missing definition: configSET_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. + #endif + + #ifndef configDEINIT_TLS_BLOCK + #error Missing definition: configDEINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1. + #endif +#endif /* if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) */ + /* * Check all the required application specific macros have been defined. * These macros are application specific and (as downloaded) are defined @@ -1223,8 +1274,8 @@ typedef struct xSTATIC_TCB #if ( configGENERATE_RUN_TIME_STATS == 1 ) configRUN_TIME_COUNTER_TYPE ulDummy16; #endif - #if ( configUSE_NEWLIB_REENTRANT == 1 ) - struct _reent xDummy17; + #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) + configTLS_BLOCK_TYPE xDummy17; #endif #if ( configUSE_TASK_NOTIFICATIONS == 1 ) uint32_t ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; diff --git a/tasks.c b/tasks.c index e5f397a5ee9..3aae3a90fe3 100644 --- a/tasks.c +++ b/tasks.c @@ -296,19 +296,8 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ #endif - #if ( configUSE_NEWLIB_REENTRANT == 1 ) - - /* Allocate a Newlib reent structure that is specific to this task. - * Note Newlib support has been included by popular demand, but is not - * used by the FreeRTOS maintainers themselves. FreeRTOS is not - * responsible for resulting newlib operation. User must be familiar with - * newlib and must provide system-wide implementations of the necessary - * stubs. Be warned that (at the time of writing) the current newlib design - * implements a system-wide malloc() that must be provided with locks. - * - * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html - * for additional information. */ - struct _reent xNewLib_reent; + #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) + configTLS_BLOCK_TYPE xTLSBlock; /*< Memory block used as Thread Local Storage (TLS) Block for the task. */ #endif #if ( configUSE_TASK_NOTIFICATIONS == 1 ) @@ -964,12 +953,10 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, } #endif - #if ( configUSE_NEWLIB_REENTRANT == 1 ) + #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) { - /* Initialise this task's Newlib reent structure. - * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html - * for additional information. */ - _REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) ); + /* Allocate and initialize memory for the task's TLS Block. */ + configINIT_TLS_BLOCK( pxNewTCB->xTLSBlock ); } #endif @@ -2038,15 +2025,13 @@ void vTaskStartScheduler( void ) * starts to run. */ portDISABLE_INTERRUPTS(); - #if ( configUSE_NEWLIB_REENTRANT == 1 ) + #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) { - /* Switch Newlib's _impure_ptr variable to point to the _reent - * structure specific to the task that will run first. - * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html - * for additional information. */ - _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + /* Switch C-Runtime's TLS Block to point to the TLS + * block specific to the task that will run first. */ + configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); } - #endif /* configUSE_NEWLIB_REENTRANT */ + #endif xNextTaskUnblockTime = portMAX_DELAY; xSchedulerRunning = pdTRUE; @@ -3078,15 +3063,13 @@ void vTaskSwitchContext( void ) } #endif - #if ( configUSE_NEWLIB_REENTRANT == 1 ) + #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) { - /* Switch Newlib's _impure_ptr variable to point to the _reent - * structure specific to this task. - * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html - * for additional information. */ - _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + /* Switch C-Runtime's TLS Block to point to the TLS + * Block specific to this task. */ + configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); } - #endif /* configUSE_NEWLIB_REENTRANT */ + #endif } } /*-----------------------------------------------------------*/ @@ -3958,15 +3941,12 @@ static void prvCheckTasksWaitingTermination( void ) * want to allocate and clean RAM statically. */ portCLEAN_UP_TCB( pxTCB ); - /* Free up the memory allocated by the scheduler for the task. It is up - * to the task to free any memory allocated at the application level. - * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html - * for additional information. */ - #if ( configUSE_NEWLIB_REENTRANT == 1 ) + #if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ) { - _reclaim_reent( &( pxTCB->xNewLib_reent ) ); + /* Free up the memory allocated for the task's TLS Block. */ + configDEINIT_TLS_BLOCK( pxCurrentTCB->xTLSBlock ); } - #endif /* configUSE_NEWLIB_REENTRANT */ + #endif #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) {