From 485514f57a7e629abf6b23e5ee7e2d5dc7cdf238 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Nov 2018 15:00:45 +1100 Subject: [PATCH] esp32: Allocate task TCB and stack from system heap not uPy heap. This is necessary for two reasons: 1) FreeRTOS still needs the TCB data structure even after vPortCleanUpTCB has been called, so this latter hook function cannot free the TCB, and there is no where else to safely delete it (this behaviour has changed recently in the ESP IDF); 2) when using external SPI RAM the uPy heap is in this external memory but the task stack must be allocated from internal SRAM. Fixes issue #3904. --- ports/esp32/main.c | 8 ++------ ports/esp32/mpthreadport.c | 17 +++++------------ ports/esp32/sdkconfig.h | 2 +- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/ports/esp32/main.c b/ports/esp32/main.c index 5ef2675de2..9ca88699d2 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -57,9 +57,6 @@ #define MP_TASK_STACK_SIZE (16 * 1024) #define MP_TASK_STACK_LEN (MP_TASK_STACK_SIZE / sizeof(StackType_t)) -STATIC StaticTask_t mp_task_tcb; -STATIC StackType_t mp_task_stack[MP_TASK_STACK_LEN] __attribute__((aligned (8))); - int vprintf_null(const char *format, va_list ap) { // do nothing: this is used as a log target during raw repl mode return 0; @@ -68,7 +65,7 @@ int vprintf_null(const char *format, va_list ap) { void mp_task(void *pvParameter) { volatile uint32_t sp = (uint32_t)get_sp(); #if MICROPY_PY_THREAD - mp_thread_init(&mp_task_stack[0], MP_TASK_STACK_LEN); + mp_thread_init(pxTaskGetStackStart(NULL), MP_TASK_STACK_LEN); #endif uart_init(); @@ -131,8 +128,7 @@ soft_reset: void app_main(void) { nvs_flash_init(); - mp_main_task_handle = xTaskCreateStaticPinnedToCore(mp_task, "mp_task", MP_TASK_STACK_LEN, NULL, MP_TASK_PRIORITY, - &mp_task_stack[0], &mp_task_tcb, 0); + xTaskCreate(mp_task, "mp_task", MP_TASK_STACK_LEN, NULL, MP_TASK_PRIORITY, &mp_main_task_handle); } void nlr_jump_fail(void *val) { diff --git a/ports/esp32/mpthreadport.c b/ports/esp32/mpthreadport.c index b002c880e2..52d4d7ff4d 100644 --- a/ports/esp32/mpthreadport.c +++ b/ports/esp32/mpthreadport.c @@ -47,7 +47,6 @@ typedef struct _thread_t { int ready; // whether the thread is ready and running void *arg; // thread Python args, a GC root pointer void *stack; // pointer to the stack - StaticTask_t *tcb; // pointer to the Task Control Block size_t stack_len; // number of words in the stack struct _thread_t *next; } thread_t; @@ -125,16 +124,14 @@ void mp_thread_create_ex(void *(*entry)(void*), void *arg, size_t *stack_size, i *stack_size = MP_THREAD_MIN_STACK_SIZE; // minimum stack size } - // allocate TCB, stack and linked-list node (must be outside thread_mutex lock) - StaticTask_t *tcb = m_new(StaticTask_t, 1); - StackType_t *stack = m_new(StackType_t, *stack_size / sizeof(StackType_t)); + // Allocate linked-list node (must be outside thread_mutex lock) thread_t *th = m_new_obj(thread_t); mp_thread_mutex_lock(&thread_mutex, 1); // create thread - TaskHandle_t id = xTaskCreateStaticPinnedToCore(freertos_entry, name, *stack_size / sizeof(StackType_t), arg, priority, stack, tcb, 0); - if (id == NULL) { + BaseType_t result = xTaskCreate(freertos_entry, name, *stack_size / sizeof(StackType_t), arg, priority, &th->id); + if (result != pdPASS) { mp_thread_mutex_unlock(&thread_mutex); nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't create thread")); } @@ -143,11 +140,9 @@ void mp_thread_create_ex(void *(*entry)(void*), void *arg, size_t *stack_size, i *stack_size -= 1024; // add thread to linked list of all threads - th->id = id; th->ready = 0; th->arg = arg; - th->stack = stack; - th->tcb = tcb; + th->stack = pxTaskGetStackStart(th->id); th->stack_len = *stack_size / sizeof(StackType_t); th->next = thread; thread = th; @@ -175,7 +170,7 @@ void vPortCleanUpTCB(void *tcb) { mp_thread_mutex_lock(&thread_mutex, 1); for (thread_t *th = thread; th != NULL; prev = th, th = th->next) { // unlink the node from the list - if (th->tcb == tcb) { + if ((void*)th->id == tcb) { if (prev != NULL) { prev->next = th->next; } else { @@ -183,8 +178,6 @@ void vPortCleanUpTCB(void *tcb) { thread = th->next; } // explicitly release all its memory - m_del(StaticTask_t, th->tcb, 1); - m_del(StackType_t, th->stack, th->stack_len); m_del(thread_t, th, 1); break; } diff --git a/ports/esp32/sdkconfig.h b/ports/esp32/sdkconfig.h index 5c6a4c8997..ba2930bca8 100644 --- a/ports/esp32/sdkconfig.h +++ b/ports/esp32/sdkconfig.h @@ -57,7 +57,7 @@ #define CONFIG_SPIRAM_MEMTEST 1 #define CONFIG_SPIRAM_USE_MALLOC 1 #define CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL 32768 -#define CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY 1 +#define CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY 0 #endif #define CONFIG_FOUR_MAC_ADDRESS_FROM_EFUSE 1