diff --git a/components/freertos/freertos/tasks.c b/components/freertos/freertos/tasks.c index 6a65fdd9..66c7e854 100644 --- a/components/freertos/freertos/tasks.c +++ b/components/freertos/freertos/tasks.c @@ -3490,6 +3490,24 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) return pvReturn; } + void **pvTaskGetThreadLocalStorageBufferPointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) + { + void **pvReturn = NULL; + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + pvReturn = &pxTCB->pvThreadLocalStoragePointers[ xIndex ]; + } + else + { + pvReturn = NULL; + } + + return pvReturn; + } + #endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ /*-----------------------------------------------------------*/ diff --git a/components/freertos/include/freertos/task.h b/components/freertos/include/freertos/task.h index 7eb67a9f..bd677d8c 100644 --- a/components/freertos/include/freertos/task.h +++ b/components/freertos/include/freertos/task.h @@ -1458,6 +1458,7 @@ constant. */ used to set and query a pointer respectively. */ void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION; void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; + void **pvTaskGetThreadLocalStorageBufferPointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; #if ( configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS ) /** diff --git a/components/freertos/port/esp8266/impure.c b/components/freertos/port/esp8266/impure.c index ecea43f3..710514dd 100644 --- a/components/freertos/port/esp8266/impure.c +++ b/components/freertos/port/esp8266/impure.c @@ -17,6 +17,8 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#define ERRNO_TLS_INDEX (configNUM_THREAD_LOCAL_STORAGE_POINTERS - 1) + static struct _reent impure_data; struct _reent *_global_impure_ptr = &impure_data; @@ -44,3 +46,8 @@ struct _reent *__getreent() #endif return _global_impure_ptr; } + +int *__errno(void) +{ + return (int *)pvTaskGetThreadLocalStorageBufferPointer(NULL, ERRNO_TLS_INDEX); +} diff --git a/components/freertos/port/esp8266/include/freertos/FreeRTOSConfig.h b/components/freertos/port/esp8266/include/freertos/FreeRTOSConfig.h index bc7f3115..bfbda69a 100644 --- a/components/freertos/port/esp8266/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/port/esp8266/include/freertos/FreeRTOSConfig.h @@ -128,10 +128,15 @@ NVIC value of 255. */ #define configUSE_NEWLIB_REENTRANT 1 #endif +/** + * 0: LwIP + * 1: pthread (optional) + * 2: errno + */ #ifdef CONFIG_ENABLE_PTHREAD -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 2 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 3 #else -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 1 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 2 #endif #define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 1 diff --git a/components/freertos/test/CMakeLists.txt b/components/freertos/test/CMakeLists.txt new file mode 100644 index 00000000..6cb8b29f --- /dev/null +++ b/components/freertos/test/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRC_DIRS "." + INCLUDE_DIRS "." + REQUIRES unity test_utils freertos) diff --git a/components/freertos/test/component.mk b/components/freertos/test/component.mk new file mode 100644 index 00000000..5dd172bd --- /dev/null +++ b/components/freertos/test/component.mk @@ -0,0 +1,5 @@ +# +#Component Makefile +# + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/freertos/test/test_errno.c b/components/freertos/test/test_errno.c new file mode 100644 index 00000000..8e167154 --- /dev/null +++ b/components/freertos/test/test_errno.c @@ -0,0 +1,57 @@ +/* mbedTLS AES performance test +*/ +#include +#include +#include +#include +#include "unity.h" +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" + +void __set_errno(int i) +{ + errno = i; +} + +void __get_errno(int *i) +{ + *i = errno; +} + +static void errno_check_task(void *p) +{ + SemaphoreHandle_t wait_sem = p; + + for (volatile int i = 0; i < 10 * 1000 * 1000; i++) { + int j; + + __set_errno(i); + __get_errno(&j); + assert(i == j); + } + + xSemaphoreGive(wait_sem); + + vTaskDelete(NULL); +} + +TEST_CASE("thread local errno", "[reent]") +{ + SemaphoreHandle_t wait1_sem, wait2_sem; + + wait1_sem = xSemaphoreCreateBinary(); + wait2_sem = xSemaphoreCreateBinary(); + + xTaskCreatePinnedToCore(&errno_check_task, "errno1", 2048, wait1_sem, 3, NULL, cpuid_0); + xTaskCreatePinnedToCore(&errno_check_task, "errno2", 2048, wait2_sem, 3, NULL, cpuid_1); + + xSemaphoreTake(wait1_sem, portMAX_DELAY); + xSemaphoreTake(wait2_sem, portMAX_DELAY); + + vQueueDelete(wait1_sem); + vQueueDelete(wait2_sem); +} + + diff --git a/components/newlib/newlib/lib/libc.a b/components/newlib/newlib/lib/libc.a index e34f3bab..a7f4c035 100644 Binary files a/components/newlib/newlib/lib/libc.a and b/components/newlib/newlib/lib/libc.a differ diff --git a/components/newlib/newlib/lib/libc_fnano.a b/components/newlib/newlib/lib/libc_fnano.a index 4d972b58..a7e20f52 100644 Binary files a/components/newlib/newlib/lib/libc_fnano.a and b/components/newlib/newlib/lib/libc_fnano.a differ diff --git a/components/newlib/newlib/lib/libc_nano.a b/components/newlib/newlib/lib/libc_nano.a index 22b45fe1..a82d270b 100644 Binary files a/components/newlib/newlib/lib/libc_nano.a and b/components/newlib/newlib/lib/libc_nano.a differ diff --git a/components/newlib/newlib/lib/strip_symbols.sh b/components/newlib/newlib/lib/strip_symbols.sh new file mode 100755 index 00000000..852000a6 --- /dev/null +++ b/components/newlib/newlib/lib/strip_symbols.sh @@ -0,0 +1,11 @@ + +libs="libc_fnano.a libc.a libc_nano.a" +symbols="lib_a-errno.o" + +for symbol in ${symbols} +do + for lib in ${libs} + do + xtensa-lx106-elf-ar d ${lib} ${symbol} + done +done