|
58 | 58 | #include <stdio.h>
|
59 | 59 | #endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */
|
60 | 60 |
|
| 61 | +#if ( configUSE_PICOLIBC_TLS == 1) |
| 62 | + |
| 63 | +/* If picolibc TLS support is being used, then initialize a per-thread |
| 64 | + * TLS block off the end of the stack and set the TLS pointer at each |
| 65 | + * task switch. More information about picolibc's thread local storage |
| 66 | + * support is provided on the following link: |
| 67 | + * https://github.com/picolibc/picolibc/blob/main/doc/tls.md */ |
| 68 | + |
| 69 | + #include <picotls.h> |
| 70 | +#endif |
| 71 | + |
61 | 72 | #if ( configUSE_PREEMPTION == 0 )
|
62 | 73 |
|
63 | 74 | /* If the cooperative scheduler is being used then a yield should not be
|
@@ -329,6 +340,13 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to
|
329 | 340 | #if ( configUSE_POSIX_ERRNO == 1 )
|
330 | 341 | int iTaskErrno;
|
331 | 342 | #endif
|
| 343 | + #if ( configUSE_PICOLIBC_TLS == 1) |
| 344 | + /* Pointer to thread-local variables for this task. |
| 345 | + * These are allocated from the task stack and managed |
| 346 | + * using Picolibc TLS support functions. |
| 347 | + */ |
| 348 | + void *pvTls; |
| 349 | + #endif |
332 | 350 | } tskTCB;
|
333 | 351 |
|
334 | 352 | /* The old tskTCB name is maintained above then typedefed to the new TCB_t name
|
@@ -964,6 +982,29 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
964 | 982 | }
|
965 | 983 | #endif
|
966 | 984 |
|
| 985 | + #if ( configUSE_PICOLIBC_TLS == 1) |
| 986 | + { |
| 987 | + /* Allocate thread local storage block off the end of the |
| 988 | + * stack. The _tls_size() function returns the size (in |
| 989 | + * bytes) of the total TLS area used by the application */ |
| 990 | + #if ( portSTACK_GROWTH < 0 ) |
| 991 | + { |
| 992 | + pxTopOfStack = ( StackType_t *) ( ( ( portPOINTER_SIZE_TYPE) pxTopOfStack) - _tls_size() ); |
| 993 | + pxNewTCB->pvTls = pxTopOfStack; |
| 994 | + } |
| 995 | + #else /* portSTACK_GROWTH */ |
| 996 | + { |
| 997 | + pxNewTCB->pvTls = pxTopOfStack; |
| 998 | + pxTopOfStack = ( StackType_t *) ( ( ( portPOINTER_SIZE_TYPE) pxTopOfStack) + _tls_size() ); |
| 999 | + } |
| 1000 | + #endif /* portSTACK_GROWTH */ |
| 1001 | + /* Initialize the thread local storage block. This copies |
| 1002 | + * the initialization data to initialized variables and |
| 1003 | + * clears uninitialized variables to zero */ |
| 1004 | + _init_tls(pxNewTCB->pvTls); |
| 1005 | + } |
| 1006 | + #endif |
| 1007 | + |
967 | 1008 | #if ( configUSE_NEWLIB_REENTRANT == 1 )
|
968 | 1009 | {
|
969 | 1010 | /* Initialise this task's Newlib reent structure.
|
@@ -2047,6 +2088,11 @@ void vTaskStartScheduler( void )
|
2047 | 2088 | _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
|
2048 | 2089 | }
|
2049 | 2090 | #endif /* configUSE_NEWLIB_REENTRANT */
|
| 2091 | + #if ( configUSE_PICOLIBC_TLS == 1) |
| 2092 | + { |
| 2093 | + _set_tls(pxCurrentTCB->pvTls); |
| 2094 | + } |
| 2095 | + #endif |
2050 | 2096 |
|
2051 | 2097 | xNextTaskUnblockTime = portMAX_DELAY;
|
2052 | 2098 | xSchedulerRunning = pdTRUE;
|
@@ -3087,6 +3133,11 @@ void vTaskSwitchContext( void )
|
3087 | 3133 | _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
|
3088 | 3134 | }
|
3089 | 3135 | #endif /* configUSE_NEWLIB_REENTRANT */
|
| 3136 | + #if ( configUSE_PICOLIBC_TLS == 1) |
| 3137 | + { |
| 3138 | + _set_tls(pxCurrentTCB->pvTls); |
| 3139 | + } |
| 3140 | + #endif |
3090 | 3141 | }
|
3091 | 3142 | }
|
3092 | 3143 | /*-----------------------------------------------------------*/
|
|
0 commit comments