|
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
|
@@ -328,6 +339,13 @@ typedef struct tskTaskControlBlock /* The old naming convention is used to
|
328 | 339 | #if ( configUSE_POSIX_ERRNO == 1 )
|
329 | 340 | int iTaskErrno;
|
330 | 341 | #endif
|
| 342 | + #if ( configUSE_PICOLIBC_TLS == 1) |
| 343 | + /* Pointer to thread-local variables for this task. |
| 344 | + * These are allocated from the task stack and managed |
| 345 | + * using Picolibc TLS support functions. |
| 346 | + */ |
| 347 | + void *pvTls; |
| 348 | + #endif |
331 | 349 | } tskTCB;
|
332 | 350 |
|
333 | 351 | /* The old tskTCB name is maintained above then typedefed to the new TCB_t name
|
@@ -986,6 +1004,29 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
986 | 1004 | }
|
987 | 1005 | #endif
|
988 | 1006 |
|
| 1007 | + #if ( configUSE_PICOLIBC_TLS == 1) |
| 1008 | + { |
| 1009 | + /* Allocate thread local storage block off the end of the |
| 1010 | + * stack. The _tls_size() function returns the size (in |
| 1011 | + * bytes) of the total TLS area used by the application */ |
| 1012 | + #if ( portSTACK_GROWTH < 0 ) |
| 1013 | + { |
| 1014 | + pxTopOfStack = ( StackType_t *) ( ( ( portPOINTER_SIZE_TYPE) pxTopOfStack) - _tls_size() ); |
| 1015 | + pxNewTCB->pvTls = pxTopOfStack; |
| 1016 | + } |
| 1017 | + #else /* portSTACK_GROWTH */ |
| 1018 | + { |
| 1019 | + pxNewTCB->pvTls = pxTopOfStack; |
| 1020 | + pxTopOfStack = ( StackType_t *) ( ( ( portPOINTER_SIZE_TYPE) pxTopOfStack) + _tls_size() ); |
| 1021 | + } |
| 1022 | + #endif /* portSTACK_GROWTH */ |
| 1023 | + /* Initialize the thread local storage block. This copies |
| 1024 | + * the initialization data to initialized variables and |
| 1025 | + * clears uninitialized variables to zero */ |
| 1026 | + _init_tls(pxNewTCB->pvTls); |
| 1027 | + } |
| 1028 | + #endif |
| 1029 | + |
989 | 1030 | #if ( configUSE_NEWLIB_REENTRANT == 1 )
|
990 | 1031 | {
|
991 | 1032 | /* Initialise this task's Newlib reent structure.
|
@@ -2068,6 +2109,11 @@ void vTaskStartScheduler( void )
|
2068 | 2109 | _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
|
2069 | 2110 | }
|
2070 | 2111 | #endif /* configUSE_NEWLIB_REENTRANT */
|
| 2112 | + #if ( configUSE_PICOLIBC_TLS == 1) |
| 2113 | + { |
| 2114 | + _set_tls(pxCurrentTCB->pvTls); |
| 2115 | + } |
| 2116 | + #endif |
2071 | 2117 |
|
2072 | 2118 | xNextTaskUnblockTime = portMAX_DELAY;
|
2073 | 2119 | xSchedulerRunning = pdTRUE;
|
@@ -3081,6 +3127,11 @@ void vTaskSwitchContext( void )
|
3081 | 3127 | _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
|
3082 | 3128 | }
|
3083 | 3129 | #endif /* configUSE_NEWLIB_REENTRANT */
|
| 3130 | + #if ( configUSE_PICOLIBC_TLS == 1) |
| 3131 | + { |
| 3132 | + _set_tls(pxCurrentTCB->pvTls); |
| 3133 | + } |
| 3134 | + #endif |
3084 | 3135 | }
|
3085 | 3136 | }
|
3086 | 3137 | /*-----------------------------------------------------------*/
|
|
0 commit comments