From f65870566a4b9caf64f9ee7e2ca97bd73df894db Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 29 Jan 2018 21:40:38 +0800 Subject: [PATCH 1/8] crosscore_int: use _ISR version of portENTER/EXIT_CRITICAL in ISR --- components/esp32/crosscore_int.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 4a57a2b197..9ccda1f824 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -61,10 +61,10 @@ static void IRAM_ATTR esp_crosscore_isr(void *arg) { DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0); } //Grab the reason and clear it. - portENTER_CRITICAL(&reason_spinlock); + portENTER_CRITICAL_ISR(&reason_spinlock); my_reason_val=*my_reason; *my_reason=0; - portEXIT_CRITICAL(&reason_spinlock); + portEXIT_CRITICAL_ISR(&reason_spinlock); //Check what we need to do. if (my_reason_val & REASON_YIELD) { From 573ea385b433c3c0e0397f15f4f5c1866edad3aa Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 29 Jan 2018 21:41:58 +0800 Subject: [PATCH 2/8] multi_heap: use portENTER/EXIT_CRITICAL instead of taskENTER/EXIT_CRITICAL --- components/heap/heap_trace.c | 16 ++++++++-------- components/heap/multi_heap_platform.h | 5 ++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/components/heap/heap_trace.c b/components/heap/heap_trace.c index 04ae69431c..bb1cc6eda8 100644 --- a/components/heap/heap_trace.c +++ b/components/heap/heap_trace.c @@ -77,7 +77,7 @@ esp_err_t heap_trace_start(heap_trace_mode_t mode_param) if (buffer == NULL || total_records == 0) { return ESP_ERR_INVALID_STATE; } - taskENTER_CRITICAL(&trace_mux); + portENTER_CRITICAL(&trace_mux); tracing = false; mode = mode_param; @@ -87,7 +87,7 @@ esp_err_t heap_trace_start(heap_trace_mode_t mode_param) has_overflowed = false; heap_trace_resume(); - taskEXIT_CRITICAL(&trace_mux); + portEXIT_CRITICAL(&trace_mux); return ESP_OK; } @@ -128,13 +128,13 @@ esp_err_t heap_trace_get(size_t index, heap_trace_record_t *record) } esp_err_t result = ESP_OK; - taskENTER_CRITICAL(&trace_mux); + portENTER_CRITICAL(&trace_mux); if (index >= count) { result = ESP_ERR_INVALID_ARG; /* out of range for 'count' */ } else { memcpy(record, &buffer[index], sizeof(heap_trace_record_t)); } - taskEXIT_CRITICAL(&trace_mux); + portEXIT_CRITICAL(&trace_mux); return result; } @@ -192,7 +192,7 @@ void heap_trace_dump(void) /* Add a new allocation to the heap trace records */ static IRAM_ATTR void record_allocation(const heap_trace_record_t *record) { - taskENTER_CRITICAL(&trace_mux); + portENTER_CRITICAL(&trace_mux); if (tracing) { if (count == total_records) { has_overflowed = true; @@ -211,7 +211,7 @@ static IRAM_ATTR void record_allocation(const heap_trace_record_t *record) count++; total_allocations++; } - taskEXIT_CRITICAL(&trace_mux); + portEXIT_CRITICAL(&trace_mux); } // remove a record, used when freeing @@ -224,7 +224,7 @@ static void remove_record(int index); */ static IRAM_ATTR void record_free(void *p, void **callers) { - taskENTER_CRITICAL(&trace_mux); + portENTER_CRITICAL(&trace_mux); if (tracing && count > 0) { total_frees++; /* search backwards for the allocation record matching this free */ @@ -244,7 +244,7 @@ static IRAM_ATTR void record_free(void *p, void **callers) } } } - taskEXIT_CRITICAL(&trace_mux); + portEXIT_CRITICAL(&trace_mux); } /* remove the entry at 'index' from the ringbuffer of saved records */ diff --git a/components/heap/multi_heap_platform.h b/components/heap/multi_heap_platform.h index 6a17522b46..df607e6cd0 100644 --- a/components/heap/multi_heap_platform.h +++ b/components/heap/multi_heap_platform.h @@ -16,7 +16,6 @@ #ifdef ESP_PLATFORM #include -#include #include #include @@ -24,14 +23,14 @@ we need to use portmux spinlocks here not RTOS mutexes */ #define MULTI_HEAP_LOCK(PLOCK) do { \ if((PLOCK) != NULL) { \ - taskENTER_CRITICAL((portMUX_TYPE *)(PLOCK)); \ + portENTER_CRITICAL((portMUX_TYPE *)(PLOCK)); \ } \ } while(0) #define MULTI_HEAP_UNLOCK(PLOCK) do { \ if ((PLOCK) != NULL) { \ - taskEXIT_CRITICAL((portMUX_TYPE *)(PLOCK)); \ + portEXIT_CRITICAL((portMUX_TYPE *)(PLOCK)); \ } \ } while(0) From 41ae0fe52b0ed212038bd7d2f6f4e839f65ee5d1 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 29 Jan 2018 21:46:20 +0800 Subject: [PATCH 3/8] newlib: define _REENT_INIT_PTR correctly for ESP_PLATFORM --- components/newlib/include/sys/reent.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/newlib/include/sys/reent.h b/components/newlib/include/sys/reent.h index bb52ae65f1..ee40961894 100644 --- a/components/newlib/include/sys/reent.h +++ b/components/newlib/include/sys/reent.h @@ -446,6 +446,7 @@ extern const struct __sFILE_fake __sf_fake_stderr; _NULL \ } +#ifndef ESP_PLATFORM #define _REENT_INIT_PTR(var) \ { memset((var), 0, sizeof(*(var))); \ (var)->_stdin = (__FILE *)&__sf_fake_stdin; \ @@ -453,6 +454,10 @@ extern const struct __sFILE_fake __sf_fake_stderr; (var)->_stderr = (__FILE *)&__sf_fake_stderr; \ (var)->_current_locale = "C"; \ } +#else +extern void esp_reent_init(struct _reent* reent); +#define _REENT_INIT_PTR(var) esp_reent_init(var) +#endif /* Only built the assert() calls if we are built with debugging. */ #if DEBUG From 2d598d6fb7d9f10464b14dc804ea2392ba224f1a Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 2 Feb 2018 00:15:55 +0800 Subject: [PATCH 4/8] esp_timer: use _ISR version of port{ENTER,EXIT}_CRITICAL from ISR --- components/esp32/esp_timer_esp32.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/esp32/esp_timer_esp32.c b/components/esp32/esp_timer_esp32.c index 0b95f67e44..4c21910e8a 100644 --- a/components/esp32/esp_timer_esp32.c +++ b/components/esp32/esp_timer_esp32.c @@ -243,7 +243,7 @@ void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp) static void IRAM_ATTR timer_alarm_isr(void *arg) { - portENTER_CRITICAL(&s_time_update_lock); + portENTER_CRITICAL_ISR(&s_time_update_lock); // Timekeeping: adjust s_time_base_us if counter has passed ALARM_OVERFLOW_VAL if (timer_overflow_happened()) { timer_count_reload(); @@ -256,17 +256,17 @@ static void IRAM_ATTR timer_alarm_isr(void *arg) // Set alarm to the next overflow moment. Later, upper layer function may // call esp_timer_impl_set_alarm to change this to an earlier value. REG_WRITE(FRC_TIMER_ALARM_REG(1), ALARM_OVERFLOW_VAL); - portEXIT_CRITICAL(&s_time_update_lock); + portEXIT_CRITICAL_ISR(&s_time_update_lock); // Call the upper layer handler (*s_alarm_handler)(arg); } void IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us) { - portENTER_CRITICAL(&s_time_update_lock); + portENTER_CRITICAL_ISR(&s_time_update_lock); /* Bail out if the timer is not initialized yet */ if (s_timer_interrupt_handle == NULL) { - portEXIT_CRITICAL(&s_time_update_lock); + portEXIT_CRITICAL_ISR(&s_time_update_lock); return; } @@ -308,7 +308,7 @@ void IRAM_ATTR esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us) s_timer_ticks_per_us = new_ticks_per_us; s_timer_us_per_overflow = ALARM_OVERFLOW_VAL / new_ticks_per_us; - portEXIT_CRITICAL(&s_time_update_lock); + portEXIT_CRITICAL_ISR(&s_time_update_lock); } esp_err_t esp_timer_impl_init(intr_handler_t alarm_handler) From 24ad64bfe4d94a03c11060042ca10a3f980708ef Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 2 Feb 2018 00:17:38 +0800 Subject: [PATCH 5/8] pthread: implement local storage using pvTaskGetThreadLocalStoragePointer If static task cleanup option is enabled, then before invoking application defined `vPortCleanUpTCB` hook, pthread specific cleanup is performed. Signed-off-by: Mahavir Jain --- components/pthread/component.mk | 4 +++ components/pthread/pthread_local_storage.c | 31 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/components/pthread/component.mk b/components/pthread/component.mk index 97ace4b78c..0dd2394810 100644 --- a/components/pthread/component.mk +++ b/components/pthread/component.mk @@ -7,3 +7,7 @@ COMPONENT_SRCDIRS := . COMPONENT_ADD_INCLUDEDIRS := include COMPONENT_ADD_LDFLAGS := -lpthread + +ifdef CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK +COMPONENT_ADD_LDFLAGS += -Wl,--wrap=vPortCleanUpTCB +endif diff --git a/components/pthread/pthread_local_storage.c b/components/pthread/pthread_local_storage.c index da59726a35..f87f698d8b 100644 --- a/components/pthread/pthread_local_storage.c +++ b/components/pthread/pthread_local_storage.c @@ -142,6 +142,29 @@ static void pthread_local_storage_thread_deleted_callback(int index, void *v_tls free(tls); } +#if defined(CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK) +/* Called from FreeRTOS task delete hook */ +void pthread_local_storage_cleanup(TaskHandle_t task) +{ + void *tls = pvTaskGetThreadLocalStoragePointer(task, PTHREAD_TLS_INDEX); + if (tls != NULL) { + pthread_local_storage_thread_deleted_callback(PTHREAD_TLS_INDEX, tls); + vTaskSetThreadLocalStoragePointer(task, PTHREAD_TLS_INDEX, NULL); + } +} + +void __real_vPortCleanUpTCB(void *tcb); + +/* If static task cleanup hook is defined then its applications responsibility to define `vPortCleanUpTCB`. + Here we are wrapping it, so that we can do pthread specific TLS cleanup and then invoke application + real specific `vPortCleanUpTCB` */ +void __wrap_vPortCleanUpTCB(void *tcb) +{ + pthread_local_storage_cleanup(tcb); + __real_vPortCleanUpTCB(tcb); +} +#endif + /* this function called from pthread_task_func for "early" cleanup of TLS in a pthread */ void pthread_internal_local_storage_destructor_callback() { @@ -151,10 +174,14 @@ void pthread_internal_local_storage_destructor_callback() /* remove the thread-local-storage pointer to avoid the idle task cleanup calling it again... */ +#if defined(CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK) + vTaskSetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX, NULL); +#else vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, PTHREAD_TLS_INDEX, NULL, NULL); +#endif } } @@ -196,10 +223,14 @@ int pthread_setspecific(pthread_key_t key, const void *value) if (tls == NULL) { return ENOMEM; } +#if defined(CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK) + vTaskSetThreadLocalStoragePointer(NULL, PTHREAD_TLS_INDEX, tls); +#else vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, PTHREAD_TLS_INDEX, tls, pthread_local_storage_thread_deleted_callback); +#endif } value_entry_t *entry = find_value(tls, key); From c65a08d2fb4534fe60b56a61c0290d2c8bd4d47c Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Tue, 27 Mar 2018 19:32:43 +0530 Subject: [PATCH 6/8] freertos: portCLEAN_UP_TCB should be performed before freeing tcb memory Signed-off-by: Mahavir Jain --- components/freertos/tasks.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index e95a8b04bc..980699ffce 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -3878,6 +3878,10 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) static void prvDeleteTCB( TCB_t *pxTCB ) { + /* This call is required for any port specific cleanup related to task. + It must be above the vPortFree() calls. */ + portCLEAN_UP_TCB( pxTCB ); + /* Free up the memory allocated by the scheduler for the task. It is up to the task to free any memory allocated at the application level. */ #if ( configUSE_NEWLIB_REENTRANT == 1 ) @@ -3920,7 +3924,6 @@ BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) /* Neither the stack nor the TCB were allocated dynamically, so nothing needs to be freed. */ configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ) - portCLEAN_UP_TCB( pxTCB ); mtCOVERAGE_TEST_MARKER(); } } From 43a12894ea7f6f6dabe1f48008898a9297b4ed08 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 23 Mar 2018 19:28:03 +0530 Subject: [PATCH 7/8] driver/spi: add _ISR counterparts if invoked from interrupt for critical section Signed-off-by: Mahavir Jain --- components/driver/spi_common.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index 4ea94a7c00..0aab4ee026 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -438,7 +438,7 @@ bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t { int otherchan = (dmachan == 1) ? 2 : 1; bool ret; - portENTER_CRITICAL(&dmaworkaround_mux); + portENTER_CRITICAL_ISR(&dmaworkaround_mux); if (dmaworkaround_channels_busy[otherchan-1]) { //Other channel is busy. Call back when it's done. dmaworkaround_cb = cb; @@ -450,7 +450,7 @@ bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t periph_module_reset( PERIPH_SPI_DMA_MODULE ); ret = true; } - portEXIT_CRITICAL(&dmaworkaround_mux); + portEXIT_CRITICAL_ISR(&dmaworkaround_mux); return ret; } @@ -461,7 +461,7 @@ bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress() void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan) { - portENTER_CRITICAL(&dmaworkaround_mux); + portENTER_CRITICAL_ISR(&dmaworkaround_mux); dmaworkaround_channels_busy[dmachan-1] = 0; if (dmaworkaround_waiting_for_chan == dmachan) { //Reset DMA @@ -471,14 +471,14 @@ void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan) dmaworkaround_cb(dmaworkaround_cb_arg); } - portEXIT_CRITICAL(&dmaworkaround_mux); + portEXIT_CRITICAL_ISR(&dmaworkaround_mux); } void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan) { - portENTER_CRITICAL(&dmaworkaround_mux); + portENTER_CRITICAL_ISR(&dmaworkaround_mux); dmaworkaround_channels_busy[dmachan-1] = 1; - portEXIT_CRITICAL(&dmaworkaround_mux); + portEXIT_CRITICAL_ISR(&dmaworkaround_mux); } From 441b4a974226c2deaa9ffb8e7308c3009985aba6 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Wed, 14 Mar 2018 13:47:04 +0530 Subject: [PATCH 8/8] esp32: fix few components with dependency on networking stack * Move smartconfig to its component directory, it should be possible to override this as whole component * Fix few header includes related to lwIP networking stack Signed-off-by: Mahavir Jain --- components/esp32/cpu_start.c | 3 +-- components/smartconfig/component.mk | 2 ++ components/{esp32 => smartconfig/include}/smartconfig.h | 0 components/{esp32 => smartconfig}/smartconfig.c | 0 components/wpa_supplicant/port/include/os.h | 2 +- 5 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 components/smartconfig/component.mk rename components/{esp32 => smartconfig/include}/smartconfig.h (100%) rename components/{esp32 => smartconfig}/smartconfig.c (100%) diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 7f0e1573d8..0454e3ac2d 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -38,8 +38,6 @@ #include "freertos/queue.h" #include "freertos/portmacro.h" -#include "tcpip_adapter.h" - #include "esp_heap_caps_init.h" #include "sdkconfig.h" #include "esp_system.h" @@ -55,6 +53,7 @@ #include "esp_newlib.h" #include "esp_brownout.h" #include "esp_int_wdt.h" +#include "esp_task.h" #include "esp_task_wdt.h" #include "esp_phy_init.h" #include "esp_cache_err_int.h" diff --git a/components/smartconfig/component.mk b/components/smartconfig/component.mk new file mode 100644 index 0000000000..58eac9a550 --- /dev/null +++ b/components/smartconfig/component.mk @@ -0,0 +1,2 @@ +# +# Component Makefile diff --git a/components/esp32/smartconfig.h b/components/smartconfig/include/smartconfig.h similarity index 100% rename from components/esp32/smartconfig.h rename to components/smartconfig/include/smartconfig.h diff --git a/components/esp32/smartconfig.c b/components/smartconfig/smartconfig.c similarity index 100% rename from components/esp32/smartconfig.c rename to components/smartconfig/smartconfig.c diff --git a/components/wpa_supplicant/port/include/os.h b/components/wpa_supplicant/port/include/os.h index e6da894e92..468d54ffe8 100644 --- a/components/wpa_supplicant/port/include/os.h +++ b/components/wpa_supplicant/port/include/os.h @@ -19,7 +19,7 @@ #include #include #include "rom/ets_sys.h" -#include "lwip/mem.h" + typedef long os_time_t; /**