Skip to content

Commit 5cb309b

Browse files
committed
Generalize Thread Local Storage (TLS) support
FreeRTOS's Thread Local Storage (TLS) support used variables and functions from newlib, thereby making the TLS support specific to newlib. This commit generalizes the TLS support so that it can be used with other c-runtime libraries also. The default behavior for newlib support is still kept same for backward compatibility. The application writer would need to set configUSE_C_RUNTIME_TLS_SUPPORT to 1 in their FreeRTOSConfig.h and define the following macros to support TLS for a c-runtime library: 1. configTLS_BLOCK_TYPE - Type used to define the TLS block in TCB. 2. configINIT_TLS_BLOCK( xTLSBlock ) - Allocate and initialize memory block for the task's TLS Block. 3. configSET_TLS_BLOCK( xTLSBlock ) - Switch C-Runtime's TLS Block to point to xTLSBlock. 4. configDEINIT_TLS_BLOCK( xTLSBlock ) - Free up the memory allocated for the task's TLS Block. The following is an example to support TLS for picolibc: #define configUSE_C_RUNTIME_TLS_SUPPORT 1 #define configTLS_BLOCK_TYPE void* #define configINIT_TLS_BLOCK( xTLSBlock ) _init_tls( xTLSBlock ) #define configSET_TLS_BLOCK( xTLSBlock ) _set_tls( xTLSBlock ) #define configDEINIT_TLS_BLOCK( xTLSBlock ) Signed-off-by: Gaurav Aggarwal <[email protected]>
1 parent fc61562 commit 5cb309b

File tree

2 files changed

+71
-41
lines changed

2 files changed

+71
-41
lines changed

include/FreeRTOS.h

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,57 @@
7171

7272
/* Required if struct _reent is used. */
7373
#if ( configUSE_NEWLIB_REENTRANT == 1 )
74+
/* Note Newlib support has been included by popular demand, but is not
75+
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
76+
* responsible for resulting newlib operation. User must be familiar with
77+
* newlib and must provide system-wide implementations of the necessary
78+
* stubs. Be warned that (at the time of writing) the current newlib design
79+
* implements a system-wide malloc() that must be provided with locks.
80+
*
81+
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
82+
* for additional information. */
7483
#include <reent.h>
84+
85+
#define configUSE_C_RUNTIME_TLS_SUPPORT 1
86+
87+
#ifndef configTLS_BLOCK_TYPE
88+
#define configTLS_BLOCK_TYPE struct _reent
89+
#endif
90+
91+
#ifndef configINIT_TLS_BLOCK
92+
#define configINIT_TLS_BLOCK( xTLSBlock ) _REENT_INIT_PTR( &( xTLSBlock ) )
93+
#endif
94+
95+
#ifndef configSET_TLS_BLOCK
96+
#define configSET_TLS_BLOCK( xTLSBlock ) _impure_ptr = &( xTLSBlock )
97+
#endif
98+
99+
#ifndef configDEINIT_TLS_BLOCK
100+
#define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) )
101+
#endif
102+
#endif
103+
104+
#ifndef configUSE_C_RUNTIME_TLS_SUPPORT
105+
#define configUSE_C_RUNTIME_TLS_SUPPORT 0
106+
#endif
107+
108+
#if ( ( configUSE_NEWLIB_REENTRANT == 0 ) && ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
109+
110+
#ifndef configTLS_BLOCK_TYPE
111+
#error Missing definition: configTLS_BLOCK_TYPE must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
112+
#endif
113+
114+
#ifndef configINIT_TLS_BLOCK
115+
#error Missing definition: configINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
116+
#endif
117+
118+
#ifndef configSET_TLS_BLOCK
119+
#error Missing definition: configSET_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
120+
#endif
121+
122+
#ifndef configDEINIT_TLS_BLOCK
123+
#error Missing definition: configDEINIT_TLS_BLOCK must be defined in FreeRTOSConfig.h when configUSE_C_RUNTIME_TLS_SUPPORT is set to 1.
124+
#endif
75125
#endif
76126

77127
/*
@@ -1223,8 +1273,8 @@ typedef struct xSTATIC_TCB
12231273
#if ( configGENERATE_RUN_TIME_STATS == 1 )
12241274
configRUN_TIME_COUNTER_TYPE ulDummy16;
12251275
#endif
1226-
#if ( configUSE_NEWLIB_REENTRANT == 1 )
1227-
struct _reent xDummy17;
1276+
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
1277+
configTLS_BLOCK_TYPE xDummy17;
12281278
#endif
12291279
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
12301280
uint32_t ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];

tasks.c

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -296,19 +296,8 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to
296296
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */
297297
#endif
298298

299-
#if ( configUSE_NEWLIB_REENTRANT == 1 )
300-
301-
/* Allocate a Newlib reent structure that is specific to this task.
302-
* Note Newlib support has been included by popular demand, but is not
303-
* used by the FreeRTOS maintainers themselves. FreeRTOS is not
304-
* responsible for resulting newlib operation. User must be familiar with
305-
* newlib and must provide system-wide implementations of the necessary
306-
* stubs. Be warned that (at the time of writing) the current newlib design
307-
* implements a system-wide malloc() that must be provided with locks.
308-
*
309-
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
310-
* for additional information. */
311-
struct _reent xNewLib_reent;
299+
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
300+
configTLS_BLOCK_TYPE xTLSBlock; /*< Memory block used as Thread Local Storage (TLS) Block for the task. */
312301
#endif
313302

314303
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
@@ -964,12 +953,10 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
964953
}
965954
#endif
966955

967-
#if ( configUSE_NEWLIB_REENTRANT == 1 )
956+
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
968957
{
969-
/* Initialise this task's Newlib reent structure.
970-
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
971-
* for additional information. */
972-
_REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) );
958+
/* Allocate and initialize memory for the task's TLS Block. */
959+
configINIT_TLS_BLOCK( pxNewTCB->xTLSBlock );
973960
}
974961
#endif
975962

@@ -2038,15 +2025,13 @@ void vTaskStartScheduler( void )
20382025
* starts to run. */
20392026
portDISABLE_INTERRUPTS();
20402027

2041-
#if ( configUSE_NEWLIB_REENTRANT == 1 )
2028+
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
20422029
{
2043-
/* Switch Newlib's _impure_ptr variable to point to the _reent
2044-
* structure specific to the task that will run first.
2045-
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
2046-
* for additional information. */
2047-
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
2030+
/* Switch C-Runtime's TLS Block to point to the TLS
2031+
* block specific to the task that will run first. */
2032+
configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock );
20482033
}
2049-
#endif /* configUSE_NEWLIB_REENTRANT */
2034+
#endif
20502035

20512036
xNextTaskUnblockTime = portMAX_DELAY;
20522037
xSchedulerRunning = pdTRUE;
@@ -3078,15 +3063,13 @@ void vTaskSwitchContext( void )
30783063
}
30793064
#endif
30803065

3081-
#if ( configUSE_NEWLIB_REENTRANT == 1 )
3066+
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
30823067
{
3083-
/* Switch Newlib's _impure_ptr variable to point to the _reent
3084-
* structure specific to this task.
3085-
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
3086-
* for additional information. */
3087-
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
3068+
/* Switch C-Runtime's TLS Block to point to the TLS
3069+
* Block specific to this task. */
3070+
configSET_TLS_BLOCK( pxCurrentTCB->xTLSBlock );
30883071
}
3089-
#endif /* configUSE_NEWLIB_REENTRANT */
3072+
#endif
30903073
}
30913074
}
30923075
/*-----------------------------------------------------------*/
@@ -3958,15 +3941,12 @@ static void prvCheckTasksWaitingTermination( void )
39583941
* want to allocate and clean RAM statically. */
39593942
portCLEAN_UP_TCB( pxTCB );
39603943

3961-
/* Free up the memory allocated by the scheduler for the task. It is up
3962-
* to the task to free any memory allocated at the application level.
3963-
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
3964-
* for additional information. */
3965-
#if ( configUSE_NEWLIB_REENTRANT == 1 )
3944+
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) )
39663945
{
3967-
_reclaim_reent( &( pxTCB->xNewLib_reent ) );
3946+
/* Free up the memory allocated for the task's TLS Block. */
3947+
configDEINIT_TLS_BLOCK( pxCurrentTCB->xTLSBlock );
39683948
}
3969-
#endif /* configUSE_NEWLIB_REENTRANT */
3949+
#endif
39703950

39713951
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) )
39723952
{

0 commit comments

Comments
 (0)