From e43fedb3f44b36048d0c35e898b0446cf02b787d Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Sun, 16 May 2021 18:51:28 +0300 Subject: [PATCH 1/8] gcov: added dbg stub capabilites and magic number entry to keep backward compatible --- components/app_trace/gcov/gcov_rtio.c | 6 ++-- components/asio/asio | 2 +- components/bt/controller/lib | 2 +- components/bt/controller/lib_esp32c3_family | 1 + components/bt/host/nimble/nimble | 2 +- components/cbor/tinycbor | 2 +- .../include/esp_private/dbg_stubs.h | 29 +++++++++++++++---- components/esp_common/src/dbg_stubs.c | 12 ++++++++ components/esp_wifi/lib | 2 +- components/esptool_py/esptool | 2 +- components/lwip/lwip | 2 +- components/mqtt/esp-mqtt | 2 +- components/nghttp/nghttp2 | 2 +- components/tinyusb/tinyusb | 2 +- .../components/esp-cryptoauthlib | 2 +- 15 files changed, 51 insertions(+), 19 deletions(-) create mode 160000 components/bt/controller/lib_esp32c3_family diff --git a/components/app_trace/gcov/gcov_rtio.c b/components/app_trace/gcov/gcov_rtio.c index 6744354563..684eed1466 100644 --- a/components/app_trace/gcov/gcov_rtio.c +++ b/components/app_trace/gcov/gcov_rtio.c @@ -115,7 +115,7 @@ static int esp_dbg_stub_gcov_dump_do(void) } /** - * @brief Triggers gcov info dump. + * @brief Triggers gcov info dump task * This function is to be called by OpenOCD, not by normal user code. * TODO: what about interrupted flash access (when cache disabled)??? * @@ -123,11 +123,13 @@ static int esp_dbg_stub_gcov_dump_do(void) */ static int esp_dbg_stub_gcov_entry(void) { - return esp_dbg_stub_gcov_dump_do(); + s_do_dump = true; + return ESP_OK; } int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused))) { + uint32_t capabilities = 0; ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__); esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry); return 0; diff --git a/components/asio/asio b/components/asio/asio index 3b66e5b051..f31694c9f1 160000 --- a/components/asio/asio +++ b/components/asio/asio @@ -1 +1 @@ -Subproject commit 3b66e5b051381fb70de9c2791df70a06181c64e3 +Subproject commit f31694c9f1746ba189a4bcae2e34db15135ddb22 diff --git a/components/bt/controller/lib b/components/bt/controller/lib index fb49791b7c..cfbb0571fb 160000 --- a/components/bt/controller/lib +++ b/components/bt/controller/lib @@ -1 +1 @@ -Subproject commit fb49791b7c1a8a35f06e68124c90022667b4cff1 +Subproject commit cfbb0571fb424ca4a68a0c172cbff1fdc79fd91b diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family new file mode 160000 index 0000000000..7ad49c38b8 --- /dev/null +++ b/components/bt/controller/lib_esp32c3_family @@ -0,0 +1 @@ +Subproject commit 7ad49c38b893952bbed155ede2c7684f0307f6d3 diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 33179b3316..aef55bbf63 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 33179b331639a6157d9196b87a3e2e53f86c7072 +Subproject commit aef55bbf636ed580d4d6408a5c2e75d1f70a875e diff --git a/components/cbor/tinycbor b/components/cbor/tinycbor index d2dd95cb88..085ca40781 160000 --- a/components/cbor/tinycbor +++ b/components/cbor/tinycbor @@ -1 +1 @@ -Subproject commit d2dd95cb8841d88d5a801e3ef9c328fd6200e7bd +Subproject commit 085ca40781f7c39febe6d14fb7e5cba342e1804b diff --git a/components/esp_common/include/esp_private/dbg_stubs.h b/components/esp_common/include/esp_private/dbg_stubs.h index 899dfa56ed..454c3418f9 100644 --- a/components/esp_common/include/esp_private/dbg_stubs.h +++ b/components/esp_common/include/esp_private/dbg_stubs.h @@ -20,13 +20,18 @@ * Debug stubs entries IDs */ typedef enum { - ESP_DBG_STUB_CONTROL_DATA, ///< stubs descriptor entry + ESP_DBG_STUB_MAGIC_NUM, + ESP_DBG_STUB_CONTROL_DATA, ///< stubs descriptor entry ESP_DBG_STUB_ENTRY_FIRST, - ESP_DBG_STUB_ENTRY_GCOV ///< GCOV entry - = ESP_DBG_STUB_ENTRY_FIRST, + ESP_DBG_STUB_ENTRY_GCOV ///< GCOV entry + = ESP_DBG_STUB_ENTRY_FIRST, + ESP_DBG_STUB_CAPABILITIES, ESP_DBG_STUB_ENTRY_MAX } esp_dbg_stub_id_t; +#define ESP_DBG_STUB_MAGIC_NUM_VAL 0xFEEDBEEF +#define ESP_DBG_STUB_CAP_GCOV_TASK (1 << 0) + /** * @brief Initializes debug stubs. * @@ -41,10 +46,22 @@ void esp_dbg_stubs_init(void); * * @param id Stub ID. * @param entry Stub entry. Usually it is stub entry function address, - * but can be any value meaningfull for OpenOCD command/code. - * + * but can be any value meaningfull for OpenOCD command/code + * such as capabilities * @return ESP_OK on success, otherwise see esp_err_t */ esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry); -#endif //ESP_DBG_STUBS_H_ \ No newline at end of file +/** + * @brief Retrives the corresponding stub entry + * + * @param id Stub ID. + * @param entry Stub entry. Usually it is stub entry function address, + * but can be any value meaningfull for OpenOCD command/code + * such as capabilities + * + * @return ESP_OK on success, otherwise see esp_err_t + */ +esp_err_t esp_dbg_stub_entry_get(esp_dbg_stub_id_t id, uint32_t *entry); + +#endif //ESP_DBG_STUBS_H_ diff --git a/components/esp_common/src/dbg_stubs.c b/components/esp_common/src/dbg_stubs.c index 1ee9124897..e4c65c22e2 100644 --- a/components/esp_common/src/dbg_stubs.c +++ b/components/esp_common/src/dbg_stubs.c @@ -76,6 +76,7 @@ void esp_dbg_stubs_init(void) s_dbg_stubs_ctl_data.data_alloc = (uint32_t)esp_dbg_stubs_data_alloc; s_dbg_stubs_ctl_data.data_free = (uint32_t)esp_dbg_stubs_data_free; + s_stub_entry[ESP_DBG_STUB_MAGIC_NUM] = ESP_DBG_STUB_MAGIC_NUM_VAL; s_stub_entry[ESP_DBG_STUB_CONTROL_DATA] = (uint32_t)&s_dbg_stubs_ctl_data; eri_write(ESP_DBG_STUBS_TRAX_REG, (uint32_t)s_stub_entry); ESP_LOGV(TAG, "%s stubs %x", __func__, eri_read(ESP_DBG_STUBS_TRAX_REG)); @@ -92,4 +93,15 @@ esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry) return ESP_OK; } +esp_err_t esp_dbg_stub_entry_get(esp_dbg_stub_id_t id, uint32_t *entry) +{ + if (id < ESP_DBG_STUB_ENTRY_FIRST || id >= ESP_DBG_STUB_ENTRY_MAX) { + ESP_LOGE(TAG, "Invalid stub id %d!", id); + return ESP_ERR_INVALID_ARG; + } + *entry = s_stub_entry[id]; + + return ESP_OK; +} + #endif diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index fbcdc77c26..e6945e61f7 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit fbcdc77c26eb0d716927c8bc7d73dbec9a8987c1 +Subproject commit e6945e61f7c63545a77b0575c3770a85b4de948e diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 4698b39673..2583017317 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 4698b396730b23fb4aab023c5fb1744db957fc4c +Subproject commit 258301731780493365bb249553ae7855a3e753ea diff --git a/components/lwip/lwip b/components/lwip/lwip index 2c9c531f0a..2195f7416f 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 2c9c531f0a7e0ee536db9de4f9dc54e453712087 +Subproject commit 2195f7416fb3136831babf3e96c027a73075bd4f diff --git a/components/mqtt/esp-mqtt b/components/mqtt/esp-mqtt index 9ea804e0ab..f10321a53b 160000 --- a/components/mqtt/esp-mqtt +++ b/components/mqtt/esp-mqtt @@ -1 +1 @@ -Subproject commit 9ea804e0ab5368d5ab53ae2301a5fec9d1f12f1a +Subproject commit f10321a53b53a146ee299cfecc320b89c0cf6611 diff --git a/components/nghttp/nghttp2 b/components/nghttp/nghttp2 index 3bcc416e13..8f7b008b15 160000 --- a/components/nghttp/nghttp2 +++ b/components/nghttp/nghttp2 @@ -1 +1 @@ -Subproject commit 3bcc416e13cc790e2fb45fcfe9111d38609c5032 +Subproject commit 8f7b008b158e12de0e58247afd170f127dbb6456 diff --git a/components/tinyusb/tinyusb b/components/tinyusb/tinyusb index 28f89e1347..334e95fac5 160000 --- a/components/tinyusb/tinyusb +++ b/components/tinyusb/tinyusb @@ -1 +1 @@ -Subproject commit 28f89e13473d40637574bcbfe4142633b39899fd +Subproject commit 334e95fac52a607150157ae5199a19e11f843982 diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib b/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib index c3d3a69021..bb672b0437 160000 --- a/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib +++ b/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib @@ -1 +1 @@ -Subproject commit c3d3a69021cfec3236ca2c0b63be4048ec6643a4 +Subproject commit bb672b0437485fc7420add178299631692b15ac3 From 67fc5183dca7c8bdc49e8e72a207d1d035219433 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Fri, 23 Apr 2021 19:10:35 +0300 Subject: [PATCH 2/8] gcov: dump in a special thread --- components/app_trace/gcov/gcov_rtio.c | 129 ++++++++++---------------- 1 file changed, 49 insertions(+), 80 deletions(-) diff --git a/components/app_trace/gcov/gcov_rtio.c b/components/app_trace/gcov/gcov_rtio.c index 684eed1466..dcfdf23a2d 100644 --- a/components/app_trace/gcov/gcov_rtio.c +++ b/components/app_trace/gcov/gcov_rtio.c @@ -22,6 +22,7 @@ #include "soc/cpu.h" #include "soc/timer_periph.h" #include "esp_app_trace.h" +#include "esp_freertos_hooks.h" #include "esp_private/dbg_stubs.h" #include "hal/wdt_hal.h" #if CONFIG_IDF_TARGET_ESP32 @@ -37,93 +38,71 @@ #define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL #include "esp_log.h" const static char *TAG = "esp_gcov_rtio"; +static volatile bool s_create_gcov_task = false; +static volatile bool s_gcov_task_running = false; extern void __gcov_dump(void); extern void __gcov_reset(void); -static struct syscall_stub_table s_gcov_stub_table; - - -static int gcov_stub_lock_try_acquire_recursive(_lock_t *lock) +void gcov_dump_task(void *pvParameter) { - if (*lock && uxSemaphoreGetCount((xSemaphoreHandle)(*lock)) == 0) { - // we can do nothing here, gcov dump is initiated with some resource locked - // which is also used by gcov functions - ESP_EARLY_LOGE(TAG, "Lock 0x%x is busy during GCOV dump! System state can be inconsistent after dump!", lock); - } - return pdTRUE; -} + int dump_result = 0; + bool *running = (bool *)pvParameter; -static void gcov_stub_lock_acquire_recursive(_lock_t *lock) -{ - gcov_stub_lock_try_acquire_recursive(lock); -} - -static void gcov_stub_lock_release_recursive(_lock_t *lock) -{ -} - -static int esp_dbg_stub_gcov_dump_do(void) -{ - int ret = ESP_OK; - FILE* old_stderr = stderr; - FILE* old_stdout = stdout; - static struct syscall_stub_table *old_tables[portNUM_PROCESSORS]; - - old_tables[0] = syscall_table_ptr_pro; -#if portNUM_PROCESSORS > 1 - old_tables[1] = syscall_table_ptr_app; -#endif ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE); void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE); if (down_buf == NULL) { ESP_EARLY_LOGE(TAG, "Could not allocate memory for the buffer"); - return ESP_ERR_NO_MEM; + dump_result = ESP_ERR_NO_MEM; + goto gcov_exit; } ESP_EARLY_LOGV(TAG, "Config apptrace down buf"); esp_apptrace_down_buffer_config(down_buf, ESP_GCOV_DOWN_BUF_SIZE); + /* we are directing the std outputs to the fake ones in order to reduce stack usage */ + FILE *old_stderr = stderr; + FILE *old_stdout = stdout; + stderr = (FILE *) &__sf_fake_stderr; + stdout = (FILE *) &__sf_fake_stdout; ESP_EARLY_LOGV(TAG, "Dump data..."); - // incase of dual-core chip APP and PRO CPUs share the same table, so it is safe to save only PRO's table - memcpy(&s_gcov_stub_table, syscall_table_ptr_pro, sizeof(s_gcov_stub_table)); - s_gcov_stub_table._lock_acquire_recursive = &gcov_stub_lock_acquire_recursive; - s_gcov_stub_table._lock_release_recursive = &gcov_stub_lock_release_recursive; - s_gcov_stub_table._lock_try_acquire_recursive = &gcov_stub_lock_try_acquire_recursive, - syscall_table_ptr_pro = &s_gcov_stub_table; -#if portNUM_PROCESSORS > 1 - syscall_table_ptr_app = &s_gcov_stub_table; -#endif - stderr = (FILE*) &__sf_fake_stderr; - stdout = (FILE*) &__sf_fake_stdout; __gcov_dump(); // reset dump status to allow incremental data accumulation __gcov_reset(); - stdout = old_stdout; - stderr = old_stderr; - syscall_table_ptr_pro = old_tables[0]; -#if portNUM_PROCESSORS > 1 - syscall_table_ptr_app = old_tables[1]; -#endif - ESP_EARLY_LOGV(TAG, "Free apptrace down buf"); free(down_buf); + stderr = old_stderr; + stdout = old_stdout; ESP_EARLY_LOGV(TAG, "Finish file transfer session"); - ret = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX); - if (ret != ESP_OK) { - ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret); + dump_result = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX); + if (dump_result != ESP_OK) { + ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", dump_result); + } + +gcov_exit: + ESP_EARLY_LOGV(TAG, "dump_result %d", dump_result); + if (running) { + *running = false; + } + vTaskDelete(NULL); +} + +static void gcov_create_task_hook(void) +{ + if (s_create_gcov_task) { + xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", 2048, &s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0); + s_create_gcov_task = false; } - ESP_EARLY_LOGV(TAG, "exit %d", ret); - return ret; } /** * @brief Triggers gcov info dump task * This function is to be called by OpenOCD, not by normal user code. - * TODO: what about interrupted flash access (when cache disabled)??? + * TODO: what about interrupted flash access (when cache disabled) * * @return ESP_OK on success, otherwise see esp_err_t */ static int esp_dbg_stub_gcov_entry(void) { - s_do_dump = true; + /* we are in isr context here */ + s_create_gcov_task = true; return ESP_OK; } @@ -132,35 +111,25 @@ int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused))) uint32_t capabilities = 0; ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__); esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry); - return 0; + if (esp_dbg_stub_entry_get(ESP_DBG_STUB_CAPABILITIES, &capabilities) == ESP_OK) { + esp_dbg_stub_entry_set(ESP_DBG_STUB_CAPABILITIES, capabilities | ESP_DBG_STUB_CAP_GCOV_TASK); + } + esp_register_freertos_tick_hook(gcov_create_task_hook); + return ESP_OK; } void esp_gcov_dump(void) { - // disable IRQs on this CPU, other CPU is halted by OpenOCD - unsigned irq_state = portENTER_CRITICAL_NESTED(); -#if !CONFIG_FREERTOS_UNICORE - int other_core = xPortGetCoreID() ? 0 : 1; - esp_cpu_stall(other_core); -#endif while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) { - wdt_hal_context_t twdt = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0}; - wdt_hal_context_t iwdt = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1}; - //Feed the Task Watchdog (TG0) to prevent it from timing out - wdt_hal_write_protect_disable(&twdt); - wdt_hal_feed(&twdt); - wdt_hal_write_protect_enable(&twdt); - //Likewise, feed the Interrupt Watchdog (TG1) to prevent a reboot - wdt_hal_write_protect_disable(&iwdt); - wdt_hal_feed(&iwdt); - wdt_hal_write_protect_enable(&iwdt); + vTaskDelay(pdMS_TO_TICKS(10)); } - esp_dbg_stub_gcov_dump_do(); -#if !CONFIG_FREERTOS_UNICORE - esp_cpu_unstall(other_core); -#endif - portEXIT_CRITICAL_NESTED(irq_state); + /* We are not in isr context here. Waiting for the completion is safe */ + s_create_gcov_task = true; + s_gcov_task_running = true; + while (s_gcov_task_running) { + vTaskDelay(pdMS_TO_TICKS(10)); + } } void *gcov_rtio_fopen(const char *path, const char *mode) @@ -179,7 +148,7 @@ int gcov_rtio_fclose(void *stream) size_t gcov_rtio_fread(void *ptr, size_t size, size_t nmemb, void *stream) { - ESP_EARLY_LOGV(TAG, "%s read %u", __FUNCTION__, size*nmemb); + ESP_EARLY_LOGV(TAG, "%s read %u", __FUNCTION__, size * nmemb); size_t sz = esp_apptrace_fread(ESP_APPTRACE_DEST_TRAX, ptr, size, nmemb, stream); ESP_EARLY_LOGV(TAG, "%s actually read %u", __FUNCTION__, sz); return sz; From d63ff8cb7a97e4fa04bb3789380fe595099bdfee Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Thu, 3 Jun 2021 21:13:57 +0300 Subject: [PATCH 3/8] gcov: readme update for ESP32-S2 --- examples/system/gcov/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/system/gcov/README.md b/examples/system/gcov/README.md index e35a5340de..256ae5cdb2 100644 --- a/examples/system/gcov/README.md +++ b/examples/system/gcov/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | -| ----------------- | ----- | +| Supported Targets | ESP32 | ESP32-S2 | +| ----------------- | ----- | -------- | # Blink Example With Coverage Info (Gcov) @@ -16,10 +16,10 @@ This example implements a simple blink application but with code coverage enable ### Hardware Required -To run this example, you need an ESP32 dev board connected to a JTAG adapter, which can come in the following forms: +To run this example, you need a supported dev board connected to a JTAG adapter, which can come in the following forms: * [ESP-WROVER-KIT](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/modules-and-boards.html#esp-wrover-kit-v4-1) which integrates an on-board JTAG adapter. Ensure that the [required jumpers to enable JTAG are connected](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/get-started-wrover-kit.html#setup-options) on the WROVER-KIT. -* ESP32 core board (e.g. ESP32-DevKitC) can also work as long as you connect it to an external JTAG adapter (e.g. FT2232H, J-LINK). +* ESP32 or ESP32-S2 core board (e.g. ESP32-DevKitC, [ESP32-S2-Saola-1](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html)) can also work as long as you connect it to an external JTAG adapter (e.g. FT2232H, J-LINK). This example will assume that that an ESP-WROVER-KIT is used. From 886ea8d33b192a477b728bf4bc45406b14bb9d36 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Tue, 29 Jun 2021 13:12:01 +0300 Subject: [PATCH 4/8] gcov: add gcov callback into the ipc task --- components/app_trace/CMakeLists.txt | 2 +- components/app_trace/gcov/gcov_rtio.c | 26 ++++++++++++--- components/esp_common/src/dbg_stubs.c | 1 + components/esp_ipc/ipc.c | 48 ++++++++++++++++++++++----- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/components/app_trace/CMakeLists.txt b/components/app_trace/CMakeLists.txt index 0861299b2c..7153ffcc9e 100644 --- a/components/app_trace/CMakeLists.txt +++ b/components/app_trace/CMakeLists.txt @@ -30,7 +30,7 @@ endif() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" - PRIV_REQUIRES soc + PRIV_REQUIRES soc esp_ipc LDFRAGMENTS linker.lf) diff --git a/components/app_trace/gcov/gcov_rtio.c b/components/app_trace/gcov/gcov_rtio.c index dcfdf23a2d..f789a004f9 100644 --- a/components/app_trace/gcov/gcov_rtio.c +++ b/components/app_trace/gcov/gcov_rtio.c @@ -24,6 +24,7 @@ #include "esp_app_trace.h" #include "esp_freertos_hooks.h" #include "esp_private/dbg_stubs.h" +#include "esp_ipc.h" #include "hal/wdt_hal.h" #if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/libc_stubs.h" @@ -49,6 +50,8 @@ void gcov_dump_task(void *pvParameter) int dump_result = 0; bool *running = (bool *)pvParameter; + ESP_EARLY_LOGV(TAG, "%s stack use in %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL)); + ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE); void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE); if (down_buf == NULL) { @@ -81,14 +84,25 @@ gcov_exit: if (running) { *running = false; } + + ESP_EARLY_LOGV(TAG, "%s stack use out %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL)); + vTaskDelete(NULL); } -static void gcov_create_task_hook(void) +void gcov_create_task(void *arg) { + ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__); + xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", 2048, (void *)&s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0); +} + +void gcov_create_task_tick_hook(void) +{ + extern esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void* arg); if (s_create_gcov_task) { - xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", 2048, &s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0); - s_create_gcov_task = false; + if (esp_ipc_start_gcov_from_isr(xPortGetCoreID(), &gcov_create_task, NULL) == ESP_OK) { + s_create_gcov_task = false; + } } } @@ -114,19 +128,21 @@ int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused))) if (esp_dbg_stub_entry_get(ESP_DBG_STUB_CAPABILITIES, &capabilities) == ESP_OK) { esp_dbg_stub_entry_set(ESP_DBG_STUB_CAPABILITIES, capabilities | ESP_DBG_STUB_CAP_GCOV_TASK); } - esp_register_freertos_tick_hook(gcov_create_task_hook); + esp_register_freertos_tick_hook(gcov_create_task_tick_hook); return ESP_OK; } void esp_gcov_dump(void) { + ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__); + while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) { vTaskDelay(pdMS_TO_TICKS(10)); } /* We are not in isr context here. Waiting for the completion is safe */ - s_create_gcov_task = true; s_gcov_task_running = true; + s_create_gcov_task = true; while (s_gcov_task_running) { vTaskDelay(pdMS_TO_TICKS(10)); } diff --git a/components/esp_common/src/dbg_stubs.c b/components/esp_common/src/dbg_stubs.c index e4c65c22e2..a1740c23e6 100644 --- a/components/esp_common/src/dbg_stubs.c +++ b/components/esp_common/src/dbg_stubs.c @@ -82,6 +82,7 @@ void esp_dbg_stubs_init(void) ESP_LOGV(TAG, "%s stubs %x", __func__, eri_read(ESP_DBG_STUBS_TRAX_REG)); } +// TODO: add lock mechanism. Not now but in the future ESP_DBG_STUB_CAPABILITIES can be set from different places. esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry) { if (id < ESP_DBG_STUB_ENTRY_FIRST || id >= ESP_DBG_STUB_ENTRY_MAX) { diff --git a/components/esp_ipc/ipc.c b/components/esp_ipc/ipc.c index a9a7ec5558..d2d75b8a09 100644 --- a/components/esp_ipc/ipc.c +++ b/components/esp_ipc/ipc.c @@ -28,7 +28,7 @@ static TaskHandle_t s_ipc_task_handle[portNUM_PROCESSORS]; static SemaphoreHandle_t s_ipc_mutex[portNUM_PROCESSORS]; // This mutex is used as a global lock for esp_ipc_* APIs static SemaphoreHandle_t s_ipc_sem[portNUM_PROCESSORS]; // Two semaphores used to wake each of ipc tasks static SemaphoreHandle_t s_ipc_ack[portNUM_PROCESSORS]; // Semaphore used to acknowledge that task was woken up, - // or function has finished running + // or function has finished running static volatile esp_ipc_func_t s_func[portNUM_PROCESSORS]; // Function which should be called by high priority task static void * volatile s_func_arg[portNUM_PROCESSORS]; // Argument to pass into s_func typedef enum { @@ -40,6 +40,11 @@ static volatile esp_ipc_wait_t s_ipc_wait[portNUM_PROCESSORS];// This variable t // s_ipc_ack semaphore: before s_func is called, or // after it returns +#if CONFIG_APPTRACE_GCOV_ENABLE +static volatile esp_ipc_func_t s_gcov_func = NULL; // Gcov dump starter function which should be called by high priority task +static void * volatile s_gcov_func_arg; // Argument to pass into s_gcov_func +#endif + static void IRAM_ATTR ipc_task(void* arg) { const uint32_t cpuid = (uint32_t) arg; @@ -53,16 +58,26 @@ static void IRAM_ATTR ipc_task(void* arg) abort(); } - esp_ipc_func_t func = s_func[cpuid]; - void* arg = s_func_arg[cpuid]; +#if CONFIG_APPTRACE_GCOV_ENABLE + if (s_gcov_func) { + (*s_gcov_func)(s_gcov_func_arg); + s_gcov_func = NULL; + } +#endif + if (s_func[cpuid]) { + esp_ipc_func_t func = s_func[cpuid]; + void* arg = s_func_arg[cpuid]; - if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_START) { - xSemaphoreGive(s_ipc_ack[cpuid]); - } - (*func)(arg); - if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_END) { - xSemaphoreGive(s_ipc_ack[cpuid]); + if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_START) { + xSemaphoreGive(s_ipc_ack[cpuid]); + } + (*func)(arg); + if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_END) { + xSemaphoreGive(s_ipc_ack[cpuid]); + } + s_func[cpuid] = NULL; } + } // TODO: currently this is unreachable code. Introduce esp_ipc_uninit // function which will signal to both tasks that they can shut down. @@ -87,6 +102,7 @@ static void esp_ipc_init(void) __attribute__((constructor)); static void esp_ipc_init(void) { char task_name[15]; + for (int i = 0; i < portNUM_PROCESSORS; ++i) { snprintf(task_name, sizeof(task_name), "ipc%d", i); s_ipc_mutex[i] = xSemaphoreCreateMutex(); @@ -144,3 +160,17 @@ esp_err_t esp_ipc_call_blocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg) return esp_ipc_call_and_wait(cpu_id, func, arg, IPC_WAIT_FOR_END); } +// currently this is only called from gcov component +#if CONFIG_APPTRACE_GCOV_ENABLE +esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void* arg) +{ + if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { + return ESP_ERR_INVALID_STATE; + } + s_gcov_func = func; + s_gcov_func_arg = arg; + xSemaphoreGiveFromISR(s_ipc_sem[cpu_id], NULL); + + return ESP_OK; +} +#endif From 5ad1e020ce8b8fe36eb52cb4452754d9a09e7987 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Fri, 16 Jul 2021 21:04:33 +0300 Subject: [PATCH 5/8] gcov: add stub table size entry --- components/app_trace/gcov/gcov_rtio.c | 4 ++-- components/esp_common/include/esp_private/dbg_stubs.h | 3 ++- components/esp_common/src/dbg_stubs.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/components/app_trace/gcov/gcov_rtio.c b/components/app_trace/gcov/gcov_rtio.c index f789a004f9..7a2d123cff 100644 --- a/components/app_trace/gcov/gcov_rtio.c +++ b/components/app_trace/gcov/gcov_rtio.c @@ -125,8 +125,8 @@ int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused))) uint32_t capabilities = 0; ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__); esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry); - if (esp_dbg_stub_entry_get(ESP_DBG_STUB_CAPABILITIES, &capabilities) == ESP_OK) { - esp_dbg_stub_entry_set(ESP_DBG_STUB_CAPABILITIES, capabilities | ESP_DBG_STUB_CAP_GCOV_TASK); + if (esp_dbg_stub_entry_get(ESP_DBG_STUB_ENTRY_CAPABILITIES, &capabilities) == ESP_OK) { + esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_CAPABILITIES, capabilities | ESP_DBG_STUB_CAP_GCOV_TASK); } esp_register_freertos_tick_hook(gcov_create_task_tick_hook); return ESP_OK; diff --git a/components/esp_common/include/esp_private/dbg_stubs.h b/components/esp_common/include/esp_private/dbg_stubs.h index 454c3418f9..65fff455cb 100644 --- a/components/esp_common/include/esp_private/dbg_stubs.h +++ b/components/esp_common/include/esp_private/dbg_stubs.h @@ -21,11 +21,12 @@ */ typedef enum { ESP_DBG_STUB_MAGIC_NUM, + ESP_DBG_STUB_TABLE_SIZE, ESP_DBG_STUB_CONTROL_DATA, ///< stubs descriptor entry ESP_DBG_STUB_ENTRY_FIRST, ESP_DBG_STUB_ENTRY_GCOV ///< GCOV entry = ESP_DBG_STUB_ENTRY_FIRST, - ESP_DBG_STUB_CAPABILITIES, + ESP_DBG_STUB_ENTRY_CAPABILITIES, ESP_DBG_STUB_ENTRY_MAX } esp_dbg_stub_id_t; diff --git a/components/esp_common/src/dbg_stubs.c b/components/esp_common/src/dbg_stubs.c index a1740c23e6..04cd11398e 100644 --- a/components/esp_common/src/dbg_stubs.c +++ b/components/esp_common/src/dbg_stubs.c @@ -77,12 +77,13 @@ void esp_dbg_stubs_init(void) s_dbg_stubs_ctl_data.data_free = (uint32_t)esp_dbg_stubs_data_free; s_stub_entry[ESP_DBG_STUB_MAGIC_NUM] = ESP_DBG_STUB_MAGIC_NUM_VAL; + s_stub_entry[ESP_DBG_STUB_TABLE_SIZE] = ESP_DBG_STUB_ENTRY_MAX; s_stub_entry[ESP_DBG_STUB_CONTROL_DATA] = (uint32_t)&s_dbg_stubs_ctl_data; eri_write(ESP_DBG_STUBS_TRAX_REG, (uint32_t)s_stub_entry); ESP_LOGV(TAG, "%s stubs %x", __func__, eri_read(ESP_DBG_STUBS_TRAX_REG)); } -// TODO: add lock mechanism. Not now but in the future ESP_DBG_STUB_CAPABILITIES can be set from different places. +// TODO: add lock mechanism. Not now but in the future ESP_DBG_STUB_ENTRY_CAPABILITIES can be set from different places. esp_err_t esp_dbg_stub_entry_set(esp_dbg_stub_id_t id, uint32_t entry) { if (id < ESP_DBG_STUB_ENTRY_FIRST || id >= ESP_DBG_STUB_ENTRY_MAX) { From dc25973825f7ce5619d1e50fde3d79e56cf24997 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Thu, 12 Aug 2021 08:52:15 +0300 Subject: [PATCH 6/8] ipc: enable ipc task at single core for gcov dump --- components/esp_ipc/ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_ipc/ipc.c b/components/esp_ipc/ipc.c index d2d75b8a09..fce1462c17 100644 --- a/components/esp_ipc/ipc.c +++ b/components/esp_ipc/ipc.c @@ -173,4 +173,4 @@ esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void return ESP_OK; } -#endif +#endif From e662d90e9f70b702ed602c430f55cb26118e691b Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Fri, 13 Aug 2021 12:06:12 +0300 Subject: [PATCH 7/8] gcov: enable single core tests --- examples/system/gcov/sdkconfig.ci | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/system/gcov/sdkconfig.ci diff --git a/examples/system/gcov/sdkconfig.ci b/examples/system/gcov/sdkconfig.ci new file mode 100644 index 0000000000..f0b0b5e03d --- /dev/null +++ b/examples/system/gcov/sdkconfig.ci @@ -0,0 +1 @@ +CONFIG_FREERTOS_UNICORE=y From e4fdf07acb4a639e6ef717e65149845593225d11 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Mon, 23 Aug 2021 17:17:19 +0300 Subject: [PATCH 8/8] esp_ipc: fix race condition in ipc task --- components/asio/asio | 2 +- components/bt/controller/lib | 2 +- components/bt/controller/lib_esp32c3_family | 1 - components/bt/host/nimble/nimble | 2 +- components/cbor/tinycbor | 2 +- components/esp_ipc/ipc.c | 2 +- components/esp_wifi/lib | 2 +- components/esptool_py/esptool | 2 +- components/lwip/lwip | 2 +- components/mqtt/esp-mqtt | 2 +- components/nghttp/nghttp2 | 2 +- components/tinyusb/tinyusb | 2 +- .../secure_element/atecc608_ecdsa/components/esp-cryptoauthlib | 2 +- 13 files changed, 12 insertions(+), 13 deletions(-) delete mode 160000 components/bt/controller/lib_esp32c3_family diff --git a/components/asio/asio b/components/asio/asio index f31694c9f1..3b66e5b051 160000 --- a/components/asio/asio +++ b/components/asio/asio @@ -1 +1 @@ -Subproject commit f31694c9f1746ba189a4bcae2e34db15135ddb22 +Subproject commit 3b66e5b051381fb70de9c2791df70a06181c64e3 diff --git a/components/bt/controller/lib b/components/bt/controller/lib index cfbb0571fb..fb49791b7c 160000 --- a/components/bt/controller/lib +++ b/components/bt/controller/lib @@ -1 +1 @@ -Subproject commit cfbb0571fb424ca4a68a0c172cbff1fdc79fd91b +Subproject commit fb49791b7c1a8a35f06e68124c90022667b4cff1 diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family deleted file mode 160000 index 7ad49c38b8..0000000000 --- a/components/bt/controller/lib_esp32c3_family +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7ad49c38b893952bbed155ede2c7684f0307f6d3 diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index aef55bbf63..33179b3316 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit aef55bbf636ed580d4d6408a5c2e75d1f70a875e +Subproject commit 33179b331639a6157d9196b87a3e2e53f86c7072 diff --git a/components/cbor/tinycbor b/components/cbor/tinycbor index 085ca40781..d2dd95cb88 160000 --- a/components/cbor/tinycbor +++ b/components/cbor/tinycbor @@ -1 +1 @@ -Subproject commit 085ca40781f7c39febe6d14fb7e5cba342e1804b +Subproject commit d2dd95cb8841d88d5a801e3ef9c328fd6200e7bd diff --git a/components/esp_ipc/ipc.c b/components/esp_ipc/ipc.c index fce1462c17..4f6a4092ee 100644 --- a/components/esp_ipc/ipc.c +++ b/components/esp_ipc/ipc.c @@ -75,7 +75,6 @@ static void IRAM_ATTR ipc_task(void* arg) if (s_ipc_wait[cpuid] == IPC_WAIT_FOR_END) { xSemaphoreGive(s_ipc_ack[cpuid]); } - s_func[cpuid] = NULL; } } @@ -142,6 +141,7 @@ static esp_err_t esp_ipc_call_and_wait(uint32_t cpu_id, esp_ipc_func_t func, voi s_ipc_wait[cpu_id] = wait_for; xSemaphoreGive(s_ipc_sem[cpu_id]); xSemaphoreTake(s_ipc_ack[cpu_id], portMAX_DELAY); + s_func[cpu_id] = NULL; #ifdef CONFIG_ESP_IPC_USES_CALLERS_PRIORITY xSemaphoreGive(s_ipc_mutex[cpu_id]); #else diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index e6945e61f7..fbcdc77c26 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit e6945e61f7c63545a77b0575c3770a85b4de948e +Subproject commit fbcdc77c26eb0d716927c8bc7d73dbec9a8987c1 diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 2583017317..4698b39673 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 258301731780493365bb249553ae7855a3e753ea +Subproject commit 4698b396730b23fb4aab023c5fb1744db957fc4c diff --git a/components/lwip/lwip b/components/lwip/lwip index 2195f7416f..2c9c531f0a 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 2195f7416fb3136831babf3e96c027a73075bd4f +Subproject commit 2c9c531f0a7e0ee536db9de4f9dc54e453712087 diff --git a/components/mqtt/esp-mqtt b/components/mqtt/esp-mqtt index f10321a53b..9ea804e0ab 160000 --- a/components/mqtt/esp-mqtt +++ b/components/mqtt/esp-mqtt @@ -1 +1 @@ -Subproject commit f10321a53b53a146ee299cfecc320b89c0cf6611 +Subproject commit 9ea804e0ab5368d5ab53ae2301a5fec9d1f12f1a diff --git a/components/nghttp/nghttp2 b/components/nghttp/nghttp2 index 8f7b008b15..3bcc416e13 160000 --- a/components/nghttp/nghttp2 +++ b/components/nghttp/nghttp2 @@ -1 +1 @@ -Subproject commit 8f7b008b158e12de0e58247afd170f127dbb6456 +Subproject commit 3bcc416e13cc790e2fb45fcfe9111d38609c5032 diff --git a/components/tinyusb/tinyusb b/components/tinyusb/tinyusb index 334e95fac5..28f89e1347 160000 --- a/components/tinyusb/tinyusb +++ b/components/tinyusb/tinyusb @@ -1 +1 @@ -Subproject commit 334e95fac52a607150157ae5199a19e11f843982 +Subproject commit 28f89e13473d40637574bcbfe4142633b39899fd diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib b/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib index bb672b0437..c3d3a69021 160000 --- a/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib +++ b/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib @@ -1 +1 @@ -Subproject commit bb672b0437485fc7420add178299631692b15ac3 +Subproject commit c3d3a69021cfec3236ca2c0b63be4048ec6643a4