From 5a7e835373aac4ec962812b73b1ce6c1a8927760 Mon Sep 17 00:00:00 2001 From: zwx Date: Tue, 23 Jan 2024 16:53:50 +0800 Subject: [PATCH 01/33] fix(phy): fix pll track when enabling and disabling PHY frequently --- components/esp_phy/Kconfig | 6 +++ components/esp_phy/include/esp_private/phy.h | 8 ++- components/esp_phy/src/phy_common.c | 51 +++++++++++++------- components/esp_phy/src/phy_init.c | 4 ++ components/esp_phy/src/phy_init_esp32hxx.c | 20 +++----- 5 files changed, 58 insertions(+), 31 deletions(-) diff --git a/components/esp_phy/Kconfig b/components/esp_phy/Kconfig index 59d7fe783d73..7a2b7a811ff9 100644 --- a/components/esp_phy/Kconfig +++ b/components/esp_phy/Kconfig @@ -154,4 +154,10 @@ menu "PHY" high interference, enable this option will sacrifice Wi-Fi OFDM receive performance. But to guarantee 11b receive performance serves as a bottom line in this case. + config ESP_PHY_PLL_TRACK_DEBUG + bool "Enable pll track logging" + default n + help + If enabled, there will be some logs while pll tracking + endmenu # PHY diff --git a/components/esp_phy/include/esp_private/phy.h b/components/esp_phy/include/esp_private/phy.h index 8968e0024610..bee81286a49b 100644 --- a/components/esp_phy/include/esp_private/phy.h +++ b/components/esp_phy/include/esp_private/phy.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -174,6 +174,12 @@ esp_phy_modem_t phy_get_modem_flag(void); * */ _lock_t phy_get_lock(void); + +/** + * @brief Call this funnction to track pll immediately. + * + */ +void phy_track_pll(void); #ifdef __cplusplus } #endif diff --git a/components/esp_phy/src/phy_common.c b/components/esp_phy/src/phy_common.c index ad4a3b388e3b..759f3b5de869 100644 --- a/components/esp_phy/src/phy_common.c +++ b/components/esp_phy/src/phy_common.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "esp_log.h" #include "esp_timer.h" #include "esp_phy_init.h" #include "esp_private/phy.h" @@ -20,6 +21,7 @@ static volatile int64_t s_wifi_prev_timestamp; static volatile int64_t s_bt_154_prev_timestamp; #endif #define PHY_TRACK_PLL_PERIOD_IN_US 1000000 +static void phy_track_pll_internal(void); #if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED || CONFIG_ESP_WIFI_ENABLED bool phy_enabled_modem_contains(esp_phy_modem_t modem) @@ -28,7 +30,28 @@ bool phy_enabled_modem_contains(esp_phy_modem_t modem) } #endif -static void phy_track_pll(void) +void phy_track_pll(void) +{ + // Light sleep scenario: enabling and disabling PHY frequently, the timer will not get triggered. + // Using a variable to record the previously tracked time when PLL was last called. + // If the duration is larger than PHY_TRACK_PLL_PERIOD_IN_US, then track PLL. + bool need_track_pll = false; +#if CONFIG_ESP_WIFI_ENABLED + if (phy_enabled_modem_contains(PHY_MODEM_WIFI)) { + need_track_pll = need_track_pll || ((esp_timer_get_time() - s_wifi_prev_timestamp) > PHY_TRACK_PLL_PERIOD_IN_US); + } +#endif +#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED + if (phy_enabled_modem_contains(PHY_MODEM_BT | PHY_MODEM_IEEE802154)) { + need_track_pll = need_track_pll || ((esp_timer_get_time() - s_bt_154_prev_timestamp) > PHY_TRACK_PLL_PERIOD_IN_US); + } +#endif + if (need_track_pll) { + phy_track_pll_internal(); + } +} + +static void phy_track_pll_internal(void) { bool wifi_track_pll = false; bool ble_154_track_pll = false; @@ -46,6 +69,14 @@ static void phy_track_pll(void) } #endif if (wifi_track_pll || ble_154_track_pll) { +#if CONFIG_ESP_PHY_PLL_TRACK_DEBUG +#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED + ESP_LOGI("PLL_TRACK", "BT or IEEE802154 tracks PLL: %s", ble_154_track_pll ? "True" : "False"); +#endif +#if CONFIG_ESP_WIFI_ENABLED + ESP_LOGI("PLL_TRACK", "Wi-Fi tracks PLL: %s", wifi_track_pll ? "True" : "False"); +#endif +#endif phy_param_track_tot(wifi_track_pll, ble_154_track_pll); } } @@ -54,26 +85,12 @@ static void phy_track_pll_timer_callback(void* arg) { _lock_t phy_lock = phy_get_lock(); _lock_acquire(&phy_lock); - phy_track_pll(); + phy_track_pll_internal(); _lock_release(&phy_lock); } void phy_track_pll_init(void) { - // Light sleep scenario: enabling and disabling PHY frequently, the timer will not get triggered. - // Using a variable to record the previously tracked time when PLL was last called. - // If the duration is larger than PHY_TRACK_PLL_PERIOD_IN_US, then track PLL. - bool need_track_pll = false; -#if CONFIG_ESP_WIFI_ENABLED - need_track_pll = need_track_pll || ((esp_timer_get_time() - s_wifi_prev_timestamp) > PHY_TRACK_PLL_PERIOD_IN_US); -#endif -#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED - need_track_pll = need_track_pll || ((esp_timer_get_time() - s_bt_154_prev_timestamp) > PHY_TRACK_PLL_PERIOD_IN_US); -#endif - if (need_track_pll) { - phy_track_pll(); - } - const esp_timer_create_args_t phy_track_pll_timer_args = { .callback = &phy_track_pll_timer_callback, .name = "phy-track-pll-timer" diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index cae9c2fbb4c8..25df1673d46e 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -278,6 +278,10 @@ void esp_phy_enable(esp_phy_modem_t modem) #endif } phy_set_modem_flag(modem); +#if !CONFIG_IDF_TARGET_ESP32 + // Immediately track pll when phy enabled. + phy_track_pll(); +#endif _lock_release(&s_phy_access_lock); } diff --git a/components/esp_phy/src/phy_init_esp32hxx.c b/components/esp_phy/src/phy_init_esp32hxx.c index 9639ffccd349..d0d3e2a20b98 100644 --- a/components/esp_phy/src/phy_init_esp32hxx.c +++ b/components/esp_phy/src/phy_init_esp32hxx.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,7 +21,6 @@ extern void phy_version_print(void); static _lock_t s_phy_access_lock; /* Reference count of enabling PHY */ -static uint8_t s_phy_access_ref = 0; static bool s_phy_is_enabled = false; uint32_t IRAM_ATTR phy_enter_critical(void) @@ -49,8 +48,7 @@ void IRAM_ATTR phy_exit_critical(uint32_t level) void esp_phy_enable(esp_phy_modem_t modem) { _lock_acquire(&s_phy_access_lock); - phy_set_modem_flag(modem); - if (s_phy_access_ref == 0) { + if (phy_get_modem_flag() == 0) { #if SOC_MODEM_CLOCK_IS_INDEPENDENT modem_clock_module_enable(PERIPH_PHY_MODULE); #endif @@ -63,9 +61,9 @@ void esp_phy_enable(esp_phy_modem_t modem) } phy_track_pll_init(); } - - s_phy_access_ref++; - + phy_set_modem_flag(modem); + // Immediately track pll when phy enabled. + phy_track_pll(); _lock_release(&s_phy_access_lock); } @@ -73,11 +71,9 @@ void esp_phy_disable(esp_phy_modem_t modem) { _lock_acquire(&s_phy_access_lock); - if (s_phy_access_ref) { - s_phy_access_ref--; - } + phy_clr_modem_flag(modem); + if (phy_get_modem_flag() == 0) { - if (s_phy_access_ref == 0) { phy_track_pll_deinit(); phy_close_rf(); phy_xpd_tsens(); @@ -85,8 +81,6 @@ void esp_phy_disable(esp_phy_modem_t modem) modem_clock_module_disable(PERIPH_PHY_MODULE); #endif } - - phy_clr_modem_flag(modem); _lock_release(&s_phy_access_lock); } From 18f5188f80357d98b09d66dffbaef978a76ee90b Mon Sep 17 00:00:00 2001 From: zwx Date: Mon, 5 Feb 2024 15:41:45 +0800 Subject: [PATCH 02/33] feat(openthread): enable RCP uart configuration for BR by default --- examples/openthread/ot_br/sdkconfig.defaults | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/openthread/ot_br/sdkconfig.defaults b/examples/openthread/ot_br/sdkconfig.defaults index c223da9ab8fd..6620bfa46b18 100644 --- a/examples/openthread/ot_br/sdkconfig.defaults +++ b/examples/openthread/ot_br/sdkconfig.defaults @@ -24,6 +24,7 @@ CONFIG_MBEDTLS_ECJPAKE_C=y # CONFIG_OPENTHREAD_ENABLED=y CONFIG_OPENTHREAD_BORDER_ROUTER=y +CONFIG_OPENTHREAD_RADIO_SPINEL_UART=y # end of OpenThread # From 88e4fd9ac10a9fe14f67715e8430554387094c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Wed, 7 Feb 2024 17:17:45 +0100 Subject: [PATCH 03/33] fix(vfs): Add missing lock release in vfs_fat_truncate --- components/fatfs/vfs/vfs_fat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index 310d62502047..c455e72baf5b 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -1040,6 +1040,7 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length) res = f_truncate(file); if (res != FR_OK) { + _lock_release(&fat_ctx->lock); ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); errno = fresult_to_errno(res); ret = -1; From 8d3e79971e0c619b4d751af1371285b0d1cebc05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Fri, 16 Feb 2024 03:37:59 +0100 Subject: [PATCH 04/33] feat(fatfs): Add f_expand function as esp_vfs_fat_create_contiguous_file Add esp_vfs_fat_test_contiguous_file to test it --- components/fatfs/src/ffconf.h | 2 +- .../flash_wl/main/test_fatfs_flash_wl.c | 9 ++ .../test_apps/sdcard/main/test_fatfs_sdmmc.c | 10 ++ .../test_fatfs_common/test_fatfs_common.c | 25 ++++ .../test_fatfs_common/test_fatfs_common.h | 4 + components/fatfs/vfs/esp_vfs_fat.h | 32 +++++ components/fatfs/vfs/vfs_fat.c | 135 ++++++++++++++++++ 7 files changed, 216 insertions(+), 1 deletion(-) diff --git a/components/fatfs/src/ffconf.h b/components/fatfs/src/ffconf.h index 8d579002b6cd..62cbeb942380 100644 --- a/components/fatfs/src/ffconf.h +++ b/components/fatfs/src/ffconf.h @@ -40,7 +40,7 @@ /* This option switches fast seek function. (0:Disable or 1:Enable) */ -#define FF_USE_EXPAND 0 +#define FF_USE_EXPAND 1 /* This option switches f_expand function. (0:Disable or 1:Enable) */ diff --git a/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c b/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c index 5374b88de3b2..155769ceb0c6 100644 --- a/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c +++ b/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c @@ -194,6 +194,15 @@ TEST_CASE("(WL) can truncate", "[fatfs][wear_levelling]") test_teardown(); } +#if FF_USE_EXPAND +TEST_CASE("(WL) can esp_vfs_fat_create_contiguous_file", "[fatfs][wear_levelling]") +{ + test_setup(); + test_fatfs_create_contiguous_file("/spiflash", "/spiflash/expand.txt"); + test_teardown(); +} +#endif + TEST_CASE("(WL) stat returns correct values", "[fatfs][wear_levelling]") { test_setup(); diff --git a/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c index bfda90cf456a..6d66dcd6de3d 100644 --- a/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c +++ b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c @@ -198,6 +198,16 @@ TEST_CASE("(SD) can ftruncate", "[fatfs][sdmmc]") test_teardown_sdmmc(card); } +#if FF_USE_EXPAND +TEST_CASE("(SD) can esp_vfs_fat_create_contiguous_file", "[fatfs][sdmmc]") +{ + sdmmc_card_t *card = NULL; + test_setup_sdmmc(&card); + test_fatfs_create_contiguous_file("/sdcard", "/sdcard/expand.txt"); + test_teardown_sdmmc(card); +} +#endif + TEST_CASE("(SD) stat returns correct values", "[fatfs][sdmmc]") { sdmmc_card_t *card = NULL; diff --git a/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c index 77372fbbd546..aa7be418c09d 100644 --- a/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c +++ b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c @@ -1011,3 +1011,28 @@ void test_fatfs_info(const char* base_path, const char* filepath) ESP_LOGD("fatfs info", "total_bytes=%llu, free_bytes_after_delete=%llu", total_bytes, free_bytes_new); TEST_ASSERT_EQUAL(free_bytes, free_bytes_new); } + +#if FF_USE_EXPAND +void test_fatfs_create_contiguous_file(const char* base_path, const char* full_path) +{ + size_t desired_file_size = 64; + + // Don't check for errors, file may not exist at first + remove(full_path); // esp_vfs_fat_create_contiguous_file will fail if the file already exists + + esp_err_t err = esp_vfs_fat_create_contiguous_file(base_path, full_path, desired_file_size, true); + TEST_ASSERT_EQUAL(ESP_OK, err); + + struct stat st; + size_t size; + + stat(full_path, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(desired_file_size, size); + + bool is_contiguous = false; + err = esp_vfs_fat_test_contiguous_file(base_path, full_path, &is_contiguous); + TEST_ASSERT_EQUAL(ESP_OK, err); + TEST_ASSERT_TRUE(is_contiguous); +} +#endif diff --git a/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h index dad352e2c43b..e7366fe1e110 100644 --- a/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h +++ b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h @@ -76,3 +76,7 @@ void test_leading_spaces(void); void test_fatfs_rw_speed(const char* filename, void* buf, size_t buf_size, size_t file_size, bool write); void test_fatfs_info(const char* base_path, const char* filepath); + +#if FF_USE_EXPAND +void test_fatfs_create_contiguous_file(const char* base_path, const char* full_path); +#endif diff --git a/components/fatfs/vfs/esp_vfs_fat.h b/components/fatfs/vfs/esp_vfs_fat.h index e89188b2d1b9..21ab1df3604c 100644 --- a/components/fatfs/vfs/esp_vfs_fat.h +++ b/components/fatfs/vfs/esp_vfs_fat.h @@ -394,6 +394,38 @@ esp_err_t esp_vfs_fat_spiflash_unmount_ro(const char* base_path, const char* par */ esp_err_t esp_vfs_fat_info(const char* base_path, uint64_t* out_total_bytes, uint64_t* out_free_bytes); +/** + * @brief Create a file with contiguous space at given path + * + * @note The file cannot exist before calling this function (or the file size has to be 0) + * For more information see documentation for `f_expand` from FATFS library + * + * @param base_path Base path of the partition examined (e.g. "/spiflash") + * @param full_path Full path of the file (e.g. "/spiflash/ABC.TXT") + * @param size File size expanded to, number of bytes in size to prepare or allocate for the file + * @param alloc_now True == allocate space now, false == prepare to allocate -- see `f_expand` from FATFS + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if invalid arguments (e.g. any of arguments are NULL or size lower or equal to 0) + * - ESP_ERR_INVALID_STATE if partition not found + * - ESP_FAIL if another FRESULT error (saved in errno) + */ +esp_err_t esp_vfs_fat_create_contiguous_file(const char* base_path, const char* full_path, uint64_t size, bool alloc_now); + +/** + * @brief Test if a file is contiguous in the FAT filesystem + * + * @param base_path Base path of the partition examined (e.g. "/spiflash") + * @param full_path Full path of the file (e.g. "/spiflash/ABC.TXT") + * @param[out] is_contiguous True == allocate space now, false == prepare to allocate -- see `f_expand` from FATFS + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if invalid arguments (e.g. any of arguments are NULL) + * - ESP_ERR_INVALID_STATE if partition not found + * - ESP_FAIL if another FRESULT error (saved in errno) + */ +esp_err_t esp_vfs_fat_test_contiguous_file(const char* base_path, const char* full_path, bool* is_contiguous); + /** @cond */ /** * @deprecated Please use `esp_vfs_fat_spiflash_mount_rw_wl` instead diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index c455e72baf5b..55cfbd1f0e50 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -1190,3 +1190,138 @@ static int vfs_fat_utime(void *ctx, const char *path, const struct utimbuf *time } #endif // CONFIG_VFS_SUPPORT_DIR + +esp_err_t esp_vfs_fat_create_contiguous_file(const char* base_path, const char* full_path, uint64_t size, bool alloc_now) +{ + if (base_path == NULL || full_path == NULL || size <= 0) { + return ESP_ERR_INVALID_ARG; + } + + size_t ctx = find_context_index_by_path(base_path); + if (ctx == FF_VOLUMES) { + return ESP_ERR_INVALID_STATE; + } + vfs_fat_ctx_t* fat_ctx = s_fat_ctxs[ctx]; + + _lock_acquire(&fat_ctx->lock); + const char* file_path = full_path + strlen(base_path); // shift the pointer and omit the base_path + prepend_drive_to_path(fat_ctx, &file_path, NULL); + + FIL* file = (FIL*) ff_memalloc(sizeof(FIL)); + if (file == NULL) { + _lock_release(&fat_ctx->lock); + ESP_LOGD(TAG, "esp_vfs_fat_create_contiguous_file alloc failed"); + errno = ENOMEM; + return -1; + } + memset(file, 0, sizeof(*file)); + + FRESULT res = f_open(file, file_path, FA_WRITE | FA_OPEN_ALWAYS); + if (res != FR_OK) { + goto fail; + } + + res = f_expand(file, size, alloc_now ? 1 : 0); + if (res != FR_OK) { + f_close(file); + goto fail; + } + + res = f_close(file); + if (res != FR_OK) { + goto fail; + } + + _lock_release(&fat_ctx->lock); + + return 0; +fail: + _lock_release(&fat_ctx->lock); + ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); + errno = fresult_to_errno(res); + return -1; +} + +static FRESULT test_contiguous_file( // From FATFS examples + FIL* fp, /* [IN] Open file object to be checked */ + int* cont /* [OUT] 1:Contiguous, 0:Fragmented or zero-length */ +) { + DWORD clst, clsz, step; + FSIZE_t fsz; + FRESULT fr; + + *cont = 0; + fr = f_rewind(fp); /* Validates and prepares the file */ + if (fr != FR_OK) return fr; + +#if FF_MAX_SS == FF_MIN_SS + clsz = (DWORD)fp->obj.fs->csize * FF_MAX_SS; /* Cluster size */ +#else + clsz = (DWORD)fp->obj.fs->csize * fp->obj.fs->ssize; +#endif + fsz = f_size(fp); + if (fsz > 0) { + clst = fp->obj.sclust - 1; /* A cluster leading the first cluster for first test */ + while (fsz) { + step = (fsz >= clsz) ? clsz : (DWORD)fsz; + fr = f_lseek(fp, f_tell(fp) + step); /* Advances file pointer a cluster */ + if (fr != FR_OK) return fr; + if (clst + 1 != fp->clust) break; /* Is not the cluster next to previous one? */ + clst = fp->clust; fsz -= step; /* Get current cluster for next test */ + } + if (fsz == 0) *cont = 1; /* All done without fail? */ + } + + return FR_OK; +} + +esp_err_t esp_vfs_fat_test_contiguous_file(const char* base_path, const char* full_path, bool* is_contiguous) +{ + if (base_path == NULL || full_path == NULL || is_contiguous == NULL) { + return ESP_ERR_INVALID_ARG; + } + + size_t ctx = find_context_index_by_path(base_path); + if (ctx == FF_VOLUMES) { + return ESP_ERR_INVALID_STATE; + } + vfs_fat_ctx_t* fat_ctx = s_fat_ctxs[ctx]; + + _lock_acquire(&fat_ctx->lock); + const char* file_path = full_path + strlen(base_path); // shift the pointer and omit the base_path + prepend_drive_to_path(fat_ctx, &file_path, NULL); + + FIL* file = (FIL*) ff_memalloc(sizeof(FIL)); + if (file == NULL) { + _lock_release(&fat_ctx->lock); + ESP_LOGD(TAG, "esp_vfs_fat_test_contiguous_file alloc failed"); + errno = ENOMEM; + return -1; + } + memset(file, 0, sizeof(*file)); + + FRESULT res = f_open(file, file_path, FA_WRITE | FA_OPEN_ALWAYS); + if (res != FR_OK) { + goto fail; + } + + res = test_contiguous_file(file, (int*) is_contiguous); + if (res != FR_OK) { + f_close(file); + goto fail; + } + + res = f_close(file); + if (res != FR_OK) { + goto fail; + } + + _lock_release(&fat_ctx->lock); + + return 0; +fail: + _lock_release(&fat_ctx->lock); + ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); + errno = fresult_to_errno(res); + return -1; +} From f2fe408b993e550ff5408068a80d9c043fdcc39e Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 27 Feb 2024 10:00:06 +0800 Subject: [PATCH 05/33] refactor(core): reformat newlib and pthread with astyle --- components/newlib/abort.c | 4 +- components/newlib/assert.c | 22 +-- components/newlib/heap.c | 11 +- components/newlib/locks.c | 53 +++--- components/newlib/newlib_init.c | 32 ++-- components/newlib/platform_include/assert.h | 1 - components/newlib/platform_include/endian.h | 128 ++++++------- components/newlib/platform_include/errno.h | 8 +- components/newlib/platform_include/net/if.h | 23 ++- .../newlib/platform_include/sys/dirent.h | 6 +- components/newlib/platform_include/sys/lock.h | 10 +- .../newlib/platform_include/sys/reent.h | 3 +- .../newlib/platform_include/sys/select.h | 8 +- .../newlib/platform_include/sys/termios.h | 4 +- components/newlib/platform_include/sys/un.h | 8 +- components/newlib/poll.c | 2 +- components/newlib/port/esp_time_impl.c | 9 +- components/newlib/realpath.c | 3 +- components/newlib/reent_init.c | 4 +- components/newlib/stdatomic.c | 65 ++++--- components/newlib/syscalls.c | 45 +++-- .../test_apps/newlib/main/test_atomic.c | 17 +- .../newlib/test_apps/newlib/main/test_misc.c | 1 - .../test_apps/newlib/main/test_newlib.c | 41 ++-- .../test_apps/newlib/main/test_setjmp.c | 1 - .../test_apps/newlib/main/test_stdatomic.c | 177 +++++++++--------- .../newlib/test_apps/newlib/main/test_time.c | 19 +- components/newlib/time.c | 63 +++---- components/pthread/pthread.c | 55 +++--- components/pthread/pthread_cond_var.c | 2 +- components/pthread/pthread_local_storage.c | 10 +- components/pthread/pthread_rwlock.c | 20 +- components/pthread/pthread_semaphore.c | 16 +- .../pthread_unity_tests/main/test_app_main.c | 1 - .../main/test_cxx_cond_var.cpp | 23 ++- .../main/test_cxx_std_future.cpp | 8 +- .../pthread_unity_tests/main/test_pthread.c | 2 +- .../main/test_pthread_local_storage.c | 11 +- tools/ci/astyle-rules.yml | 2 - 39 files changed, 450 insertions(+), 468 deletions(-) diff --git a/components/newlib/abort.c b/components/newlib/abort.c index 011202854a45..f26a5478b54f 100644 --- a/components/newlib/abort.c +++ b/components/newlib/abort.c @@ -13,8 +13,8 @@ void __attribute__((noreturn)) abort(void) { - #define ERR_STR1 "abort() was called at PC 0x" - #define ERR_STR2 " on core " +#define ERR_STR1 "abort() was called at PC 0x" +#define ERR_STR2 " on core " _Static_assert(UINTPTR_MAX == 0xffffffff, "abort() assumes 32-bit addresses"); _Static_assert(SOC_CPU_CORES_NUM < 10, "abort() assumes number of cores is 1 to 9"); diff --git a/components/newlib/assert.c b/components/newlib/assert.c index 5b0d80736f99..869f673f10b6 100644 --- a/components/newlib/assert.c +++ b/components/newlib/assert.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -51,18 +51,18 @@ void __attribute__((noreturn)) __assert_func(const char *file, int line, const c if (!spi_flash_cache_enabled()) #endif { - if (esp_ptr_in_drom(file)) { - file = CACHE_DISABLED_STR; - } + if (esp_ptr_in_drom(file)) { + file = CACHE_DISABLED_STR; + } - if (esp_ptr_in_drom(func)) { - ra_to_str(addr); - func = addr; - } + if (esp_ptr_in_drom(func)) { + ra_to_str(addr); + func = addr; + } - if (esp_ptr_in_drom(expr)) { - expr = CACHE_DISABLED_STR; - } + if (esp_ptr_in_drom(expr)) { + expr = CACHE_DISABLED_STR; + } } const char *str[] = {ASSERT_STR, func ? func : "\b", " ", file, ":", lbuf, " (", expr, ")"}; diff --git a/components/newlib/heap.c b/components/newlib/heap.c index 685e1e3c721c..f58817920ce5 100644 --- a/components/newlib/heap.c +++ b/components/newlib/heap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,14 +11,13 @@ #include #include "esp_heap_caps.h" - /* These contain the business logic for the malloc() and realloc() implementation. Because of heap tracing wrapping reasons, we do not want these to be a public api, however, so they're not defined publicly. */ -extern void *heap_caps_malloc_default( size_t size ); -extern void *heap_caps_realloc_default( void *ptr, size_t size ); -extern void *heap_caps_aligned_alloc_default( size_t alignment, size_t size ); +extern void *heap_caps_malloc_default(size_t size); +extern void *heap_caps_realloc_default(void *ptr, size_t size); +extern void *heap_caps_aligned_alloc_default(size_t alignment, size_t size); void* malloc(size_t size) { @@ -52,7 +51,7 @@ void _free_r(struct _reent *r, void* ptr) void* _realloc_r(struct _reent *r, void* ptr, size_t size) { - return heap_caps_realloc_default( ptr, size ); + return heap_caps_realloc_default(ptr, size); } void* _calloc_r(struct _reent *r, size_t nmemb, size_t size) diff --git a/components/newlib/locks.c b/components/newlib/locks.c index 7d8ba336fd3b..6ad04fcfafa5 100644 --- a/components/newlib/locks.c +++ b/components/newlib/locks.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,15 +38,14 @@ static portMUX_TYPE lock_init_spinlock = portMUX_INITIALIZER_UNLOCKED; Called by _lock_init*, also called by _lock_acquire* to lazily initialize locks that might have been initialised (to zero only) before the RTOS scheduler started. */ -static void IRAM_ATTR lock_init_generic(_lock_t *lock, uint8_t mutex_type) { +static void IRAM_ATTR lock_init_generic(_lock_t *lock, uint8_t mutex_type) +{ portENTER_CRITICAL(&lock_init_spinlock); if (*lock) { - /* Lock already initialised (either we didn't check earlier, - or it got initialised while we were waiting for the - spinlock.) */ - } - else - { + /* Lock already initialised (either we didn't check earlier, + or it got initialised while we were waiting for the + spinlock.) */ + } else { /* Create a new semaphore this is a bit of an API violation, as we're calling the @@ -70,12 +69,14 @@ static void IRAM_ATTR lock_init_generic(_lock_t *lock, uint8_t mutex_type) { portEXIT_CRITICAL(&lock_init_spinlock); } -void IRAM_ATTR _lock_init(_lock_t *lock) { +void IRAM_ATTR _lock_init(_lock_t *lock) +{ *lock = 0; // In case lock's memory is uninitialized lock_init_generic(lock, queueQUEUE_TYPE_MUTEX); } -void IRAM_ATTR _lock_init_recursive(_lock_t *lock) { +void IRAM_ATTR _lock_init_recursive(_lock_t *lock) +{ *lock = 0; // In case lock's memory is uninitialized lock_init_generic(lock, queueQUEUE_TYPE_RECURSIVE_MUTEX); } @@ -90,7 +91,8 @@ void IRAM_ATTR _lock_init_recursive(_lock_t *lock) { re-initialised if it is used again. Caller has to avoid doing this! */ -void IRAM_ATTR _lock_close(_lock_t *lock) { +void IRAM_ATTR _lock_close(_lock_t *lock) +{ portENTER_CRITICAL(&lock_init_spinlock); if (*lock) { SemaphoreHandle_t h = (SemaphoreHandle_t)(*lock); @@ -108,7 +110,8 @@ void _lock_close_recursive(_lock_t *lock) __attribute__((alias("_lock_close"))); /* Acquire the mutex semaphore for lock. wait up to delay ticks. mutex_type is queueQUEUE_TYPE_RECURSIVE_MUTEX or queueQUEUE_TYPE_MUTEX */ -static int IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t mutex_type) { +static int IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t mutex_type) +{ SemaphoreHandle_t h = (SemaphoreHandle_t)(*lock); if (!h) { if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { @@ -137,8 +140,7 @@ static int IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t if (higher_task_woken) { portYIELD_FROM_ISR(); } - } - else { + } else { /* In task context */ if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) { success = xSemaphoreTakeRecursive(h, delay); @@ -150,26 +152,31 @@ static int IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t return (success == pdTRUE) ? 0 : -1; } -void IRAM_ATTR _lock_acquire(_lock_t *lock) { +void IRAM_ATTR _lock_acquire(_lock_t *lock) +{ lock_acquire_generic(lock, portMAX_DELAY, queueQUEUE_TYPE_MUTEX); } -void IRAM_ATTR _lock_acquire_recursive(_lock_t *lock) { +void IRAM_ATTR _lock_acquire_recursive(_lock_t *lock) +{ lock_acquire_generic(lock, portMAX_DELAY, queueQUEUE_TYPE_RECURSIVE_MUTEX); } -int IRAM_ATTR _lock_try_acquire(_lock_t *lock) { +int IRAM_ATTR _lock_try_acquire(_lock_t *lock) +{ return lock_acquire_generic(lock, 0, queueQUEUE_TYPE_MUTEX); } -int IRAM_ATTR _lock_try_acquire_recursive(_lock_t *lock) { +int IRAM_ATTR _lock_try_acquire_recursive(_lock_t *lock) +{ return lock_acquire_generic(lock, 0, queueQUEUE_TYPE_RECURSIVE_MUTEX); } /* Release the mutex semaphore for lock. mutex_type is queueQUEUE_TYPE_RECURSIVE_MUTEX or queueQUEUE_TYPE_MUTEX */ -static void IRAM_ATTR lock_release_generic(_lock_t *lock, uint8_t mutex_type) { +static void IRAM_ATTR lock_release_generic(_lock_t *lock, uint8_t mutex_type) +{ if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { return; /* locking is a no-op before scheduler is up */ } @@ -194,11 +201,13 @@ static void IRAM_ATTR lock_release_generic(_lock_t *lock, uint8_t mutex_type) { } } -void IRAM_ATTR _lock_release(_lock_t *lock) { +void IRAM_ATTR _lock_release(_lock_t *lock) +{ lock_release_generic(lock, queueQUEUE_TYPE_MUTEX); } -void IRAM_ATTR _lock_release_recursive(_lock_t *lock) { +void IRAM_ATTR _lock_release_recursive(_lock_t *lock) +{ lock_release_generic(lock, queueQUEUE_TYPE_RECURSIVE_MUTEX); } @@ -242,7 +251,6 @@ _Static_assert(configSUPPORT_STATIC_ALLOCATION, static StaticSemaphore_t s_common_mutex; static StaticSemaphore_t s_common_recursive_mutex; - #if ESP_ROM_HAS_RETARGETABLE_LOCKING /* C3 and S3 ROMs are built without Newlib static lock symbols exported, and * with an extra level of _LOCK_T indirection in mind. @@ -271,7 +279,6 @@ static StaticSemaphore_t s_common_recursive_mutex; #define MAYBE_OVERRIDE_LOCK(_lock, _lock_to_use_instead) #endif // ROM_NEEDS_MUTEX_OVERRIDE - void IRAM_ATTR __retarget_lock_init(_LOCK_T *lock) { *lock = NULL; /* In case lock's memory is uninitialized */ diff --git a/components/newlib/newlib_init.c b/components/newlib/newlib_init.c index b1e5c20b2ade..6e03f6c04e58 100644 --- a/components/newlib/newlib_init.c +++ b/components/newlib/newlib_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,23 +43,22 @@ #endif extern int _printf_float(struct _reent *rptr, - void *pdata, - FILE * fp, - int (*pfunc) (struct _reent *, FILE *, const char *, size_t len), - va_list * ap); - + void *pdata, + FILE * fp, + int (*pfunc)(struct _reent *, FILE *, const char *, size_t len), + va_list * ap); extern int _scanf_float(struct _reent *rptr, - void *pdata, - FILE *fp, - va_list *ap); + void *pdata, + FILE *fp, + va_list *ap); static void raise_r_stub(struct _reent *rptr) { _raise_r(rptr, 0); } -static void esp_cleanup_r (struct _reent *rptr) +static void esp_cleanup_r(struct _reent *rptr) { if (_REENT_STDIN(rptr) != _REENT_STDIN(_GLOBAL_REENT)) { _fclose_r(rptr, _REENT_STDIN(rptr)); @@ -69,7 +68,7 @@ static void esp_cleanup_r (struct _reent *rptr) _fclose_r(rptr, _REENT_STDOUT(rptr)); } - if (_REENT_STDERR(rptr) !=_REENT_STDERR(_GLOBAL_REENT)) { + if (_REENT_STDERR(rptr) != _REENT_STDERR(_GLOBAL_REENT)) { _fclose_r(rptr, _REENT_STDERR(rptr)); } } @@ -96,9 +95,9 @@ static struct syscall_stub_table s_stub_table = { ._exit_r = NULL, // never called in ROM ._close_r = &_close_r, ._open_r = &_open_r, - ._write_r = (int (*)(struct _reent *r, int, const void *, int)) &_write_r, - ._lseek_r = (int (*)(struct _reent *r, int, int, int)) &_lseek_r, - ._read_r = (int (*)(struct _reent *r, int, void *, int)) &_read_r, + ._write_r = (int (*)(struct _reent * r, int, const void *, int)) &_write_r, + ._lseek_r = (int (*)(struct _reent * r, int, int, int)) &_lseek_r, + ._read_r = (int (*)(struct _reent * r, int, void *, int)) &_read_r, #if ESP_ROM_HAS_RETARGETABLE_LOCKING ._retarget_lock_init = &__retarget_lock_init, ._retarget_lock_init_recursive = &__retarget_lock_init_recursive, @@ -196,8 +195,7 @@ void esp_setup_newlib_syscalls(void) __attribute__((alias("esp_newlib_init"))); */ void esp_newlib_init_global_stdio(const char *stdio_dev) { - if (stdio_dev == NULL) - { + if (stdio_dev == NULL) { _GLOBAL_REENT->__cleanup = NULL; _REENT_SDIDINIT(_GLOBAL_REENT) = 0; __sinit(_GLOBAL_REENT); @@ -216,7 +214,7 @@ void esp_newlib_init_global_stdio(const char *stdio_dev) file pointers. Thus, the ROM newlib code will never call the ROM version of __swsetup_r(). - See IDFGH-7728 for more details */ - extern int __swsetup_r (struct _reent *, FILE *); + extern int __swsetup_r(struct _reent *, FILE *); __swsetup_r(_GLOBAL_REENT, _REENT_STDIN(_GLOBAL_REENT)); __swsetup_r(_GLOBAL_REENT, _REENT_STDOUT(_GLOBAL_REENT)); __swsetup_r(_GLOBAL_REENT, _REENT_STDERR(_GLOBAL_REENT)); diff --git a/components/newlib/platform_include/assert.h b/components/newlib/platform_include/assert.h index d90bee4e0343..72a4d2149b0b 100644 --- a/components/newlib/platform_include/assert.h +++ b/components/newlib/platform_include/assert.h @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - /* This header file wraps newlib's own unmodified assert.h and adds support for silent assertion failure. */ diff --git a/components/newlib/platform_include/endian.h b/components/newlib/platform_include/endian.h index 67131ff4c125..5671d9013d5c 100644 --- a/components/newlib/platform_include/endian.h +++ b/components/newlib/platform_include/endian.h @@ -7,7 +7,7 @@ */ /*- - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020 Francesco Giancane * SPDX-FileCopyrightText: 2002 Thomas Moestl * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND Apache-2.0 @@ -57,42 +57,42 @@ extern "C" { /* * General byte order swapping functions. */ -#define bswap16(x) __bswap16(x) -#define bswap32(x) __bswap32(x) -#define bswap64(x) __bswap64(x) +#define bswap16(x) __bswap16(x) +#define bswap32(x) __bswap32(x) +#define bswap64(x) __bswap64(x) /* * Host to big endian, host to little endian, big endian to host, and little * endian to host byte order functions as detailed in byteorder(9). */ #if _BYTE_ORDER == _LITTLE_ENDIAN -#define htobe16(x) bswap16((x)) -#define htobe32(x) bswap32((x)) -#define htobe64(x) bswap64((x)) -#define htole16(x) ((uint16_t)(x)) -#define htole32(x) ((uint32_t)(x)) -#define htole64(x) ((uint64_t)(x)) - -#define be16toh(x) bswap16((x)) -#define be32toh(x) bswap32((x)) -#define be64toh(x) bswap64((x)) -#define le16toh(x) ((uint16_t)(x)) -#define le32toh(x) ((uint32_t)(x)) -#define le64toh(x) ((uint64_t)(x)) +#define htobe16(x) bswap16((x)) +#define htobe32(x) bswap32((x)) +#define htobe64(x) bswap64((x)) +#define htole16(x) ((uint16_t)(x)) +#define htole32(x) ((uint32_t)(x)) +#define htole64(x) ((uint64_t)(x)) + +#define be16toh(x) bswap16((x)) +#define be32toh(x) bswap32((x)) +#define be64toh(x) bswap64((x)) +#define le16toh(x) ((uint16_t)(x)) +#define le32toh(x) ((uint32_t)(x)) +#define le64toh(x) ((uint64_t)(x)) #else /* _BYTE_ORDER != _LITTLE_ENDIAN */ -#define htobe16(x) ((uint16_t)(x)) -#define htobe32(x) ((uint32_t)(x)) -#define htobe64(x) ((uint64_t)(x)) -#define htole16(x) bswap16((x)) -#define htole32(x) bswap32((x)) -#define htole64(x) bswap64((x)) - -#define be16toh(x) ((uint16_t)(x)) -#define be32toh(x) ((uint32_t)(x)) -#define be64toh(x) ((uint64_t)(x)) -#define le16toh(x) bswap16((x)) -#define le32toh(x) bswap32((x)) -#define le64toh(x) bswap64((x)) +#define htobe16(x) ((uint16_t)(x)) +#define htobe32(x) ((uint32_t)(x)) +#define htobe64(x) ((uint64_t)(x)) +#define htole16(x) bswap16((x)) +#define htole32(x) bswap32((x)) +#define htole64(x) bswap64((x)) + +#define be16toh(x) ((uint16_t)(x)) +#define be32toh(x) ((uint32_t)(x)) +#define be64toh(x) ((uint64_t)(x)) +#define le16toh(x) bswap16((x)) +#define le32toh(x) bswap32((x)) +#define le64toh(x) bswap64((x)) #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */ /* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ @@ -100,107 +100,107 @@ extern "C" { static __inline uint16_t be16dec(const void *pp) { - uint8_t const *p = (uint8_t const *)pp; + uint8_t const *p = (uint8_t const *)pp; - return ((p[0] << 8) | p[1]); + return ((p[0] << 8) | p[1]); } static __inline uint32_t be32dec(const void *pp) { - uint8_t const *p = (uint8_t const *)pp; + uint8_t const *p = (uint8_t const *)pp; - return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); + return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); } static __inline uint64_t be64dec(const void *pp) { - uint8_t const *p = (uint8_t const *)pp; + uint8_t const *p = (uint8_t const *)pp; - return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); + return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); } static __inline uint16_t le16dec(const void *pp) { - uint8_t const *p = (uint8_t const *)pp; + uint8_t const *p = (uint8_t const *)pp; - return ((p[1] << 8) | p[0]); + return ((p[1] << 8) | p[0]); } static __inline uint32_t le32dec(const void *pp) { - uint8_t const *p = (uint8_t const *)pp; + uint8_t const *p = (uint8_t const *)pp; - return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); + return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); } static __inline uint64_t le64dec(const void *pp) { - uint8_t const *p = (uint8_t const *)pp; + uint8_t const *p = (uint8_t const *)pp; - return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); + return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); } static __inline void be16enc(void *pp, uint16_t u) { - uint8_t *p = (uint8_t *)pp; + uint8_t *p = (uint8_t *)pp; - p[0] = (u >> 8) & 0xff; - p[1] = u & 0xff; + p[0] = (u >> 8) & 0xff; + p[1] = u & 0xff; } static __inline void be32enc(void *pp, uint32_t u) { - uint8_t *p = (uint8_t *)pp; + uint8_t *p = (uint8_t *)pp; - p[0] = (u >> 24) & 0xff; - p[1] = (u >> 16) & 0xff; - p[2] = (u >> 8) & 0xff; - p[3] = u & 0xff; + p[0] = (u >> 24) & 0xff; + p[1] = (u >> 16) & 0xff; + p[2] = (u >> 8) & 0xff; + p[3] = u & 0xff; } static __inline void be64enc(void *pp, uint64_t u) { - uint8_t *p = (uint8_t *)pp; + uint8_t *p = (uint8_t *)pp; - be32enc(p, (uint32_t)(u >> 32)); - be32enc(p + 4, (uint32_t)(u & 0xffffffffU)); + be32enc(p, (uint32_t)(u >> 32)); + be32enc(p + 4, (uint32_t)(u & 0xffffffffU)); } static __inline void le16enc(void *pp, uint16_t u) { - uint8_t *p = (uint8_t *)pp; + uint8_t *p = (uint8_t *)pp; - p[0] = u & 0xff; - p[1] = (u >> 8) & 0xff; + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; } static __inline void le32enc(void *pp, uint32_t u) { - uint8_t *p = (uint8_t *)pp; + uint8_t *p = (uint8_t *)pp; - p[0] = u & 0xff; - p[1] = (u >> 8) & 0xff; - p[2] = (u >> 16) & 0xff; - p[3] = (u >> 24) & 0xff; + p[0] = u & 0xff; + p[1] = (u >> 8) & 0xff; + p[2] = (u >> 16) & 0xff; + p[3] = (u >> 24) & 0xff; } static __inline void le64enc(void *pp, uint64_t u) { - uint8_t *p = (uint8_t *)pp; + uint8_t *p = (uint8_t *)pp; - le32enc(p, (uint32_t)(u & 0xffffffffU)); - le32enc(p + 4, (uint32_t)(u >> 32)); + le32enc(p, (uint32_t)(u & 0xffffffffU)); + le32enc(p + 4, (uint32_t)(u >> 32)); } #ifdef __cplusplus diff --git a/components/newlib/platform_include/errno.h b/components/newlib/platform_include/errno.h index 98dedeef88ac..cad5f16165b3 100644 --- a/components/newlib/platform_include/errno.h +++ b/components/newlib/platform_include/errno.h @@ -1,6 +1,6 @@ /* - * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,15 +17,15 @@ #endif #ifndef EAI_SOCKTYPE -#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #endif #ifndef EAI_AGAIN -#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ #endif #ifndef EAI_BADFLAGS -#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #endif #endif // _ESP_PLATFORM_ERRNO_H_ diff --git a/components/newlib/platform_include/net/if.h b/components/newlib/platform_include/net/if.h index 4d444679e72b..ddde601f55ee 100644 --- a/components/newlib/platform_include/net/if.h +++ b/components/newlib/platform_include/net/if.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,22 +13,21 @@ extern "C" { #include "lwip/sockets.h" #include "lwip/if_api.h" -#define MSG_DONTROUTE 0x4 /* send without using routing tables */ -#define SOCK_SEQPACKET 5 /* sequenced packet stream */ -#define MSG_EOR 0x8 /* data completes record */ -#define SOCK_SEQPACKET 5 /* sequenced packet stream */ -#define SOMAXCONN 128 +#define MSG_DONTROUTE 0x4 /* send without using routing tables */ +#define SOCK_SEQPACKET 5 /* sequenced packet stream */ +#define MSG_EOR 0x8 /* data completes record */ +#define SOCK_SEQPACKET 5 /* sequenced packet stream */ +#define SOMAXCONN 128 -#define IPV6_UNICAST_HOPS 4 /* int; IP6 hops */ +#define IPV6_UNICAST_HOPS 4 /* int; IP6 hops */ -#define NI_MAXHOST 1025 -#define NI_MAXSERV 32 -#define NI_NUMERICSERV 0x00000008 -#define NI_DGRAM 0x00000010 +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 +#define NI_NUMERICSERV 0x00000008 +#define NI_DGRAM 0x00000010 typedef u32_t socklen_t; - unsigned int if_nametoindex(const char *ifname); char *if_indextoname(unsigned int ifindex, char *ifname); diff --git a/components/newlib/platform_include/sys/dirent.h b/components/newlib/platform_include/sys/dirent.h index f3d13ab3be5f..444dad2ddf5c 100644 --- a/components/newlib/platform_include/sys/dirent.h +++ b/components/newlib/platform_include/sys/dirent.h @@ -42,7 +42,7 @@ struct dirent { #define DT_DIR 2 #if __BSD_VISIBLE #define MAXNAMLEN 255 - char d_name[MAXNAMLEN+1]; /*!< zero-terminated file name */ + char d_name[MAXNAMLEN + 1]; /*!< zero-terminated file name */ #else char d_name[256]; #endif @@ -56,8 +56,8 @@ void rewinddir(DIR* pdir); int closedir(DIR* pdir); int readdir_r(DIR* pdir, struct dirent* entry, struct dirent** out_dirent); int scandir(const char *dirname, struct dirent ***out_dirlist, - int (*select_func)(const struct dirent *), - int (*cmp_func)(const struct dirent **, const struct dirent **)); + int (*select_func)(const struct dirent *), + int (*cmp_func)(const struct dirent **, const struct dirent **)); int alphasort(const struct dirent **d1, const struct dirent **d2); #ifdef __cplusplus diff --git a/components/newlib/platform_include/sys/lock.h b/components/newlib/platform_include/sys/lock.h index a7fa41ed8579..34d9126086f1 100644 --- a/components/newlib/platform_include/sys/lock.h +++ b/components/newlib/platform_include/sys/lock.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,13 +19,13 @@ */ struct __lock { #if (CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES && CONFIG_FREERTOS_USE_TRACE_FACILITY) - int reserved[29]; + int reserved[29]; #elif (CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES && !CONFIG_FREERTOS_USE_TRACE_FACILITY) - int reserved[27]; + int reserved[27]; #elif (!CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES && CONFIG_FREERTOS_USE_TRACE_FACILITY) - int reserved[23]; + int reserved[23]; #else - int reserved[21]; + int reserved[21]; #endif /* #if (CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES && CONFIG_FREERTOS_USE_TRACE_FACILITY) */ }; diff --git a/components/newlib/platform_include/sys/reent.h b/components/newlib/platform_include/sys/reent.h index 0be3983d27a6..64f47954144b 100644 --- a/components/newlib/platform_include/sys/reent.h +++ b/components/newlib/platform_include/sys/reent.h @@ -21,14 +21,13 @@ #include_next - #ifdef __cplusplus extern "C" { #endif #if __NEWLIB__ > 4 || ( __NEWLIB__ == 4 && __NEWLIB_MINOR__ > 1 ) /* TODO: IDF-8134 */ -extern void __sinit (struct _reent *); +extern void __sinit(struct _reent *); extern struct _glue __sglue; extern struct _reent * _global_impure_ptr; diff --git a/components/newlib/platform_include/sys/select.h b/components/newlib/platform_include/sys/select.h index d2c765506bed..e4d828b71102 100644 --- a/components/newlib/platform_include/sys/select.h +++ b/components/newlib/platform_include/sys/select.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,9 +34,9 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct #define __FD_SAFE_SET(n, code) do { if ((unsigned)(n) < FD_SETSIZE) { code; } } while(0) #define __FD_SAFE_GET(n, code) (((unsigned)(n) < FD_SETSIZE) ? (code) : 0) -#define FD_SET(n, p) __FD_SAFE_SET(n, ((p)->fds_bits[(n) / NFDBITS] |= (1L << ((n) % NFDBITS)))) -#define FD_CLR(n, p) __FD_SAFE_SET(n, ((p)->fds_bits[(n) / NFDBITS] &= ~(1L << ((n) % NFDBITS)))) -#define FD_ISSET(n, p) __FD_SAFE_GET(n, ((p)->fds_bits[(n) / NFDBITS] & (1L << ((n) % NFDBITS)))) +#define FD_SET(n, p) __FD_SAFE_SET(n, ((p)->fds_bits[(n) / NFDBITS] |= (1L << ((n) % NFDBITS)))) +#define FD_CLR(n, p) __FD_SAFE_SET(n, ((p)->fds_bits[(n) / NFDBITS] &= ~(1L << ((n) % NFDBITS)))) +#define FD_ISSET(n, p) __FD_SAFE_GET(n, ((p)->fds_bits[(n) / NFDBITS] & (1L << ((n) % NFDBITS)))) #endif // FD_ISSET || FD_SET || FD_CLR #endif //__ESP_SYS_SELECT_H__ diff --git a/components/newlib/platform_include/sys/termios.h b/components/newlib/platform_include/sys/termios.h index 4f34f2ec9e2b..be45a87be398 100644 --- a/components/newlib/platform_include/sys/termios.h +++ b/components/newlib/platform_include/sys/termios.h @@ -14,7 +14,6 @@ // Not everything has a defined meaning for ESP-IDF (e.g. process leader IDs) and therefore are likely to be stubbed // in actual implementations. - #include #include #include "sdkconfig.h" @@ -164,8 +163,7 @@ typedef uint8_t cc_t; typedef uint32_t speed_t; typedef uint16_t tcflag_t; -struct termios -{ +struct termios { tcflag_t c_iflag; /** Input modes */ tcflag_t c_oflag; /** Output modes */ tcflag_t c_cflag; /** Control modes */ diff --git a/components/newlib/platform_include/sys/un.h b/components/newlib/platform_include/sys/un.h index 213b0ab4fdee..64f90b2ab3af 100644 --- a/components/newlib/platform_include/sys/un.h +++ b/components/newlib/platform_include/sys/un.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,11 +9,11 @@ extern "C" { #endif -#define AF_UNIX 1 /* local to host (pipes) */ +#define AF_UNIX 1 /* local to host (pipes) */ struct sockaddr_un { - short sun_family; /*AF_UNIX*/ - char sun_path[108]; /*path name */ + short sun_family; /*AF_UNIX*/ + char sun_path[108]; /*path name */ }; #ifdef __cplusplus diff --git a/components/newlib/poll.c b/components/newlib/poll.c index ee23ef7a6a89..2963a402caa0 100644 --- a/components/newlib/poll.c +++ b/components/newlib/poll.c @@ -60,7 +60,7 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout) } } - const int select_ret = select(max_fd + 1, &readfds, &writefds, &errorfds, timeout < 0 ? NULL: &tv); + const int select_ret = select(max_fd + 1, &readfds, &writefds, &errorfds, timeout < 0 ? NULL : &tv); if (select_ret > 0) { ret += select_ret; diff --git a/components/newlib/port/esp_time_impl.c b/components/newlib/port/esp_time_impl.c index ddc73f29483b..6affb70a5b78 100644 --- a/components/newlib/port/esp_time_impl.c +++ b/components/newlib/port/esp_time_impl.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -50,8 +50,6 @@ #include "esp32p4/rtc.h" #endif - - // Offset between High resolution timer and the RTC. // Initialized after reset or light sleep. #if defined(CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER) && defined(CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER) @@ -94,13 +92,12 @@ uint64_t esp_time_impl_get_time(void) #endif // defined( CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER ) || defined( CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER ) - void esp_time_impl_set_boot_time(uint64_t time_us) { _lock_acquire(&s_boot_time_lock); #ifdef CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER - REG_WRITE(RTC_BOOT_TIME_LOW_REG, (uint32_t) (time_us & 0xffffffff)); - REG_WRITE(RTC_BOOT_TIME_HIGH_REG, (uint32_t) (time_us >> 32)); + REG_WRITE(RTC_BOOT_TIME_LOW_REG, (uint32_t)(time_us & 0xffffffff)); + REG_WRITE(RTC_BOOT_TIME_HIGH_REG, (uint32_t)(time_us >> 32)); #else s_boot_time = time_us; #endif diff --git a/components/newlib/realpath.c b/components/newlib/realpath.c index fb0118bae996..6a6f1bddc8ba 100644 --- a/components/newlib/realpath.c +++ b/components/newlib/realpath.c @@ -43,7 +43,6 @@ char * realpath(const char *file_name, char *resolved_name) /* number of path components in the output buffer */ size_t out_depth = 0; - while (*in_ptr) { /* "path component" is the part between two '/' path separators. * locate the next path component in the input path: @@ -52,7 +51,7 @@ char * realpath(const char *file_name, char *resolved_name) size_t path_component_len = end_of_path_component - in_ptr; if (path_component_len == 0 || - (path_component_len == 1 && in_ptr[0] == '.')) { + (path_component_len == 1 && in_ptr[0] == '.')) { /* empty path component or '.' - nothing to do */ } else if (path_component_len == 2 && in_ptr[0] == '.' && in_ptr[1] == '.') { /* '..' - remove one path component from the output */ diff --git a/components/newlib/reent_init.c b/components/newlib/reent_init.c index 7d8ade98f89e..b4a393702c80 100644 --- a/components/newlib/reent_init.c +++ b/components/newlib/reent_init.c @@ -49,7 +49,7 @@ void esp_reent_cleanup(void) /* Clean up "glue" (lazily-allocated FILE objects) */ struct _glue* prev = &_REENT_SGLUE(_GLOBAL_REENT); - for (struct _glue* cur = _REENT_SGLUE(_GLOBAL_REENT)._next; cur != NULL;) { + for (struct _glue * cur = _REENT_SGLUE(_GLOBAL_REENT)._next; cur != NULL;) { if (cur->_niobs == 0) { cur = cur->_next; continue; @@ -67,7 +67,7 @@ void esp_reent_cleanup(void) cur = cur->_next; continue; } - struct _glue* next = cur->_next; + struct _glue * next = cur->_next; prev->_next = next; free(cur); cur = next; diff --git a/components/newlib/stdatomic.c b/components/newlib/stdatomic.c index ae52f83ed52b..103a3dc2bad3 100644 --- a/components/newlib/stdatomic.c +++ b/components/newlib/stdatomic.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -297,7 +297,6 @@ CLANG_DECLARE_ALIAS( __sync_lock_test_and_set_ ## n ) } \ CLANG_DECLARE_ALIAS( __sync_lock_release_ ## n ) - #if !HAS_ATOMICS_32 _Static_assert(sizeof(unsigned char) == 1, "atomics require a 1-byte type"); @@ -376,21 +375,21 @@ SYNC_OP_FETCH(sub, 1, unsigned char) SYNC_OP_FETCH(sub, 2, short unsigned int) SYNC_OP_FETCH(sub, 4, unsigned int) -SYNC_FETCH_OP(and, 1, unsigned char) -SYNC_FETCH_OP(and, 2, short unsigned int) -SYNC_FETCH_OP(and, 4, unsigned int) +SYNC_FETCH_OP( and, 1, unsigned char) +SYNC_FETCH_OP( and, 2, short unsigned int) +SYNC_FETCH_OP( and, 4, unsigned int) -SYNC_OP_FETCH(and, 1, unsigned char) -SYNC_OP_FETCH(and, 2, short unsigned int) -SYNC_OP_FETCH(and, 4, unsigned int) +SYNC_OP_FETCH( and, 1, unsigned char) +SYNC_OP_FETCH( and, 2, short unsigned int) +SYNC_OP_FETCH( and, 4, unsigned int) -SYNC_FETCH_OP(or, 1, unsigned char) -SYNC_FETCH_OP(or, 2, short unsigned int) -SYNC_FETCH_OP(or, 4, unsigned int) +SYNC_FETCH_OP( or, 1, unsigned char) +SYNC_FETCH_OP( or, 2, short unsigned int) +SYNC_FETCH_OP( or, 4, unsigned int) -SYNC_OP_FETCH(or, 1, unsigned char) -SYNC_OP_FETCH(or, 2, short unsigned int) -SYNC_OP_FETCH(or, 4, unsigned int) +SYNC_OP_FETCH( or, 1, unsigned char) +SYNC_OP_FETCH( or, 2, short unsigned int) +SYNC_OP_FETCH( or, 4, unsigned int) SYNC_FETCH_OP(xor, 1, unsigned char) SYNC_FETCH_OP(xor, 2, short unsigned int) @@ -416,7 +415,6 @@ SYNC_VAL_CMP_EXCHANGE(1, unsigned char) SYNC_VAL_CMP_EXCHANGE(2, short unsigned int) SYNC_VAL_CMP_EXCHANGE(4, unsigned int) - SYNC_LOCK_TEST_AND_SET(1, unsigned char) SYNC_LOCK_TEST_AND_SET(2, short unsigned int) SYNC_LOCK_TEST_AND_SET(4, unsigned int) @@ -436,15 +434,17 @@ ATOMIC_STORE(4, unsigned int) #elif __riscv_atomic == 1 -bool CLANG_ATOMIC_SUFFIX(__atomic_always_lock_free) (unsigned int size, const volatile void *) { - return size <= sizeof(int); +bool CLANG_ATOMIC_SUFFIX(__atomic_always_lock_free)(unsigned int size, const volatile void *) +{ + return size <= sizeof(int); } -CLANG_DECLARE_ALIAS( __atomic_always_lock_free) +CLANG_DECLARE_ALIAS(__atomic_always_lock_free) -bool CLANG_ATOMIC_SUFFIX(__atomic_is_lock_free) (unsigned int size, const volatile void *) { - return size <= sizeof(int); +bool CLANG_ATOMIC_SUFFIX(__atomic_is_lock_free)(unsigned int size, const volatile void *) +{ + return size <= sizeof(int); } -CLANG_DECLARE_ALIAS( __atomic_is_lock_free) +CLANG_DECLARE_ALIAS(__atomic_is_lock_free) #endif // !HAS_ATOMICS_32 @@ -484,9 +484,9 @@ SYNC_FETCH_OP(add, 8, long long unsigned int) SYNC_FETCH_OP(sub, 8, long long unsigned int) -SYNC_FETCH_OP(and, 8, long long unsigned int) +SYNC_FETCH_OP( and, 8, long long unsigned int) -SYNC_FETCH_OP(or, 8, long long unsigned int) +SYNC_FETCH_OP( or, 8, long long unsigned int) SYNC_FETCH_OP(xor, 8, long long unsigned int) @@ -496,9 +496,9 @@ SYNC_OP_FETCH(add, 8, long long unsigned int) SYNC_OP_FETCH(sub, 8, long long unsigned int) -SYNC_OP_FETCH(and, 8, long long unsigned int) +SYNC_OP_FETCH( and, 8, long long unsigned int) -SYNC_OP_FETCH(or, 8, long long unsigned int) +SYNC_OP_FETCH( or, 8, long long unsigned int) SYNC_OP_FETCH(xor, 8, long long unsigned int) @@ -519,21 +519,24 @@ ATOMIC_STORE(8, long long unsigned int) #endif // !HAS_ATOMICS_64 // Clang generates calls to the __atomic_load/__atomic_store functions for object size more then 4 bytes -void CLANG_ATOMIC_SUFFIX( __atomic_load ) (size_t size, const volatile void *src, void *dest, int model) { +void CLANG_ATOMIC_SUFFIX(__atomic_load)(size_t size, const volatile void *src, void *dest, int model) +{ unsigned state = _ATOMIC_ENTER_CRITICAL(); memcpy(dest, (const void *)src, size); _ATOMIC_EXIT_CRITICAL(state); } -CLANG_DECLARE_ALIAS( __atomic_load ) +CLANG_DECLARE_ALIAS(__atomic_load) -void CLANG_ATOMIC_SUFFIX( __atomic_store ) (size_t size, volatile void *dest, void *src, int model) { +void CLANG_ATOMIC_SUFFIX(__atomic_store)(size_t size, volatile void *dest, void *src, int model) +{ unsigned state = _ATOMIC_ENTER_CRITICAL(); memcpy((void *)dest, (const void *)src, size); _ATOMIC_EXIT_CRITICAL(state); } -CLANG_DECLARE_ALIAS( __atomic_store) +CLANG_DECLARE_ALIAS(__atomic_store) -bool CLANG_ATOMIC_SUFFIX(__atomic_compare_exchange) (size_t size, volatile void *ptr, void *expected, void *desired, int success_memorder, int failure_memorder) { +bool CLANG_ATOMIC_SUFFIX(__atomic_compare_exchange)(size_t size, volatile void *ptr, void *expected, void *desired, int success_memorder, int failure_memorder) +{ bool ret = false; unsigned state = _ATOMIC_ENTER_CRITICAL(); if (!memcmp((void *)ptr, expected, size)) { @@ -545,4 +548,4 @@ bool CLANG_ATOMIC_SUFFIX(__atomic_compare_exchange) (size_t size, volatile void _ATOMIC_EXIT_CRITICAL(state); return ret; } -CLANG_DECLARE_ALIAS( __atomic_compare_exchange) +CLANG_DECLARE_ALIAS(__atomic_compare_exchange) diff --git a/components/newlib/syscalls.c b/components/newlib/syscalls.c index a573229923ef..3f58a446ef2e 100644 --- a/components/newlib/syscalls.c +++ b/components/newlib/syscalls.c @@ -83,20 +83,18 @@ static int _fsync_console(int fd) return -1; } - /* The following weak definitions of syscalls will be used unless * another definition is provided. That definition may come from * VFS, LWIP, or the application. */ ssize_t _read_r(struct _reent *r, int fd, void * dst, size_t size) - __attribute__((weak,alias("_read_r_console"))); +__attribute__((weak, alias("_read_r_console"))); ssize_t _write_r(struct _reent *r, int fd, const void * data, size_t size) - __attribute__((weak,alias("_write_r_console"))); -int _fstat_r (struct _reent *r, int fd, struct stat *st) - __attribute__((weak,alias("_fstat_r_console"))); +__attribute__((weak, alias("_write_r_console"))); +int _fstat_r(struct _reent *r, int fd, struct stat *st) +__attribute__((weak, alias("_fstat_r_console"))); int fsync(int fd) - __attribute__((weak,alias("_fsync_console"))); - +__attribute__((weak, alias("_fsync_console"))); /* The aliases below are to "syscall_not_implemented", which * doesn't have the same signature as the original function. @@ -108,40 +106,39 @@ int fsync(int fd) #endif int _open_r(struct _reent *r, const char * path, int flags, int mode) - __attribute__((weak,alias("syscall_not_implemented"))); +__attribute__((weak, alias("syscall_not_implemented"))); int _close_r(struct _reent *r, int fd) - __attribute__((weak,alias("syscall_not_implemented"))); +__attribute__((weak, alias("syscall_not_implemented"))); off_t _lseek_r(struct _reent *r, int fd, off_t size, int mode) - __attribute__((weak,alias("syscall_not_implemented"))); +__attribute__((weak, alias("syscall_not_implemented"))); int _fcntl_r(struct _reent *r, int fd, int cmd, int arg) - __attribute__((weak,alias("syscall_not_implemented"))); +__attribute__((weak, alias("syscall_not_implemented"))); int _stat_r(struct _reent *r, const char * path, struct stat * st) - __attribute__((weak,alias("syscall_not_implemented"))); +__attribute__((weak, alias("syscall_not_implemented"))); int _link_r(struct _reent *r, const char* n1, const char* n2) - __attribute__((weak,alias("syscall_not_implemented"))); +__attribute__((weak, alias("syscall_not_implemented"))); int _unlink_r(struct _reent *r, const char *path) - __attribute__((weak,alias("syscall_not_implemented"))); +__attribute__((weak, alias("syscall_not_implemented"))); int _rename_r(struct _reent *r, const char *src, const char *dst) - __attribute__((weak,alias("syscall_not_implemented"))); +__attribute__((weak, alias("syscall_not_implemented"))); int _isatty_r(struct _reent *r, int fd) - __attribute__((weak,alias("syscall_not_implemented"))); - +__attribute__((weak, alias("syscall_not_implemented"))); /* These functions are not expected to be overridden */ int _system_r(struct _reent *r, const char *str) - __attribute__((alias("syscall_not_implemented"))); +__attribute__((alias("syscall_not_implemented"))); int raise(int sig) - __attribute__((alias("syscall_not_implemented_aborts"))); +__attribute__((alias("syscall_not_implemented_aborts"))); int _raise_r(struct _reent *r, int sig) - __attribute__((alias("syscall_not_implemented_aborts"))); +__attribute__((alias("syscall_not_implemented_aborts"))); void* _sbrk_r(struct _reent *r, ptrdiff_t sz) - __attribute__((alias("syscall_not_implemented_aborts"))); +__attribute__((alias("syscall_not_implemented_aborts"))); int _getpid_r(struct _reent *r) - __attribute__((alias("syscall_not_implemented"))); +__attribute__((alias("syscall_not_implemented"))); int _kill_r(struct _reent *r, int pid, int sig) - __attribute__((alias("syscall_not_implemented"))); +__attribute__((alias("syscall_not_implemented"))); void _exit(int __status) - __attribute__((alias("syscall_not_implemented_aborts"))); +__attribute__((alias("syscall_not_implemented_aborts"))); #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop diff --git a/components/newlib/test_apps/newlib/main/test_atomic.c b/components/newlib/test_apps/newlib/main/test_atomic.c index 5f6b56b8ab52..538176816413 100644 --- a/components/newlib/test_apps/newlib/main/test_atomic.c +++ b/components/newlib/test_apps/newlib/main/test_atomic.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -14,7 +14,6 @@ #define RECORD_TIME_START() do {__t1 = esp_cpu_get_cycle_count();}while(0) #define RECORD_TIME_END(p_time) do{__t2 = esp_cpu_get_cycle_count(); *p_time = (__t2-__t1);}while(0) - #define TEST_TIMES 11 //Test twice, and only get the result of second time, to avoid influence of cache miss @@ -37,11 +36,13 @@ static uint32_t s_t_ref; static void sorted_array_insert(uint32_t* array, int* size, uint32_t item) { int pos; - for (pos = *size; pos>0; pos--) { - if (array[pos-1] < item) break; - array[pos] = array[pos-1]; + for (pos = *size; pos > 0; pos--) { + if (array[pos - 1] < item) { + break; + } + array[pos] = array[pos - 1]; } - array[pos]=item; + array[pos] = item; (*size)++; } @@ -56,7 +57,7 @@ static void test_flow(const char* name, test_f func) sorted_array_insert(t_flight_sorted, &t_flight_num, t_op); } for (int i = 0; i < TEST_TIMES; i++) { - ESP_LOGI(TAG, "%s: %" PRIu32 " ops", name, t_flight_sorted[i]-s_t_ref); + ESP_LOGI(TAG, "%s: %" PRIu32 " ops", name, t_flight_sorted[i] - s_t_ref); } } @@ -126,7 +127,7 @@ static IRAM_ATTR void test_atomic_compare_exchange(uint32_t* t_op) (void) res; } -TEST_CASE("test atomic","[atomic]") +TEST_CASE("test atomic", "[atomic]") { test_flow("ref", test_ref); diff --git a/components/newlib/test_apps/newlib/main/test_misc.c b/components/newlib/test_apps/newlib/main/test_misc.c index edbe5a1fa034..a79fdf252b8a 100644 --- a/components/newlib/test_apps/newlib/main/test_misc.c +++ b/components/newlib/test_apps/newlib/main/test_misc.c @@ -18,7 +18,6 @@ #include "esp_heap_caps.h" #include "esp_vfs.h" - TEST_CASE("misc - posix_memalign", "[newlib_misc]") { void* outptr = NULL; diff --git a/components/newlib/test_apps/newlib/main/test_newlib.c b/components/newlib/test_apps/newlib/main/test_newlib.c index 2651d3d61c7d..4939fd028e2c 100644 --- a/components/newlib/test_apps/newlib/main/test_newlib.c +++ b/components/newlib/test_apps/newlib/main/test_newlib.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -18,12 +18,12 @@ TEST_CASE("test ctype functions", "[newlib]") { - TEST_ASSERT_TRUE( isalnum('a') && isalnum('A') && isalnum('z') && isalnum('Z') && isalnum('0') && isalnum('9') ); - TEST_ASSERT_FALSE( isalnum('(') || isalnum('-') || isalnum(' ') || isalnum('\x81') || isalnum('.') || isalnum('\\') ); - TEST_ASSERT_TRUE( isalpha('a') && isalpha('A') && isalpha('z') && isalpha('Z') ); - TEST_ASSERT_FALSE( isalpha('0') || isalpha('9') || isalpha(')') || isalpha('\t') || isalpha(' ') || isalpha('\x81') ); - TEST_ASSERT_TRUE( isspace(' ') && isspace('\t') && isspace('\n') && isspace('\r') ); - TEST_ASSERT_FALSE( isspace('0') || isspace('9') || isspace(')') || isspace('A') || isspace('*') || isspace('\x81') || isspace('a')); + TEST_ASSERT_TRUE(isalnum('a') && isalnum('A') && isalnum('z') && isalnum('Z') && isalnum('0') && isalnum('9')); + TEST_ASSERT_FALSE(isalnum('(') || isalnum('-') || isalnum(' ') || isalnum('\x81') || isalnum('.') || isalnum('\\')); + TEST_ASSERT_TRUE(isalpha('a') && isalpha('A') && isalpha('z') && isalpha('Z')); + TEST_ASSERT_FALSE(isalpha('0') || isalpha('9') || isalpha(')') || isalpha('\t') || isalpha(' ') || isalpha('\x81')); + TEST_ASSERT_TRUE(isspace(' ') && isspace('\t') && isspace('\n') && isspace('\r')); + TEST_ASSERT_FALSE(isspace('0') || isspace('9') || isspace(')') || isspace('A') || isspace('*') || isspace('\x81') || isspace('a')); } TEST_CASE("test atoX functions", "[newlib]") @@ -74,28 +74,27 @@ TEST_CASE("test time functions", "[newlib]") setenv("TZ", "UTC-8", 1); tzset(); struct tm *tm_utc = gmtime(&now); - TEST_ASSERT_EQUAL( 28, tm_utc->tm_sec); - TEST_ASSERT_EQUAL( 41, tm_utc->tm_min); - TEST_ASSERT_EQUAL( 7, tm_utc->tm_hour); - TEST_ASSERT_EQUAL( 26, tm_utc->tm_mday); - TEST_ASSERT_EQUAL( 4, tm_utc->tm_mon); + TEST_ASSERT_EQUAL(28, tm_utc->tm_sec); + TEST_ASSERT_EQUAL(41, tm_utc->tm_min); + TEST_ASSERT_EQUAL(7, tm_utc->tm_hour); + TEST_ASSERT_EQUAL(26, tm_utc->tm_mday); + TEST_ASSERT_EQUAL(4, tm_utc->tm_mon); TEST_ASSERT_EQUAL(116, tm_utc->tm_year); - TEST_ASSERT_EQUAL( 4, tm_utc->tm_wday); + TEST_ASSERT_EQUAL(4, tm_utc->tm_wday); TEST_ASSERT_EQUAL(146, tm_utc->tm_yday); struct tm *tm_local = localtime(&now); - TEST_ASSERT_EQUAL( 28, tm_local->tm_sec); - TEST_ASSERT_EQUAL( 41, tm_local->tm_min); - TEST_ASSERT_EQUAL( 15, tm_local->tm_hour); - TEST_ASSERT_EQUAL( 26, tm_local->tm_mday); - TEST_ASSERT_EQUAL( 4, tm_local->tm_mon); + TEST_ASSERT_EQUAL(28, tm_local->tm_sec); + TEST_ASSERT_EQUAL(41, tm_local->tm_min); + TEST_ASSERT_EQUAL(15, tm_local->tm_hour); + TEST_ASSERT_EQUAL(26, tm_local->tm_mday); + TEST_ASSERT_EQUAL(4, tm_local->tm_mon); TEST_ASSERT_EQUAL(116, tm_local->tm_year); - TEST_ASSERT_EQUAL( 4, tm_local->tm_wday); + TEST_ASSERT_EQUAL(4, tm_local->tm_wday); TEST_ASSERT_EQUAL(146, tm_local->tm_yday); } - TEST_CASE("test asctime", "[newlib]") { char buf[64]; @@ -204,7 +203,6 @@ TEST_CASE("test 64bit int formats", "[newlib]") } #endif // CONFIG_NEWLIB_NANO_FORMAT - TEST_CASE("fmod and fmodf work as expected", "[newlib]") { TEST_ASSERT_EQUAL(0.1, fmod(10.1, 2.0)); @@ -216,7 +214,6 @@ TEST_CASE("newlib: can link 'system', 'raise'", "[newlib]") printf("system: %p, raise: %p\n", &system, &raise); } - TEST_CASE("newlib: rom and toolchain localtime func gives the same result", "[newlib]") { // This UNIX time represents 2020-03-12 15:00:00 EDT (19:00 GMT) diff --git a/components/newlib/test_apps/newlib/main/test_setjmp.c b/components/newlib/test_apps/newlib/main/test_setjmp.c index 7e96fc64c186..f51373bfe4cf 100644 --- a/components/newlib/test_apps/newlib/main/test_setjmp.c +++ b/components/newlib/test_apps/newlib/main/test_setjmp.c @@ -9,7 +9,6 @@ #include "unity.h" #include "esp_system.h" - typedef struct { jmp_buf jmp_env; uint32_t retval; diff --git a/components/newlib/test_apps/newlib/main/test_stdatomic.c b/components/newlib/test_apps/newlib/main/test_stdatomic.c index 3331697feb04..2f642f27d33c 100644 --- a/components/newlib/test_apps/newlib/main/test_stdatomic.c +++ b/components/newlib/test_apps/newlib/main/test_stdatomic.c @@ -21,19 +21,18 @@ atomic_uint g_atomic32; atomic_ushort g_atomic16; atomic_uchar g_atomic8; - TEST_CASE("stdatomic - test_64bit_atomics", "[newlib_stdatomic]") { unsigned long long x64 = 0; g_atomic64 = 0; // calls atomic_store - x64 += atomic_fetch_or (&g_atomic64, 0x1111111111111111ULL); + x64 += atomic_fetch_or(&g_atomic64, 0x1111111111111111ULL); x64 += atomic_fetch_xor(&g_atomic64, 0x3333333333333333ULL); x64 += atomic_fetch_and(&g_atomic64, 0xf0f0f0f0f0f0f0f0ULL); x64 += atomic_fetch_sub(&g_atomic64, 0x0f0f0f0f0f0f0f0fULL); x64 += atomic_fetch_add(&g_atomic64, 0x2222222222222222ULL); #ifndef __clang__ - x64 += __atomic_fetch_nand_8 (&g_atomic64, 0xAAAAAAAAAAAAAAAAULL, 0); + x64 += __atomic_fetch_nand_8(&g_atomic64, 0xAAAAAAAAAAAAAAAAULL, 0); TEST_ASSERT_EQUAL_HEX64(0x9797979797979797ULL, x64); TEST_ASSERT_EQUAL_HEX64(0xDDDDDDDDDDDDDDDDULL, g_atomic64); // calls atomic_load @@ -48,13 +47,13 @@ TEST_CASE("stdatomic - test_32bit_atomics", "[newlib_stdatomic]") unsigned int x32 = 0; g_atomic32 = 0; - x32 += atomic_fetch_or (&g_atomic32, 0x11111111U); + x32 += atomic_fetch_or(&g_atomic32, 0x11111111U); x32 += atomic_fetch_xor(&g_atomic32, 0x33333333U); x32 += atomic_fetch_and(&g_atomic32, 0xf0f0f0f0U); x32 += atomic_fetch_sub(&g_atomic32, 0x0f0f0f0fU); x32 += atomic_fetch_add(&g_atomic32, 0x22222222U); #ifndef __clang__ - x32 += __atomic_fetch_nand_4 (&g_atomic32, 0xAAAAAAAAU, 0); + x32 += __atomic_fetch_nand_4(&g_atomic32, 0xAAAAAAAAU, 0); TEST_ASSERT_EQUAL_HEX32(0x97979797U, x32); TEST_ASSERT_EQUAL_HEX32(0xDDDDDDDDU, g_atomic32); @@ -69,13 +68,13 @@ TEST_CASE("stdatomic - test_16bit_atomics", "[newlib_stdatomic]") unsigned int x16 = 0; g_atomic16 = 0; - x16 += atomic_fetch_or (&g_atomic16, 0x1111); + x16 += atomic_fetch_or(&g_atomic16, 0x1111); x16 += atomic_fetch_xor(&g_atomic16, 0x3333); x16 += atomic_fetch_and(&g_atomic16, 0xf0f0); x16 += atomic_fetch_sub(&g_atomic16, 0x0f0f); x16 += atomic_fetch_add(&g_atomic16, 0x2222); #ifndef __clang__ - x16 += __atomic_fetch_nand_2 (&g_atomic16, 0xAAAA, 0); + x16 += __atomic_fetch_nand_2(&g_atomic16, 0xAAAA, 0); TEST_ASSERT_EQUAL_HEX16(0x9797, x16); TEST_ASSERT_EQUAL_HEX16(0xDDDD, g_atomic16); @@ -90,13 +89,13 @@ TEST_CASE("stdatomic - test_8bit_atomics", "[newlib_stdatomic]") unsigned int x8 = 0; g_atomic8 = 0; - x8 += atomic_fetch_or (&g_atomic8, 0x11); + x8 += atomic_fetch_or(&g_atomic8, 0x11); x8 += atomic_fetch_xor(&g_atomic8, 0x33); x8 += atomic_fetch_and(&g_atomic8, 0xf0); x8 += atomic_fetch_sub(&g_atomic8, 0x0f); x8 += atomic_fetch_add(&g_atomic8, 0x22); #ifndef __clang__ - x8 += __atomic_fetch_nand_1 (&g_atomic8, 0xAA, 0); + x8 += __atomic_fetch_nand_1(&g_atomic8, 0xAA, 0); TEST_ASSERT_EQUAL_HEX8(0x97, x8); TEST_ASSERT_EQUAL_HEX8(0xDD, g_atomic8); @@ -112,7 +111,7 @@ TEST_CASE("stdatomic - test_64bit_atomics", "[newlib_stdatomic]") unsigned long long x64 = 0; g_atomic64 = 0; // calls atomic_store - x64 += __atomic_or_fetch_8 (&g_atomic64, 0x1111111111111111ULL, 0); + x64 += __atomic_or_fetch_8(&g_atomic64, 0x1111111111111111ULL, 0); x64 += __atomic_xor_fetch_8(&g_atomic64, 0x3333333333333333ULL, 0); x64 += __atomic_and_fetch_8(&g_atomic64, 0xf0f0f0f0f0f0f0f0ULL, 0); x64 += __atomic_sub_fetch_8(&g_atomic64, 0x0f0f0f0f0f0f0f0fULL, 0); @@ -128,12 +127,12 @@ TEST_CASE("stdatomic - test_32bit_atomics", "[newlib_stdatomic]") unsigned int x32 = 0; g_atomic32 = 0; - x32 += __atomic_or_fetch_4 (&g_atomic32, 0x11111111U, 0); + x32 += __atomic_or_fetch_4(&g_atomic32, 0x11111111U, 0); x32 += __atomic_xor_fetch_4(&g_atomic32, 0x33333333U, 0); x32 += __atomic_and_fetch_4(&g_atomic32, 0xf0f0f0f0U, 0); x32 += __atomic_sub_fetch_4(&g_atomic32, 0x0f0f0f0fU, 0); x32 += __atomic_add_fetch_4(&g_atomic32, 0x22222222U, 0); - x32 += __atomic_nand_fetch_4 (&g_atomic32, 0xAAAAAAAAU, 0); + x32 += __atomic_nand_fetch_4(&g_atomic32, 0xAAAAAAAAU, 0); TEST_ASSERT_EQUAL_HEX32(0x75757574U, x32); TEST_ASSERT_EQUAL_HEX32(0xDDDDDDDDU, g_atomic32); @@ -144,12 +143,12 @@ TEST_CASE("stdatomic - test_16bit_atomics", "[newlib_stdatomic]") unsigned int x16 = 0; g_atomic16 = 0; - x16 += __atomic_or_fetch_2 (&g_atomic16, 0x1111, 0); + x16 += __atomic_or_fetch_2(&g_atomic16, 0x1111, 0); x16 += __atomic_xor_fetch_2(&g_atomic16, 0x3333, 0); x16 += __atomic_and_fetch_2(&g_atomic16, 0xf0f0, 0); x16 += __atomic_sub_fetch_2(&g_atomic16, 0x0f0f, 0); x16 += __atomic_add_fetch_2(&g_atomic16, 0x2222, 0); - x16 += __atomic_nand_fetch_2 (&g_atomic16, 0xAAAA, 0); + x16 += __atomic_nand_fetch_2(&g_atomic16, 0xAAAA, 0); TEST_ASSERT_EQUAL_HEX16(0x7574, x16); TEST_ASSERT_EQUAL_HEX16(0xDDDD, g_atomic16); @@ -160,12 +159,12 @@ TEST_CASE("stdatomic - test_8bit_atomics", "[newlib_stdatomic]") unsigned int x8 = 0; g_atomic8 = 0; - x8 += __atomic_or_fetch_1 (&g_atomic8, 0x11, 0); + x8 += __atomic_or_fetch_1(&g_atomic8, 0x11, 0); x8 += __atomic_xor_fetch_1(&g_atomic8, 0x33, 0); x8 += __atomic_and_fetch_1(&g_atomic8, 0xf0, 0); x8 += __atomic_sub_fetch_1(&g_atomic8, 0x0f, 0); x8 += __atomic_add_fetch_1(&g_atomic8, 0x22, 0); - x8 += __atomic_nand_fetch_1 (&g_atomic8, 0xAA, 0); + x8 += __atomic_nand_fetch_1(&g_atomic8, 0xAA, 0); TEST_ASSERT_EQUAL_HEX8(0x74, x8); TEST_ASSERT_EQUAL_HEX8(0xDD, g_atomic8); @@ -173,7 +172,6 @@ TEST_CASE("stdatomic - test_8bit_atomics", "[newlib_stdatomic]") #endif // #ifndef __clang__ - #define TEST_EXCLUSION(n) TEST_CASE("stdatomic - test_" #n "bit_exclusion", "[newlib_stdatomic]") \ { \ g_atomic ## n = 0; \ @@ -216,7 +214,6 @@ TEST_EXCLUSION(16) TEST_EXCLUSION_TASK(8) TEST_EXCLUSION(8) - #define ITER_COUNT 20000 #define TEST_RACE_OPERATION(ASSERT_SUFFIX, NAME, LHSTYPE, PRE, POST, INIT, FINAL) \ @@ -283,75 +280,75 @@ TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]") \ TEST_ASSERT(EXPECTED == var_##NAME); \ } -TEST_RACE_OPERATION ( ,uint8_add, uint8_t, , += 1, 0, (uint8_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint8_add_3, uint8_t, , += 3, 0, (uint8_t) (6*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint8_postinc, uint8_t, , ++, 0, (uint8_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint8_preinc, uint8_t, ++, , 0, (uint8_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint8_sub, uint8_t, , -= 1, 0, (uint8_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint8_sub_3, uint8_t, , -= 3, 0, (uint8_t) -(6*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint8_postdec, uint8_t, , --, 0, (uint8_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint8_predec, uint8_t, --, , 0, (uint8_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint8_mul, uint8_t, , *= 3, 1, (uint8_t) 0x1) - -TEST_RACE_OPERATION ( ,uint16_add, uint16_t, , += 1, 0, (uint16_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint16_add_3, uint16_t, , += 3, 0, (uint16_t) (6*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint16_postinc, uint16_t, , ++, 0, (uint16_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint16_preinc, uint16_t, ++, , 0, (uint16_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint16_sub, uint16_t, , -= 1, 0, (uint16_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint16_sub_3, uint16_t, , -= 3, 0, (uint16_t) -(6*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint16_postdec, uint16_t, , --, 0, (uint16_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint16_predec, uint16_t, --, , 0, (uint16_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint16_mul, uint16_t, , *= 3, 1, (uint16_t) 0x6D01) - -TEST_RACE_OPERATION ( ,uint32_add, uint32_t, , += 1, 0, (uint32_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint32_add_3, uint32_t, , += 3, 0, (uint32_t) (6*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint32_postinc, uint32_t, , ++, 0, (uint32_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint32_preinc, uint32_t, ++, , 0, (uint32_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint32_sub, uint32_t, , -= 1, 0, (uint32_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint32_sub_3, uint32_t, , -= 3, 0, (uint32_t) -(6*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint32_postdec, uint32_t, , --, 0, (uint32_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint32_predec, uint32_t, --, , 0, (uint32_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint32_mul, uint32_t, , *= 3, 1, (uint32_t) 0xC1E36D01U) - -TEST_RACE_OPERATION ( ,uint64_add, uint64_t, , += 1, 0, (uint64_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint64_add_3, uint64_t, , += 3, 0, (uint64_t) (6*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint64_add_neg, uint64_t, , += 1, -10000, (uint64_t) (2*ITER_COUNT-10000)) -TEST_RACE_OPERATION ( ,uint64_postinc, uint64_t, , ++, 0, (uint64_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint64_postinc_neg, uint64_t, , ++, -10000, (uint64_t) (2*ITER_COUNT-10000)) -TEST_RACE_OPERATION ( ,uint64_preinc, uint64_t, ++, , 0, (uint64_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint64_preinc_neg, uint64_t, ++, , -10000, (uint64_t) (2*ITER_COUNT-10000)) -TEST_RACE_OPERATION ( ,uint64_sub, uint64_t, , -= 1, 0, (uint64_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint64_sub_3, uint64_t, , -= 3, 0, (uint64_t) -(6*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint64_sub_neg, uint64_t, , -= 1, 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) -TEST_RACE_OPERATION ( ,uint64_postdec, uint64_t, , --, 0, (uint64_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint64_postdec_neg, uint64_t, , --, 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) -TEST_RACE_OPERATION ( ,uint64_predec, uint64_t, --, , 0, (uint64_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION ( ,uint64_predec_neg, uint64_t, --, , 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) -TEST_RACE_OPERATION ( ,uint64_mul, uint64_t, , *= 3, 1, (uint64_t) 0x988EE974C1E36D01ULL) - -TEST_RACE_OPERATION (_FLOAT ,float_add, float, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (_FLOAT ,complex_float_add, _Complex float, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (_FLOAT ,float_postinc, float, , ++, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (_FLOAT ,float_preinc, float, ++, , 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (_FLOAT ,float_sub, float, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (_FLOAT ,complex_float_sub, _Complex float, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (_FLOAT ,float_postdec, float, , --, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (_FLOAT ,float_predec, float, --, , 0, -(2*ITER_COUNT)) - -TEST_RACE_OPERATION (_DOUBLE ,double_add, double, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (_DOUBLE ,complex_double_add, _Complex double, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (_DOUBLE ,double_postinc, double, , ++, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (_DOUBLE ,double_preinc, double, ++, , 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (_DOUBLE ,double_sub, double, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (_DOUBLE ,complex_double_sub, _Complex double, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (_DOUBLE ,double_postdec, double, , --, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (_DOUBLE ,double_predec, double, --, , 0, -(2*ITER_COUNT)) - -TEST_RACE_OPERATION_LONG_DOUBLE (long_double_add, long double, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION_LONG_DOUBLE (complex_long_double_add, _Complex long double, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION_LONG_DOUBLE (long_double_postinc, long double, , ++, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION_LONG_DOUBLE (long_double_sub, long double, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION_LONG_DOUBLE (long_double_preinc, long double, ++, , 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION_LONG_DOUBLE (complex_long_double_sub, _Complex long double, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION_LONG_DOUBLE (long_double_postdec, long double, , --, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION_LONG_DOUBLE (long_double_predec, long double, --, , 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_add, uint8_t,, += 1, 0, (uint8_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_add_3, uint8_t,, += 3, 0, (uint8_t)(6 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_postinc, uint8_t,, ++, 0, (uint8_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_preinc, uint8_t, ++,, 0, (uint8_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_sub, uint8_t,, -= 1, 0, (uint8_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_sub_3, uint8_t,, -= 3, 0, (uint8_t) - (6 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_postdec, uint8_t,, --, 0, (uint8_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_predec, uint8_t, --,, 0, (uint8_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint8_mul, uint8_t,, *= 3, 1, (uint8_t) 0x1) + +TEST_RACE_OPERATION(, uint16_add, uint16_t,, += 1, 0, (uint16_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint16_add_3, uint16_t,, += 3, 0, (uint16_t)(6 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint16_postinc, uint16_t,, ++, 0, (uint16_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint16_preinc, uint16_t, ++,, 0, (uint16_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint16_sub, uint16_t,, -= 1, 0, (uint16_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint16_sub_3, uint16_t,, -= 3, 0, (uint16_t) - (6 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint16_postdec, uint16_t,, --, 0, (uint16_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint16_predec, uint16_t, --,, 0, (uint16_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint16_mul, uint16_t,, *= 3, 1, (uint16_t) 0x6D01) + +TEST_RACE_OPERATION(, uint32_add, uint32_t,, += 1, 0, (uint32_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint32_add_3, uint32_t,, += 3, 0, (uint32_t)(6 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint32_postinc, uint32_t,, ++, 0, (uint32_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint32_preinc, uint32_t, ++,, 0, (uint32_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint32_sub, uint32_t,, -= 1, 0, (uint32_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint32_sub_3, uint32_t,, -= 3, 0, (uint32_t) - (6 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint32_postdec, uint32_t,, --, 0, (uint32_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint32_predec, uint32_t, --,, 0, (uint32_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint32_mul, uint32_t,, *= 3, 1, (uint32_t) 0xC1E36D01U) + +TEST_RACE_OPERATION(, uint64_add, uint64_t,, += 1, 0, (uint64_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint64_add_3, uint64_t,, += 3, 0, (uint64_t)(6 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint64_add_neg, uint64_t,, += 1, -10000, (uint64_t)(2 * ITER_COUNT - 10000)) +TEST_RACE_OPERATION(, uint64_postinc, uint64_t,, ++, 0, (uint64_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint64_postinc_neg, uint64_t,, ++, -10000, (uint64_t)(2 * ITER_COUNT - 10000)) +TEST_RACE_OPERATION(, uint64_preinc, uint64_t, ++,, 0, (uint64_t)(2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint64_preinc_neg, uint64_t, ++,, -10000, (uint64_t)(2 * ITER_COUNT - 10000)) +TEST_RACE_OPERATION(, uint64_sub, uint64_t,, -= 1, 0, (uint64_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint64_sub_3, uint64_t,, -= 3, 0, (uint64_t) - (6 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint64_sub_neg, uint64_t,, -= 1, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000)) +TEST_RACE_OPERATION(, uint64_postdec, uint64_t,, --, 0, (uint64_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint64_postdec_neg, uint64_t,, --, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000)) +TEST_RACE_OPERATION(, uint64_predec, uint64_t, --,, 0, (uint64_t) - (2 * ITER_COUNT)) +TEST_RACE_OPERATION(, uint64_predec_neg, uint64_t, --,, 10000, (uint64_t)((-2 * ITER_COUNT) + 10000)) +TEST_RACE_OPERATION(, uint64_mul, uint64_t,, *= 3, 1, (uint64_t) 0x988EE974C1E36D01ULL) + +TEST_RACE_OPERATION(_FLOAT, float_add, float,, += 1, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION(_FLOAT, complex_float_add, _Complex float,, += 1, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION(_FLOAT, float_postinc, float,, ++, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION(_FLOAT, float_preinc, float, ++,, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION(_FLOAT, float_sub, float,, -= 1, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION(_FLOAT, complex_float_sub, _Complex float,, -= 1, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION(_FLOAT, float_postdec, float,, --, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION(_FLOAT, float_predec, float, --,, 0, -(2 * ITER_COUNT)) + +TEST_RACE_OPERATION(_DOUBLE, double_add, double,, += 1, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION(_DOUBLE, complex_double_add, _Complex double,, += 1, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION(_DOUBLE, double_postinc, double,, ++, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION(_DOUBLE, double_preinc, double, ++,, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION(_DOUBLE, double_sub, double,, -= 1, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION(_DOUBLE, complex_double_sub, _Complex double,, -= 1, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION(_DOUBLE, double_postdec, double,, --, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION(_DOUBLE, double_predec, double, --,, 0, -(2 * ITER_COUNT)) + +TEST_RACE_OPERATION_LONG_DOUBLE(long_double_add, long double,, += 1, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_add, _Complex long double,, += 1, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postinc, long double,, ++, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE(long_double_sub, long double,, -= 1, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE(long_double_preinc, long double, ++,, 0, (2 * ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE(complex_long_double_sub, _Complex long double,, -= 1, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE(long_double_postdec, long double,, --, 0, -(2 * ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE(long_double_predec, long double, --,, 0, -(2 * ITER_COUNT)) diff --git a/components/newlib/test_apps/newlib/main/test_time.c b/components/newlib/test_apps/newlib/main/test_time.c index 9cc3cc221e0d..37b7e78c2e7c 100644 --- a/components/newlib/test_apps/newlib/main/test_time.c +++ b/components/newlib/test_apps/newlib/main/test_time.c @@ -72,7 +72,6 @@ static void time_adc_test_task(void* arg) vTaskDelete(NULL); } - TEST_CASE("Reading RTC registers on APP CPU doesn't affect clock", "[newlib]") { SemaphoreHandle_t done = xSemaphoreCreateBinary(); @@ -82,7 +81,7 @@ TEST_CASE("Reading RTC registers on APP CPU doesn't affect clock", "[newlib]") for (int i = 0; i < 4; ++i) { struct timeval tv_start; gettimeofday(&tv_start, NULL); - vTaskDelay(1000/portTICK_PERIOD_MS); + vTaskDelay(1000 / portTICK_PERIOD_MS); struct timeval tv_stop; gettimeofday(&tv_stop, NULL); float time_sec = tv_stop.tv_sec - tv_start.tv_sec + 1e-6f * (tv_stop.tv_usec - tv_start.tv_usec); @@ -190,7 +189,9 @@ static void adjtimeTask2(void *pvParameters) while (exit_flag == false) { delta.tv_sec += 1; delta.tv_usec = 900000; - if (delta.tv_sec >= 2146) delta.tv_sec = 1; + if (delta.tv_sec >= 2146) { + delta.tv_sec = 1; + } adjtime(&delta, &outdelta); } xSemaphoreGive(*sema); @@ -242,7 +243,7 @@ TEST_CASE("test for no interlocking adjtime, gettimeofday and settimeofday funct // set exit flag to let thread exit exit_flag = true; for (int i = 0; i < max_tasks; ++i) { - if (!xSemaphoreTake(exit_sema[i], 2000/portTICK_PERIOD_MS)) { + if (!xSemaphoreTake(exit_sema[i], 2000 / portTICK_PERIOD_MS)) { TEST_FAIL_MESSAGE("exit_sema not released by test task"); } vSemaphoreDelete(exit_sema[i]); @@ -284,7 +285,7 @@ static int64_t calc_correction(const char* tag, int64_t* sys_time, int64_t* real int64_t real_correction_us = dt_sys_time_us - dt_real_time_us; int64_t error_us = calc_correction_us - real_correction_us; printf("%s: dt_real_time = %lli us, dt_sys_time = %lli us, calc_correction = %lli us, error = %lli us\n", - tag, dt_real_time_us, dt_sys_time_us, calc_correction_us, error_us); + tag, dt_real_time_us, dt_sys_time_us, calc_correction_us, error_us); TEST_ASSERT_TRUE(dt_sys_time_us > 0 && dt_real_time_us > 0); TEST_ASSERT_INT_WITHIN(100, 0, error_us); @@ -349,7 +350,7 @@ TEST_CASE("test time adjustment happens linearly", "[newlib][timeout=15]") exit_flag = true; for (int i = 0; i < 2; ++i) { - if (!xSemaphoreTake(exit_sema[i], 2100/portTICK_PERIOD_MS)) { + if (!xSemaphoreTake(exit_sema[i], 2100 / portTICK_PERIOD_MS)) { TEST_FAIL_MESSAGE("exit_sema not released by test task"); } } @@ -360,7 +361,7 @@ TEST_CASE("test time adjustment happens linearly", "[newlib][timeout=15]") } #endif -void test_posix_timers_clock (void) +void test_posix_timers_clock(void) { #ifndef _POSIX_TIMERS TEST_ASSERT_MESSAGE(false, "_POSIX_TIMERS - is not defined"); @@ -475,7 +476,7 @@ static struct timeval get_time(const char *desc, char *buffer) TEST_CASE("test time_t wide 64 bits", "[newlib]") { static char buffer[32]; - ESP_LOGI("TAG", "sizeof(time_t): %d (%d-bit)", sizeof(time_t), sizeof(time_t)*8); + ESP_LOGI("TAG", "sizeof(time_t): %d (%d-bit)", sizeof(time_t), sizeof(time_t) * 8); TEST_ASSERT_EQUAL(8, sizeof(time_t)); // mktime takes current timezone into account, this test assumes it's UTC+0 @@ -563,7 +564,6 @@ TEST_CASE("test time functions wide 64 bits", "[newlib]") extern int64_t s_microseconds_offset; static const uint64_t s_start_timestamp = 1606838354; - static __NOINIT_ATTR uint64_t s_saved_time; static __NOINIT_ATTR uint64_t s_time_in_reboot; @@ -662,7 +662,6 @@ static void check_time(void) TEST_ASSERT_LESS_OR_EQUAL(latency_before_run_ut, dt); } - TEST_CASE_MULTIPLE_STAGES("Timestamp after abort is correct in case RTC & High-res timer have + big error", "[newlib][reset=abort,SW_CPU_RESET]", set_timestamp1, check_time); TEST_CASE_MULTIPLE_STAGES("Timestamp after restart is correct in case RTC & High-res timer have + big error", "[newlib][reset=SW_CPU_RESET]", set_timestamp2, check_time); TEST_CASE_MULTIPLE_STAGES("Timestamp after restart is correct in case RTC & High-res timer have - big error", "[newlib][reset=SW_CPU_RESET]", set_timestamp3, check_time); diff --git a/components/newlib/time.c b/components/newlib/time.c index 1fa1936bd739..bc23c1b6f0cc 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -45,7 +45,7 @@ static _lock_t s_time_lock; // This function gradually changes boot_time to the correction value and immediately updates it. static uint64_t adjust_boot_time(void) { - #define ADJTIME_CORRECTION_FACTOR 6 +#define ADJTIME_CORRECTION_FACTOR 6 uint64_t boot_time = esp_time_impl_get_boot_time(); if ((boot_time == 0) || (esp_time_impl_get_time_since_boot() < s_adjtime_start_us)) { @@ -83,7 +83,6 @@ static uint64_t adjust_boot_time(void) return boot_time; } - // Get the adjusted boot time. static uint64_t get_adjusted_boot_time(void) { @@ -94,10 +93,10 @@ static uint64_t get_adjusted_boot_time(void) } // Applying the accumulated correction to base_time and stopping the smooth time adjustment. -static void adjtime_corr_stop (void) +static void adjtime_corr_stop(void) { _lock_acquire(&s_time_lock); - if (s_adjtime_start_us != 0){ + if (s_adjtime_start_us != 0) { adjust_boot_time(); s_adjtime_start_us = 0; } @@ -108,7 +107,7 @@ static void adjtime_corr_stop (void) int adjtime(const struct timeval *delta, struct timeval *outdelta) { #if IMPL_NEWLIB_TIME_FUNCS - if(outdelta != NULL){ + if (outdelta != NULL) { _lock_acquire(&s_time_lock); adjust_boot_time(); if (s_adjtime_start_us != 0) { @@ -120,10 +119,10 @@ int adjtime(const struct timeval *delta, struct timeval *outdelta) } _lock_release(&s_time_lock); } - if(delta != NULL){ + if (delta != NULL) { int64_t sec = delta->tv_sec; int64_t usec = delta->tv_usec; - if(llabs(sec) > ((INT_MAX / 1000000L) - 1L)) { + if (llabs(sec) > ((INT_MAX / 1000000L) - 1L)) { errno = EINVAL; return -1; } @@ -208,7 +207,7 @@ int usleep(useconds_t us) unsigned int sleep(unsigned int seconds) { - usleep(seconds*1000000UL); + usleep(seconds * 1000000UL); return 0; } @@ -221,14 +220,14 @@ int clock_settime(clockid_t clock_id, const struct timespec *tp) } struct timeval tv; switch (clock_id) { - case CLOCK_REALTIME: - tv.tv_sec = tp->tv_sec; - tv.tv_usec = tp->tv_nsec / 1000L; - settimeofday(&tv, NULL); - break; - default: - errno = EINVAL; - return -1; + case CLOCK_REALTIME: + tv.tv_sec = tp->tv_sec; + tv.tv_usec = tp->tv_nsec / 1000L; + settimeofday(&tv, NULL); + break; + default: + errno = EINVAL; + return -1; } return 0; #else @@ -237,7 +236,7 @@ int clock_settime(clockid_t clock_id, const struct timespec *tp) #endif } -int clock_gettime (clockid_t clock_id, struct timespec *tp) +int clock_gettime(clockid_t clock_id, struct timespec *tp) { #if IMPL_NEWLIB_TIME_FUNCS if (tp == NULL) { @@ -247,19 +246,19 @@ int clock_gettime (clockid_t clock_id, struct timespec *tp) struct timeval tv; uint64_t monotonic_time_us = 0; switch (clock_id) { - case CLOCK_REALTIME: - _gettimeofday_r(NULL, &tv, NULL); - tp->tv_sec = tv.tv_sec; - tp->tv_nsec = tv.tv_usec * 1000L; - break; - case CLOCK_MONOTONIC: - monotonic_time_us = esp_time_impl_get_time(); - tp->tv_sec = monotonic_time_us / 1000000LL; - tp->tv_nsec = (monotonic_time_us % 1000000LL) * 1000L; - break; - default: - errno = EINVAL; - return -1; + case CLOCK_REALTIME: + _gettimeofday_r(NULL, &tv, NULL); + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * 1000L; + break; + case CLOCK_MONOTONIC: + monotonic_time_us = esp_time_impl_get_time(); + tp->tv_sec = monotonic_time_us / 1000000LL; + tp->tv_nsec = (monotonic_time_us % 1000000LL) * 1000L; + break; + default: + errno = EINVAL; + return -1; } return 0; #else @@ -268,7 +267,7 @@ int clock_gettime (clockid_t clock_id, struct timespec *tp) #endif } -int clock_getres (clockid_t clock_id, struct timespec *res) +int clock_getres(clockid_t clock_id, struct timespec *res) { #if IMPL_NEWLIB_TIME_FUNCS if (res == NULL) { diff --git a/components/pthread/pthread.c b/components/pthread/pthread.c index 53ea4b26aac9..3fbda1219572 100644 --- a/components/pthread/pthread.c +++ b/components/pthread/pthread.c @@ -62,10 +62,9 @@ typedef struct { static SemaphoreHandle_t s_threads_mux = NULL; portMUX_TYPE pthread_lazy_init_lock = portMUX_INITIALIZER_UNLOCKED; // Used for mutexes and cond vars and rwlocks static SLIST_HEAD(esp_thread_list_head, esp_pthread_entry) s_threads_list - = SLIST_HEAD_INITIALIZER(s_threads_list); + = SLIST_HEAD_INITIALIZER(s_threads_list); static pthread_key_t s_pthread_cfg_key; - static int pthread_mutex_lock_internal(esp_pthread_mutex_t *mux, TickType_t tmo); static void esp_pthread_cfg_key_destructor(void *value) @@ -239,16 +238,16 @@ static UBaseType_t coreID_to_AffinityMask(BaseType_t core_id) #endif static BaseType_t pthread_create_freertos_task_with_caps(TaskFunction_t pxTaskCode, - const char * const pcName, - const configSTACK_DEPTH_TYPE usStackDepth, - void * const pvParameters, - UBaseType_t uxPriority, - BaseType_t core_id, - UBaseType_t uxStackMemoryCaps, - TaskHandle_t * const pxCreatedTask) + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + BaseType_t core_id, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask) { #if CONFIG_SPIRAM - #if CONFIG_FREERTOS_SMP +#if CONFIG_FREERTOS_SMP return prvTaskCreateDynamicAffinitySetWithCaps(pxTaskCode, pcName, usStackDepth, @@ -257,7 +256,7 @@ static BaseType_t pthread_create_freertos_task_with_caps(TaskFunction_t pxTaskCo coreID_to_AffinityMask(core_id), uxStackMemoryCaps, pxCreatedTask); - #else +#else return prvTaskCreateDynamicPinnedToCoreWithCaps(pxTaskCode, pcName, usStackDepth, @@ -266,7 +265,7 @@ static BaseType_t pthread_create_freertos_task_with_caps(TaskFunction_t pxTaskCo core_id, uxStackMemoryCaps, pxCreatedTask); - #endif +#endif #else return xTaskCreatePinnedToCore(pxTaskCode, pcName, @@ -279,7 +278,7 @@ static BaseType_t pthread_create_freertos_task_with_caps(TaskFunction_t pxTaskCo } int pthread_create(pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine) (void *), void *arg) + void *(*start_routine)(void *), void *arg) { TaskHandle_t xHandle = NULL; @@ -360,13 +359,13 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr, pthread->task_arg = task_arg; BaseType_t res = pthread_create_freertos_task_with_caps(&pthread_task_func, - task_name, - stack_size, - task_arg, - prio, - core_id, - stack_alloc_caps, - &xHandle); + task_name, + stack_size, + task_arg, + prio, + core_id, + stack_alloc_caps, + &xHandle); if (res != pdPASS) { ESP_LOGE(TAG, "Failed to create task!"); @@ -549,7 +548,7 @@ int pthread_cancel(pthread_t thread) return ENOSYS; } -int sched_yield( void ) +int sched_yield(void) { vTaskDelay(0); return 0; @@ -594,8 +593,8 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) static int mutexattr_check(const pthread_mutexattr_t *attr) { if (attr->type != PTHREAD_MUTEX_NORMAL && - attr->type != PTHREAD_MUTEX_RECURSIVE && - attr->type != PTHREAD_MUTEX_ERRORCHECK) { + attr->type != PTHREAD_MUTEX_RECURSIVE && + attr->type != PTHREAD_MUTEX_ERRORCHECK) { return EINVAL; } return 0; @@ -686,7 +685,7 @@ static int pthread_mutex_lock_internal(esp_pthread_mutex_t *mux, TickType_t tmo) } if ((mux->type == PTHREAD_MUTEX_ERRORCHECK) && - (xSemaphoreGetMutexHolder(mux->sem) == xTaskGetCurrentTaskHandle())) { + (xSemaphoreGetMutexHolder(mux->sem) == xTaskGetCurrentTaskHandle())) { return EDEADLK; } @@ -740,8 +739,8 @@ int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *timeo struct timespec currtime; clock_gettime(CLOCK_REALTIME, &currtime); - TickType_t tmo = ((timeout->tv_sec - currtime.tv_sec)*1000 + - (timeout->tv_nsec - currtime.tv_nsec)/1000000)/portTICK_PERIOD_MS; + TickType_t tmo = ((timeout->tv_sec - currtime.tv_sec) * 1000 + + (timeout->tv_nsec - currtime.tv_nsec) / 1000000) / portTICK_PERIOD_MS; res = pthread_mutex_lock_internal((esp_pthread_mutex_t *)*mutex, tmo); if (res == EBUSY) { @@ -775,8 +774,8 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex) } if (((mux->type == PTHREAD_MUTEX_RECURSIVE) || - (mux->type == PTHREAD_MUTEX_ERRORCHECK)) && - (xSemaphoreGetMutexHolder(mux->sem) != xTaskGetCurrentTaskHandle())) { + (mux->type == PTHREAD_MUTEX_ERRORCHECK)) && + (xSemaphoreGetMutexHolder(mux->sem) != xTaskGetCurrentTaskHandle())) { return EPERM; } diff --git a/components/pthread/pthread_cond_var.c b/components/pthread/pthread_cond_var.c index 0395c2cca254..145ae430747b 100644 --- a/components/pthread/pthread_cond_var.c +++ b/components/pthread/pthread_cond_var.c @@ -127,7 +127,7 @@ int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mut, const struc timersub(&abs_time, &cur_time, &diff_time); // Round up timeout microseconds to the next millisecond timeout_msec = (diff_time.tv_sec * 1000) + - ((diff_time.tv_usec + 1000 - 1) / 1000); + ((diff_time.tv_usec + 1000 - 1) / 1000); } if (timeout_msec <= 0) { diff --git a/components/pthread/pthread_local_storage.c b/components/pthread/pthread_local_storage.c index abb547675bda..19cb73a98d88 100644 --- a/components/pthread/pthread_local_storage.c +++ b/components/pthread/pthread_local_storage.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ /* Sanity check to ensure that the number of FreeRTOS TLSPs is at least 1 */ #if (CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS < 1) - #error "CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS cannot be 0 for pthread TLS" +#error "CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS cannot be 0 for pthread TLS" #endif #define PTHREAD_TLS_INDEX 0 @@ -77,7 +77,7 @@ static key_entry_t *find_key(pthread_key_t key) portENTER_CRITICAL(&s_keys_lock); key_entry_t *result = NULL;; SLIST_FOREACH(result, &s_keys, next) { - if(result->key == key) { + if (result->key == key) { break; } } @@ -171,7 +171,7 @@ static value_entry_t *find_value(const values_list_t *list, pthread_key_t key) { value_entry_t *result = NULL;; SLIST_FOREACH(result, list, next) { - if(result->key == key) { + if (result->key == key) { break; } } @@ -186,7 +186,7 @@ void *pthread_getspecific(pthread_key_t key) } value_entry_t *entry = find_value(tls, key); - if(entry != NULL) { + if (entry != NULL) { return entry->value; } return NULL; diff --git a/components/pthread/pthread_rwlock.c b/components/pthread/pthread_rwlock.c index 91f4d49420b9..846225562b04 100644 --- a/components/pthread/pthread_rwlock.c +++ b/components/pthread/pthread_rwlock.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,7 +23,6 @@ #include "esp_log.h" const static char *TAG = "pthread_rw_lock"; - /** pthread rw_mutex FreeRTOS wrapper */ typedef struct { /** @@ -46,8 +45,8 @@ typedef struct { #define WRITER_QUEUE_SIZE 4 #define READER_QUEUE_SIZE 4 -int pthread_rwlock_init (pthread_rwlock_t *rwlock, - const pthread_rwlockattr_t *attr) +int pthread_rwlock_init(pthread_rwlock_t *rwlock, + const pthread_rwlockattr_t *attr) { int result; if (!rwlock) { @@ -99,7 +98,7 @@ static int pthread_rwlock_init_if_static(pthread_rwlock_t *rwlock) return res; } -int pthread_rwlock_destroy (pthread_rwlock_t *rwlock) +int pthread_rwlock_destroy(pthread_rwlock_t *rwlock) { esp_pthread_rwlock_t *esp_rwlock; @@ -158,7 +157,7 @@ static int checkrw_lock(pthread_rwlock_t *rwlock) return 0; } -int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) +int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) { esp_pthread_rwlock_t *esp_rwlock; int res; @@ -191,7 +190,7 @@ int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) return 0; } -int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) +int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) { esp_pthread_rwlock_t *esp_rwlock; int res; @@ -219,7 +218,7 @@ int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) return res; } -int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) +int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) { esp_pthread_rwlock_t *esp_rwlock; int res; @@ -247,7 +246,8 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) return 0; } -int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) { +int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) +{ esp_pthread_rwlock_t *esp_rwlock; int res; @@ -276,7 +276,7 @@ int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) { return res; } -int pthread_rwlock_unlock (pthread_rwlock_t *rwlock) +int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) { esp_pthread_rwlock_t *esp_rwlock; int res; diff --git a/components/pthread/pthread_semaphore.c b/components/pthread/pthread_semaphore.c index ca030db65e10..c424c4a7d4ec 100644 --- a/components/pthread/pthread_semaphore.c +++ b/components/pthread/pthread_semaphore.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,7 @@ int sem_destroy(sem_t * semaphore) return -1; } - SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) *semaphore; + SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) * semaphore; vSemaphoreDelete(freertos_semaphore); return 0; } @@ -60,7 +60,7 @@ int sem_post(sem_t * semaphore) return -1; } - SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) *semaphore; + SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) * semaphore; BaseType_t ret = xSemaphoreGive(freertos_semaphore); if (ret == pdFALSE) { @@ -96,7 +96,7 @@ int sem_timedwait(sem_t * restrict semaphore, const struct timespec *restrict ab long timeout_msec; // Round up timeout nanoseconds to the next millisecond timeout_msec = (diff_time.tv_sec * 1000) + - ((diff_time.tv_nsec + (1 * MIO) - 1) / (1 * MIO)); + ((diff_time.tv_nsec + (1 * MIO) - 1) / (1 * MIO)); // Round up milliseconds to the next tick timeout_ticks = (timeout_msec + portTICK_PERIOD_MS - 1) / portTICK_PERIOD_MS; @@ -112,7 +112,7 @@ int sem_timedwait(sem_t * restrict semaphore, const struct timespec *restrict ab timeout_ticks += 1; } - SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) *semaphore; + SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) * semaphore; BaseType_t sem_take_result; sem_take_result = xSemaphoreTake(freertos_semaphore, timeout_ticks); if (sem_take_result == pdFALSE) { @@ -130,7 +130,7 @@ int sem_trywait(sem_t * semaphore) return -1; } - SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) *semaphore; + SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) * semaphore; BaseType_t ret = xSemaphoreTake(freertos_semaphore, 0); @@ -149,7 +149,7 @@ int sem_wait(sem_t * semaphore) return -1; } - SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) *semaphore; + SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) * semaphore; // Only returns failure if block time expires, but we block indefinitely, hence not return code check xSemaphoreTake(freertos_semaphore, portMAX_DELAY); @@ -168,7 +168,7 @@ int sem_getvalue(sem_t *restrict semaphore, int *restrict sval) return -1; } - SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) *semaphore; + SemaphoreHandle_t freertos_semaphore = (SemaphoreHandle_t) * semaphore; *sval = uxSemaphoreGetCount(freertos_semaphore); return 0; } diff --git a/components/pthread/test_apps/pthread_unity_tests/main/test_app_main.c b/components/pthread/test_apps/pthread_unity_tests/main/test_app_main.c index 7b647833b81e..0f773d0fed46 100644 --- a/components/pthread/test_apps/pthread_unity_tests/main/test_app_main.c +++ b/components/pthread/test_apps/pthread_unity_tests/main/test_app_main.c @@ -11,7 +11,6 @@ #include "unity_test_runner.h" #include "esp_heap_caps.h" - // Some resources are lazy allocated (e.g. newlib locks), the threshold is left for that case #define TEST_MEMORY_LEAK_THRESHOLD (-200) diff --git a/components/pthread/test_apps/pthread_unity_tests/main/test_cxx_cond_var.cpp b/components/pthread/test_apps/pthread_unity_tests/main/test_cxx_cond_var.cpp index 18c1e2692bb4..10548dab6233 100644 --- a/components/pthread/test_apps/pthread_unity_tests/main/test_cxx_cond_var.cpp +++ b/components/pthread/test_apps/pthread_unity_tests/main/test_cxx_cond_var.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -24,10 +24,13 @@ static void waits(int idx, int timeout_ms) std::unique_lock lk(cv_m); auto now = std::chrono::system_clock::now(); - if(cv.wait_until(lk, now + std::chrono::milliseconds(timeout_ms), [](){return i == 1;})) - std::cout << "Thread " << idx << " finished waiting. i == " << i << '\n'; - else + if (cv.wait_until(lk, now + std::chrono::milliseconds(timeout_ms), []() { + return i == 1; +})) + std::cout << "Thread " << idx << " finished waiting. i == " << i << '\n'; + else { std::cout << "Thread " << idx << " timed out. i == " << i << '\n'; + } } static void signals(int signal_ms) @@ -53,7 +56,6 @@ TEST_CASE("C++ condition_variable", "[std::condition_variable]") std::cout << "All threads joined\n"; } - TEST_CASE("cxx: condition_variable can timeout", "[cxx]") { std::condition_variable cv; @@ -76,19 +78,20 @@ TEST_CASE("cxx: condition_variable timeout never before deadline", "[cxx]") std::unique_lock lock(mutex); for (int i = 0; i < 25; ++i) { - auto timeout = std::chrono::milliseconds(portTICK_PERIOD_MS * (i+1)); + auto timeout = std::chrono::milliseconds(portTICK_PERIOD_MS * (i + 1)); auto deadline = SysClock::now() + timeout; auto secs = std::chrono::time_point_cast(deadline); auto nsecs = std::chrono::duration_cast - (deadline - secs); + (deadline - secs); struct timespec ts = { - .tv_sec = static_cast(secs.time_since_epoch().count()), - .tv_nsec = static_cast(nsecs.count())}; + .tv_sec = static_cast(secs.time_since_epoch().count()), + .tv_nsec = static_cast(nsecs.count()) + }; int rc = ::pthread_cond_timedwait(cond.native_handle(), lock.mutex()->native_handle(), &ts); auto status = (rc == ETIMEDOUT) ? std::cv_status::timeout : - std::cv_status::no_timeout; + std::cv_status::no_timeout; auto end = SysClock::now(); auto extra = end - deadline; auto extra_us = extra / std::chrono::microseconds(1); diff --git a/components/pthread/test_apps/pthread_unity_tests/main/test_cxx_std_future.cpp b/components/pthread/test_apps/pthread_unity_tests/main/test_cxx_std_future.cpp index 58f4fcb0bae3..892e105d20fd 100644 --- a/components/pthread/test_apps/pthread_unity_tests/main/test_cxx_std_future.cpp +++ b/components/pthread/test_apps/pthread_unity_tests/main/test_cxx_std_future.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -12,17 +12,17 @@ TEST_CASE("C++ future", "[std::future]") { // future from a packaged_task - std::packaged_task task([]{ return 7; }); // wrap the function + std::packaged_task task([] { return 7; }); // wrap the function std::future f1 = task.get_future(); // get a future std::thread t(std::move(task)); // launch on a thread // future from an async() - std::future f2 = std::async(std::launch::async, []{ return 8; }); + std::future f2 = std::async(std::launch::async, [] { return 8; }); // future from a promise std::promise p; std::future f3 = p.get_future(); - std::thread( [&p]{ p.set_value_at_thread_exit(9); }).detach(); + std::thread([&p] { p.set_value_at_thread_exit(9); }).detach(); std::cout << "Waiting..." << std::flush; f1.wait(); diff --git a/components/pthread/test_apps/pthread_unity_tests/main/test_pthread.c b/components/pthread/test_apps/pthread_unity_tests/main/test_pthread.c index a85b03b4ddc6..2ebc220b1358 100644 --- a/components/pthread/test_apps/pthread_unity_tests/main/test_pthread.c +++ b/components/pthread/test_apps/pthread_unity_tests/main/test_pthread.c @@ -232,7 +232,7 @@ static void test_mutex_lock_unlock(int mutex_type) res = pthread_mutex_lock(&mutex); - if(mutex_type == PTHREAD_MUTEX_ERRORCHECK) { + if (mutex_type == PTHREAD_MUTEX_ERRORCHECK) { TEST_ASSERT_EQUAL_INT(EDEADLK, res); } else { TEST_ASSERT_EQUAL_INT(0, res); diff --git a/components/pthread/test_apps/pthread_unity_tests/main/test_pthread_local_storage.c b/components/pthread/test_apps/pthread_unity_tests/main/test_pthread_local_storage.c index eeb9e565504f..cb8191e60fcb 100644 --- a/components/pthread/test_apps/pthread_unity_tests/main/test_pthread_local_storage.c +++ b/components/pthread/test_apps/pthread_unity_tests/main/test_pthread_local_storage.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -114,7 +114,7 @@ TEST_CASE("pthread local storage destructor in FreeRTOS task", "[thread-specific TEST_ASSERT_EQUAL(0, pthread_key_create(&key, test_pthread_destructor)); xTaskCreate(task_test_pthread_destructor, - "ptdest", 8192, (void *)key, UNITY_FREERTOS_PRIORITY+1, + "ptdest", 8192, (void *)key, UNITY_FREERTOS_PRIORITY + 1, NULL); // Above task has higher priority to us, so should run immediately @@ -146,14 +146,13 @@ static void *thread_stress_test(void *v_key) pthread_setspecific(key, tls_value); - for(int i = 0; i < STRESS_NUMITER; i++) { + for (int i = 0; i < STRESS_NUMITER; i++) { TEST_ASSERT_EQUAL_HEX32(pthread_getspecific(key), tls_value); } return NULL; } - // This test case added to reproduce issues with unpinned tasks and TLS TEST_CASE("pthread local storage stress test", "[thread-specific]") { @@ -169,7 +168,6 @@ TEST_CASE("pthread local storage stress test", "[thread-specific]") } } - #define NUM_KEYS 4 // number of keys used in repeat destructor test #define NUM_REPEATS 17 // number of times we re-set a key to a non-NULL value to re-trigger destructor @@ -179,7 +177,6 @@ typedef struct { int last_idx; // index of last key where destructor was called } destr_test_state_t; - static void s_test_repeat_destructor(void *vp_state); static void *s_test_repeat_destructor_thread(void *vp_state); @@ -202,7 +199,7 @@ TEST_CASE("pthread local storage 'repeat' destructor test", "[thread-specific]") TEST_ASSERT_EQUAL(0, r); r = pthread_join(thread, NULL); - TEST_ASSERT_EQUAL(0 ,r); + TEST_ASSERT_EQUAL(0, r); // Cheating here to make sure compiler reads the value of 'count' from memory not from a register // diff --git a/tools/ci/astyle-rules.yml b/tools/ci/astyle-rules.yml index 30fa324b0e87..33fe7f946c00 100644 --- a/tools/ci/astyle-rules.yml +++ b/tools/ci/astyle-rules.yml @@ -80,7 +80,6 @@ components_not_formatted_temporary: - "/components/lwip/" - "/components/mbedtls/" - "/components/mqtt/" - - "/components/newlib/" - "/components/nvs_flash/" - "/components/nvs_sec_provider/" - "/components/openthread/" @@ -88,7 +87,6 @@ components_not_formatted_temporary: - "/components/perfmon/" - "/components/protobuf-c/" - "/components/protocomm/" - - "/components/pthread/" - "/components/riscv/" - "/components/sdmmc/" - "/components/soc/" From 7f22c235db4741bba0bbdf4f6e55531ea11ad65d Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Tue, 27 Feb 2024 14:46:55 +0100 Subject: [PATCH 06/33] refactor(esp_hid): Format the code with astyle --- .../include/esp_private/esp_hidd_private.h | 18 +-- .../include/esp_private/esp_hidh_private.h | 18 +-- components/esp_hid/src/ble_hidd.c | 15 +-- components/esp_hid/src/ble_hidh.c | 7 +- components/esp_hid/src/bt_hidd.c | 13 +- components/esp_hid/src/bt_hidh.c | 23 ++-- components/esp_hid/src/esp_hid_common.c | 11 +- components/esp_hid/src/esp_hidh.c | 8 +- components/esp_hid/src/nimble_hidd.c | 69 +++++----- components/esp_hid/src/nimble_hidh.c | 124 +++++++++--------- tools/ci/astyle-rules.yml | 1 - 11 files changed, 148 insertions(+), 159 deletions(-) diff --git a/components/esp_hid/include/esp_private/esp_hidd_private.h b/components/esp_hid/include/esp_private/esp_hidd_private.h index bac88d1e16c3..fccf4e22ee81 100644 --- a/components/esp_hid/include/esp_private/esp_hidd_private.h +++ b/components/esp_hid/include/esp_private/esp_hidd_private.h @@ -41,15 +41,15 @@ struct esp_hidd_dev_s { void *dev; esp_hid_transport_t transport; - bool (*connected) (void *dev); - esp_err_t (*deinit) (void *dev); - esp_err_t (*disconnect) (void *dev); - esp_err_t (*virtual_unplug) (void *dev); - esp_err_t (*battery_set) (void *dev, uint8_t level); - esp_err_t (*input_set) (void *dev, size_t map_index, size_t report_id, uint8_t *data, size_t length); - esp_err_t (*feature_set) (void *dev, size_t map_index, size_t report_id, uint8_t *data, size_t length); - esp_err_t (*event_handler_register) (void *dev, esp_event_handler_t callback, esp_hidd_event_t event); - esp_err_t (*event_handler_unregister) (void *dev, esp_event_handler_t callback, esp_hidd_event_t event); + bool (*connected)(void *dev); + esp_err_t (*deinit)(void *dev); + esp_err_t (*disconnect)(void *dev); + esp_err_t (*virtual_unplug)(void *dev); + esp_err_t (*battery_set)(void *dev, uint8_t level); + esp_err_t (*input_set)(void *dev, size_t map_index, size_t report_id, uint8_t *data, size_t length); + esp_err_t (*feature_set)(void *dev, size_t map_index, size_t report_id, uint8_t *data, size_t length); + esp_err_t (*event_handler_register)(void *dev, esp_event_handler_t callback, esp_hidd_event_t event); + esp_err_t (*event_handler_unregister)(void *dev, esp_event_handler_t callback, esp_hidd_event_t event); }; typedef struct esp_hidd_dev_s esp_hidd_dev_t; diff --git a/components/esp_hid/include/esp_private/esp_hidh_private.h b/components/esp_hid/include/esp_private/esp_hidh_private.h index 41fad3dce715..086000ec9f5f 100644 --- a/components/esp_hid/include/esp_private/esp_hidh_private.h +++ b/components/esp_hid/include/esp_private/esp_hidh_private.h @@ -69,15 +69,15 @@ struct esp_hidh_dev_s { SemaphoreHandle_t semaphore; SemaphoreHandle_t mutex; - esp_err_t (*close) (esp_hidh_dev_t *dev); - esp_err_t (*report_write) (esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, uint8_t *data, size_t len); - esp_err_t (*report_read) (esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, size_t max_length, uint8_t *value, size_t *value_len); - esp_err_t (*set_report) (esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, uint8_t *data, size_t len); - esp_err_t (*get_idle) (esp_hidh_dev_t *dev); - esp_err_t (*set_idle) (esp_hidh_dev_t *dev, uint8_t idle_time); - esp_err_t (*get_protocol) (esp_hidh_dev_t *dev); - esp_err_t (*set_protocol) (esp_hidh_dev_t *dev, uint8_t protocol_mode); - void (*dump) (esp_hidh_dev_t *dev, FILE *fp); + esp_err_t (*close)(esp_hidh_dev_t *dev); + esp_err_t (*report_write)(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, uint8_t *data, size_t len); + esp_err_t (*report_read)(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, size_t max_length, uint8_t *value, size_t *value_len); + esp_err_t (*set_report)(esp_hidh_dev_t *dev, size_t map_index, size_t report_id, int report_type, uint8_t *data, size_t len); + esp_err_t (*get_idle)(esp_hidh_dev_t *dev); + esp_err_t (*set_idle)(esp_hidh_dev_t *dev, uint8_t idle_time); + esp_err_t (*get_protocol)(esp_hidh_dev_t *dev); + esp_err_t (*set_protocol)(esp_hidh_dev_t *dev, uint8_t protocol_mode); + void (*dump)(esp_hidh_dev_t *dev, FILE *fp); union { #if CONFIG_BT_HID_HOST_ENABLED diff --git a/components/esp_hid/src/ble_hidd.c b/components/esp_hid/src/ble_hidd.c index 743b6c35ba22..ec8d9fd29bf9 100644 --- a/components/esp_hid/src/ble_hidd.c +++ b/components/esp_hid/src/ble_hidd.c @@ -141,7 +141,6 @@ struct esp_ble_hidd_dev_s { esp_hid_device_config_t config; uint16_t appearance; - bool connected; uint16_t conn_id; esp_bd_addr_t remote_bda; @@ -158,7 +157,6 @@ struct esp_ble_hidd_dev_s { uint16_t bat_level_handle; uint16_t bat_ccc_handle; - uint8_t pnp[7]; hidd_dev_map_t *devices; @@ -173,7 +171,6 @@ static const uint8_t hidInfo[4] = { ESP_HID_FLAGS_REMOTE_WAKE | ESP_HID_FLAGS_NORMALLY_CONNECTABLE // Flags }; - #define WAIT_CB(d) xSemaphoreTake(d->sem, portMAX_DELAY) #define SEND_CB(d) xSemaphoreGive(d->sem) @@ -181,7 +178,7 @@ static const char *gatts_evt_names[25] = { "REG", "READ", "WRITE", "EXEC_WRITE", static const char *gatts_evt_str(uint8_t event) { - if (event >= (sizeof(gatts_evt_names)/sizeof(*gatts_evt_names))) { + if (event >= (sizeof(gatts_evt_names) / sizeof(*gatts_evt_names))) { return "UNKNOWN"; } return gatts_evt_names[event]; @@ -230,8 +227,8 @@ static esp_err_t create_info_db(esp_ble_hidd_dev_t *dev) uint8_t pnp_val[7] = { 0x02, //0x1=BT, 0x2=USB dev->config.vendor_id & 0xFF, (dev->config.vendor_id >> 8) & 0xFF, //VID - dev->config.product_id & 0xFF, (dev->config.product_id >> 8) & 0xFF, //PID - dev->config.version & 0xFF, (dev->config.version >> 8) & 0xFF //VERSION + dev->config.product_id & 0xFF, (dev->config.product_id >> 8) & 0xFF, //PID + dev->config.version & 0xFF, (dev->config.version >> 8) & 0xFF //VERSION }; memcpy(dev->pnp, pnp_val, 7); add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read); @@ -335,7 +332,6 @@ static esp_err_t create_hid_db(esp_ble_hidd_dev_t *dev, int device_index) return err; } - static void link_report_handles(hidd_dev_map_t *dev, uint16_t *handles) { @@ -601,7 +597,7 @@ static void hid_event_handler(esp_ble_hidd_dev_t *dev, int device_index, esp_gat } } -static int get_device_map_index_by_gatts_if (esp_ble_hidd_dev_t *dev, esp_gatt_if_t gatts_if) +static int get_device_map_index_by_gatts_if(esp_ble_hidd_dev_t *dev, esp_gatt_if_t gatts_if) { for (uint8_t d = 0; d < dev->devices_len; d++) { if (dev->devices[d].hid_svc.gatt_if && gatts_if == dev->devices[d].hid_svc.gatt_if) { @@ -780,7 +776,7 @@ void esp_hidd_gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatt } else if (s_dev->info_svc.gatt_if && gatts_if == s_dev->info_svc.gatt_if) { info_event_handler(s_dev, event, gatts_if, param); } else { - int devi = get_device_map_index_by_gatts_if (s_dev, gatts_if); + int devi = get_device_map_index_by_gatts_if(s_dev, gatts_if); if (devi >= 0) { hid_event_handler(s_dev, devi, event, gatts_if, param); } else { @@ -971,7 +967,6 @@ esp_err_t esp_ble_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_conf return ESP_FAIL; } - esp_event_loop_args_t event_task_args = { .queue_size = 5, .task_name = "ble_hidd_events", diff --git a/components/esp_hid/src/ble_hidh.c b/components/esp_hid/src/ble_hidh.c index 817972623945..616bd278469f 100644 --- a/components/esp_hid/src/ble_hidh.c +++ b/components/esp_hid/src/ble_hidh.c @@ -28,7 +28,7 @@ static const char *s_gattc_evt_names[] = {"REG", "UNREG", "OPEN", "READ_CHAR", " const char *gattc_evt_str(uint8_t event) { - if (event >= (sizeof(s_gattc_evt_names)/sizeof(*s_gattc_evt_names))) { + if (event >= (sizeof(s_gattc_evt_names) / sizeof(*s_gattc_evt_names))) { return "UNKNOWN"; } return s_gattc_evt_names[event]; @@ -396,7 +396,6 @@ void esp_hidh_gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gatt SEND_CB();//return from open break; - case ESP_GATTC_READ_CHAR_EVT: case ESP_GATTC_READ_DESCR_EVT: { dev = esp_hidh_dev_get_by_conn_id(p_data->read.conn_id); @@ -607,8 +606,8 @@ static void esp_ble_hidh_dev_dump(esp_hidh_dev_t *dev, FILE *fp) while (report) { if (report->map_index == d) { fprintf(fp, " %8s %7s %6s, ID: %2u, Length: %3u, Permissions: 0x%02x, Handle: %3u, CCC Handle: %3u\n", - esp_hid_usage_str(report->usage), esp_hid_report_type_str(report->report_type), esp_hid_protocol_mode_str(report->protocol_mode), - report->report_id, report->value_len, report->permissions, report->handle, report->ccc_handle); + esp_hid_usage_str(report->usage), esp_hid_report_type_str(report->report_type), esp_hid_protocol_mode_str(report->protocol_mode), + report->report_id, report->value_len, report->permissions, report->handle, report->ccc_handle); } report = report->next; } diff --git a/components/esp_hid/src/bt_hidd.c b/components/esp_hid/src/bt_hidd.c index ec888267ffa2..beb05a0eff1c 100644 --- a/components/esp_hid/src/bt_hidd.c +++ b/components/esp_hid/src/bt_hidd.c @@ -43,8 +43,7 @@ typedef struct { uint8_t devices_len; } esp_bt_hidd_dev_t; -typedef struct -{ +typedef struct { osi_mutex_t mutex; esp_bt_hidd_dev_t *dev; esp_hidd_app_param_t app_param; @@ -313,7 +312,7 @@ static bool esp_bt_hidd_dev_connected(void *devp) ret = false; break; } - } while(0); + } while (0); if (ret) { ret = dev->connected; } @@ -337,7 +336,7 @@ static esp_err_t esp_bt_hidd_dev_deinit(void *devp) ESP_LOGE(TAG, "Wrong HID device provided"); ret = ESP_FAIL; } - } while(0); + } while (0); osi_mutex_unlock(&s_hidd_param.mutex); if (ret == ESP_OK) { @@ -369,7 +368,7 @@ static esp_err_t esp_bt_hidd_dev_disconnect(void *devp) ESP_LOGW(TAG, "already disconnected"); return ESP_OK; } - } while(0); + } while (0); osi_mutex_unlock(&s_hidd_param.mutex); if (ret == ESP_OK) { @@ -423,7 +422,7 @@ static esp_err_t esp_bt_hidd_dev_input_set(void *devp, size_t index, size_t id, ret = ESP_FAIL; break; } - } while(0); + } while (0); osi_mutex_unlock(&s_hidd_param.mutex); if (ret == ESP_OK) { @@ -469,7 +468,7 @@ static esp_err_t esp_bt_hidd_dev_feature_set(void *devp, size_t index, size_t id ret = ESP_FAIL; break; } - } while(0); + } while (0); osi_mutex_unlock(&s_hidd_param.mutex); if (ret == ESP_OK) { diff --git a/components/esp_hid/src/bt_hidh.c b/components/esp_hid/src/bt_hidh.c index 8193b38c07bb..59e641f573b8 100644 --- a/components/esp_hid/src/bt_hidh.c +++ b/components/esp_hid/src/bt_hidh.c @@ -55,7 +55,8 @@ static const char *s_esp_hh_status_names[] = {"OK", "NO_DATA", "NEED_INIT", "NEED_DEINIT", - "NO_CONNECTION"}; + "NO_CONNECTION" + }; static esp_hidh_dev_t *hidh_dev_ctor(esp_bd_addr_t bda); @@ -418,7 +419,7 @@ static void esp_hh_cb(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param) esp_hidh_dev_lock(dev); dev->added = param->add_dev.status == ESP_HIDH_OK ? true : false; esp_hidh_dev_unlock(dev); - } while(0); + } while (0); if (param->add_dev.status != ESP_HIDH_OK) { ESP_LOGE(TAG, "ADD_DEV ERROR: %s", s_esp_hh_status_names[param->add_dev.status]); @@ -460,7 +461,7 @@ static void esp_hh_cb(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param) // free the device in the wrapper event handler dev->in_use = false; esp_hidh_dev_unlock(dev); - } while(0); + } while (0); if (param->close.status != ESP_HIDH_OK) { ESP_LOGE(TAG, "CLOSE ERROR: %s", s_esp_hh_status_names[param->close.status]); @@ -535,7 +536,7 @@ static void esp_hh_cb(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param) reset_trans(dev); break; } - case ESP_HIDH_GET_IDLE_EVT:{ + case ESP_HIDH_GET_IDLE_EVT: { if (param->get_idle.status != ESP_HIDH_OK) { ESP_LOGE(TAG, "GET_IDLE ERROR: handle: %d, status: %s", param->get_idle.handle, s_esp_hh_status_names[param->get_idle.status]); @@ -684,7 +685,7 @@ static void esp_hh_cb(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param) } } else { report = esp_hidh_dev_get_input_report_by_proto_and_data( - dev, ESP_HID_PROTOCOL_MODE_REPORT, param->data_ind.len, param->data_ind.data, &has_report_id); + dev, ESP_HID_PROTOCOL_MODE_REPORT, param->data_ind.len, param->data_ind.data, &has_report_id); if (report == NULL) { esp_hidh_dev_unlock(dev); ESP_LOGE(TAG, "Not find report handle: %d mode: %s", param->data_ind.handle, @@ -903,7 +904,7 @@ static esp_err_t esp_bt_hidh_dev_get_idle(esp_hidh_dev_t *dev) if (ret == ESP_OK) { set_trans(dev, ESP_HID_TRANS_GET_IDLE); } - } while(0); + } while (0); return ret; } @@ -926,7 +927,7 @@ static esp_err_t esp_bt_hidh_dev_set_idle(esp_hidh_dev_t *dev, uint8_t idle_time if (ret == ESP_OK) { set_trans(dev, ESP_HID_TRANS_SET_IDLE); } - } while(0); + } while (0); return ret; } @@ -949,7 +950,7 @@ static esp_err_t esp_bt_hidh_dev_get_protocol(esp_hidh_dev_t *dev) if (ret == ESP_OK) { set_trans(dev, ESP_HID_TRANS_GET_PROTOCOL); } - } while(0); + } while (0); return ret; } @@ -973,7 +974,7 @@ static esp_err_t esp_bt_hidh_dev_set_protocol(esp_hidh_dev_t *dev, uint8_t proto if (ret == ESP_OK) { set_trans(dev, ESP_HID_TRANS_SET_PROTOCOL); } - } while(0); + } while (0); return ret; } @@ -987,8 +988,8 @@ static void esp_bt_hidh_dev_dump(esp_hidh_dev_t *dev, FILE *fp) esp_hidh_dev_report_t *report = dev->reports; while (report) { fprintf(fp, " %8s %7s %6s, ID: %3u, Length: %3u\n", - esp_hid_usage_str(report->usage), esp_hid_report_type_str(report->report_type), get_protocol_mode(report->protocol_mode), - report->report_id, report->value_len); + esp_hid_usage_str(report->usage), esp_hid_report_type_str(report->report_type), get_protocol_mode(report->protocol_mode), + report->report_id, report->value_len); report = report->next; } } diff --git a/components/esp_hid/src/esp_hid_common.c b/components/esp_hid/src/esp_hid_common.c index ed4afc89472c..364073ed9cb0 100644 --- a/components/esp_hid/src/esp_hid_common.c +++ b/components/esp_hid/src/esp_hid_common.c @@ -45,7 +45,6 @@ typedef enum { PARSE_WAIT_USAGE_PAGE, PARSE_WAIT_USAGE, PARSE_WAIT_COLLECTION_APPLICATION, PARSE_WAIT_END_COLLECTION } s_parse_step_t; - static s_parse_step_t s_parse_step = PARSE_WAIT_USAGE_PAGE; static uint8_t s_collection_depth = 0; static hid_report_params_t s_report_params = {0,}; @@ -192,7 +191,6 @@ static int handle_report(hid_report_params_t *report, bool first) return 0; } - static int parse_cmd(const uint8_t *data, size_t len, size_t index, hid_report_cmd_t **out) { if (index == len) { @@ -334,7 +332,6 @@ static int handle_cmd(hid_report_cmd_t *cmd) return 0; } - esp_hid_report_map_t *esp_hid_parse_report_map(const uint8_t *hid_rm, size_t hid_rm_len) { size_t index = 0; @@ -405,7 +402,7 @@ esp_hid_report_map_t *esp_hid_parse_report_map(const uint8_t *hid_rm, size_t hid void esp_hid_free_report_map(esp_hid_report_map_t *map) { - if (map != NULL){ + if (map != NULL) { free(map->reports); free(map); } @@ -444,7 +441,7 @@ const char *esp_hid_usage_str(esp_hid_usage_t usage) const char *esp_hid_protocol_mode_str(uint8_t protocol) { - if (protocol >= (sizeof(s_hid_protocol_names)/sizeof(s_hid_protocol_names[0]))) { + if (protocol >= (sizeof(s_hid_protocol_names) / sizeof(s_hid_protocol_names[0]))) { return s_unknown_str; } return s_hid_protocol_names[protocol]; @@ -452,7 +449,7 @@ const char *esp_hid_protocol_mode_str(uint8_t protocol) const char *esp_hid_report_type_str(uint8_t report_type) { - if (report_type >= (sizeof(s_hid_report_type_names)/sizeof(s_hid_report_type_names[0]))) { + if (report_type >= (sizeof(s_hid_report_type_names) / sizeof(s_hid_report_type_names[0]))) { return s_unknown_str; } return s_hid_report_type_names[report_type]; @@ -460,7 +457,7 @@ const char *esp_hid_report_type_str(uint8_t report_type) const char *esp_hid_cod_major_str(uint8_t cod_major) { - if (cod_major >= (sizeof(s_hid_cod_major_names)/sizeof(s_hid_cod_major_names[0]))) { + if (cod_major >= (sizeof(s_hid_cod_major_names) / sizeof(s_hid_cod_major_names[0]))) { return s_unknown_str; } return s_hid_cod_major_names[cod_major]; diff --git a/components/esp_hid/src/esp_hidh.c b/components/esp_hid/src/esp_hidh.c index 9f926746bf08..1bbbf89bd93b 100644 --- a/components/esp_hid/src/esp_hidh.c +++ b/components/esp_hid/src/esp_hidh.c @@ -37,7 +37,6 @@ static inline void unlock_devices(void) } } - /* * Public Functions * */ @@ -504,7 +503,6 @@ esp_err_t esp_hidh_dev_report_maps_get(esp_hidh_dev_t *dev, size_t *num_maps, es return ESP_OK; } - /* * Private Functions * */ @@ -557,7 +555,7 @@ esp_hidh_dev_report_t *esp_hidh_dev_get_report_by_id_type_proto(esp_hidh_dev_t * esp_hidh_dev_report_t *r = dev->reports; while (r) { if (r->map_index == map_index && r->report_type == report_type && r->report_id == report_id && - r->protocol_mode == protocol_mode) { + r->protocol_mode == protocol_mode) { return r; } r = r->next; @@ -614,7 +612,7 @@ esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_proto_and_data(esp_hidh_ // first, assume data not include report id while (r) { if (r->value_len == len && r->report_id == 0 && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) && - r->protocol_mode == protocol_mode) { + r->protocol_mode == protocol_mode) { *has_report_id = false; break; } @@ -630,7 +628,7 @@ esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_proto_and_data(esp_hidh_ r = dev->reports; while (r) { if (r->value_len == len - 1 && r->report_id == *data && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) && - r->protocol_mode == protocol_mode) { + r->protocol_mode == protocol_mode) { *has_report_id = true; break; } diff --git a/components/esp_hid/src/nimble_hidd.c b/components/esp_hid/src/nimble_hidd.c index f9c9cadf5cce..eec5fc4abffe 100644 --- a/components/esp_hid/src/nimble_hidd.c +++ b/components/esp_hid/src/nimble_hidd.c @@ -32,7 +32,6 @@ static const char *TAG = "NIMBLE_HIDD"; #define BLE_SVC_BAS_UUID16 0x180F - typedef struct esp_ble_hidd_dev_s esp_ble_hidd_dev_t; // there can be only one BLE HID device static esp_ble_hidd_dev_t *s_dev = NULL; @@ -48,8 +47,6 @@ typedef struct { uint16_t hid_protocol_handle; } hidd_dev_map_t; - - struct esp_ble_hidd_dev_s { esp_hidd_dev_t *dev; esp_event_loop_handle_t event_loop_handle; @@ -119,7 +116,7 @@ static int create_hid_db(int device_index) if (report->usage == ESP_HID_USAGE_KEYBOARD) { //Boot Keyboard Input hparams.kbd_inp_present = 1; } else { //Boot Mouse Input - hparams.mouse_inp_present = 1; + hparams.mouse_inp_present = 1; } } else { //Boot Keyboard Output hparams.kbd_out_present = 1; @@ -129,14 +126,14 @@ static int create_hid_db(int device_index) hparams.rpts_len = report_mode_rpts; /* Add service */ rc = ble_svc_hid_add(hparams); - if(rc != 0) { + if (rc != 0) { return rc; } return rc; } - -static int ble_hid_create_info_db() { +static int ble_hid_create_info_db() +{ int rc; rc = 0; @@ -144,8 +141,8 @@ static int ble_hid_create_info_db() { uint8_t pnp_val[7] = { 0x02, //0x1=BT, 0x2=USB s_dev->config.vendor_id & 0xFF, (s_dev->config.vendor_id >> 8) & 0xFF, //VID - s_dev->config.product_id & 0xFF, (s_dev->config.product_id >> 8) & 0xFF, //PID - s_dev->config.version & 0xFF, (s_dev->config.version >> 8) & 0xFF //VERSION + s_dev->config.product_id & 0xFF, (s_dev->config.product_id >> 8) & 0xFF, //PID + s_dev->config.version & 0xFF, (s_dev->config.version >> 8) & 0xFF //VERSION }; memcpy(s_dev->pnp, pnp_val, 7); ble_svc_dis_pnp_id_set((char *)s_dev->pnp); @@ -170,7 +167,7 @@ static int nimble_hid_start_gatts(void) for (uint8_t d = 0; d < s_dev->devices_len; d++) { rc = create_hid_db(d); - if(rc != 0) { + if (rc != 0) { return rc; } } @@ -273,7 +270,8 @@ static int ble_hid_free_config(esp_ble_hidd_dev_t *dev) return ESP_OK; } -static int nimble_hidd_dev_deinit(void *devp) { +static int nimble_hidd_dev_deinit(void *devp) +{ esp_ble_hidd_dev_t *dev = (esp_ble_hidd_dev_t *)devp; if (!s_dev) { ESP_LOGE(TAG, "HID device profile already uninitialized"); @@ -322,24 +320,26 @@ static int nimble_hidd_dev_battery_set(void *devp, uint8_t level) } /* if mode is NULL, find the first matching report */ -static hidd_le_report_item_t* find_report(uint8_t id, uint8_t type, uint8_t *mode) { +static hidd_le_report_item_t* find_report(uint8_t id, uint8_t type, uint8_t *mode) +{ hidd_le_report_item_t *rpt; for (uint8_t d = 0; d < s_dev->devices_len; d++) { for (uint8_t i = 0; i < s_dev->devices[d].reports_len; i++) { rpt = &s_dev->devices[d].reports[i]; - if(rpt->report_id == id && rpt->report_type == type && (!mode || (mode && *mode == rpt->protocol_mode))) { + if (rpt->report_id == id && rpt->report_type == type && (!mode || (mode && *mode == rpt->protocol_mode))) { return rpt; } } } return NULL; } -static hidd_le_report_item_t* find_report_by_usage_and_type(uint8_t usage, uint8_t type, uint8_t *mode) { +static hidd_le_report_item_t* find_report_by_usage_and_type(uint8_t usage, uint8_t type, uint8_t *mode) +{ hidd_le_report_item_t *rpt; for (uint8_t d = 0; d < s_dev->devices_len; d++) { for (uint8_t i = 0; i < s_dev->devices[d].reports_len; i++) { rpt = &s_dev->devices[d].reports[i]; - if(rpt->usage == usage && rpt->report_type == type && (!mode || (mode && *mode == rpt->protocol_mode))) { + if (rpt->usage == usage && rpt->report_type == type && (!mode || (mode && *mode == rpt->protocol_mode))) { return rpt; } } @@ -365,12 +365,12 @@ static int nimble_hidd_dev_input_set(void *devp, size_t index, size_t id, uint8_ /* check the protocol mode */ /* as the protocol mode is always present, its safe to read the characteristic */ rc = ble_att_svr_read_local(s_dev->devices[index].hid_protocol_handle, &om); - if(rc != 0) { + if (rc != 0) { ESP_LOGE(TAG, "Unable to fetch protocol_mode\n"); return ESP_FAIL; } rc = ble_hs_mbuf_to_flat(om, &dev->protocol, sizeof(dev->protocol), NULL); - if(rc != 0) { + if (rc != 0) { return ESP_FAIL; } /* free the mbuf */ @@ -409,12 +409,12 @@ static int nimble_hidd_dev_feature_set(void *devp, size_t index, size_t id, uint /* check the protocol mode */ /* as the protocol mode is always present, its safe to read the characteristic */ rc = ble_att_svr_read_local(s_dev->devices[index].hid_protocol_handle, &om); - if(rc != 0) { + if (rc != 0) { ESP_LOGE(TAG, "Unable to fetch protocol_mode\n"); return ESP_FAIL; } rc = ble_hs_mbuf_to_flat(om, &dev->protocol, sizeof(dev->protocol), NULL); - if(rc != 0) { + if (rc != 0) { return ESP_FAIL; } /* free the mbuf */ @@ -488,11 +488,11 @@ static int nimble_hid_gap_event(struct ble_gap_event *event, void *arg) /* reset the protocol mode value */ data = ESP_HID_PROTOCOL_MODE_REPORT; om = ble_hs_mbuf_from_flat(&data, 1); - if(om == NULL) { + if (om == NULL) { ESP_LOGD(TAG, "No memory to allocate mbuf"); } /* NOTE : om is freed by stack */ - for(int i = 0; i < s_dev->devices_len; i++) { + for (int i = 0; i < s_dev->devices_len; i++) { rc = ble_att_svr_write_local(s_dev->devices[i].hid_protocol_handle, om); if (rc != 0) { ESP_LOGE(TAG, "Write on Protocol Mode Failed: %d", rc); @@ -541,7 +541,7 @@ static void nimble_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, voi ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), ctxt->svc.handle); uuid16 = ble_uuid_u16(ctxt->svc.svc_def->uuid); - if(uuid16 == BLE_SVC_HID_UUID16) { + if (uuid16 == BLE_SVC_HID_UUID16) { ++service_index; s_dev->devices[service_index].hid_svc = ctxt->svc.handle; } @@ -555,36 +555,36 @@ static void nimble_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, voi ctxt->chr.def_handle, ctxt->chr.val_handle); uuid16 = ble_uuid_u16(ctxt->chr.chr_def->uuid); - if(uuid16 == BLE_SVC_HID_CHR_UUID16_HID_CTRL_PT) { + if (uuid16 == BLE_SVC_HID_CHR_UUID16_HID_CTRL_PT) { /* assuming this characteristic is from the last registered hid service */ s_dev->devices[service_index].hid_control_handle = ctxt->chr.val_handle; } - if(uuid16 == BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE) { + if (uuid16 == BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE) { /* assuming this characteristic is from the last registered hid service */ s_dev->devices[service_index].hid_protocol_handle = ctxt->chr.val_handle; } - if(uuid16 == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_INP) { + if (uuid16 == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_INP) { protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; rpt = find_report_by_usage_and_type(ESP_HID_USAGE_KEYBOARD, ESP_HID_REPORT_TYPE_INPUT, &protocol_mode); - if(rpt == NULL) { + if (rpt == NULL) { ESP_LOGE(TAG, "Unknown boot kbd input report registration"); return; } rpt->handle = ctxt->chr.val_handle; } - if(uuid16 == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_OUT) { + if (uuid16 == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_OUT) { protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; rpt = find_report_by_usage_and_type(ESP_HID_USAGE_KEYBOARD, ESP_HID_REPORT_TYPE_OUTPUT, &protocol_mode); - if(rpt == NULL) { + if (rpt == NULL) { ESP_LOGE(TAG, "Unknown boot kbd output report registration"); return; } rpt->handle = ctxt->chr.val_handle; } - if(uuid16 == BLE_SVC_HID_CHR_UUID16_BOOT_MOUSE_INP) { + if (uuid16 == BLE_SVC_HID_CHR_UUID16_BOOT_MOUSE_INP) { protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; rpt = find_report_by_usage_and_type(ESP_HID_USAGE_MOUSE, ESP_HID_REPORT_TYPE_INPUT, &protocol_mode); - if(rpt == NULL) { + if (rpt == NULL) { ESP_LOGE(TAG, "Unknown boot mouse input report registration"); return; } @@ -597,7 +597,7 @@ static void nimble_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, voi ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), ctxt->dsc.handle); uuid16 = ble_uuid_u16(ctxt->dsc.dsc_def->uuid); - if(uuid16 == BLE_SVC_HID_DSC_UUID16_RPT_REF) { + if (uuid16 == BLE_SVC_HID_DSC_UUID16_RPT_REF) { rc = ble_att_svr_read_local(ctxt->dsc.handle, &om); assert(rc == 0); @@ -621,7 +621,8 @@ static void nimble_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, voi } } -static void nimble_host_synced(void) { +static void nimble_host_synced(void) +{ esp_event_post_to(s_dev->event_loop_handle, ESP_HIDD_EVENTS, ESP_HIDD_START_EVENT, NULL, 0, portMAX_DELAY); } @@ -699,11 +700,11 @@ esp_err_t esp_ble_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_conf ble_hs_cfg.sync_cb = nimble_host_synced; ble_hs_cfg.gatts_register_cb = nimble_gatt_svr_register_cb; rc = nimble_hid_start_gatts(); - if(rc != ESP_OK) { + if (rc != ESP_OK) { return rc; } ble_gap_event_listener_register(&nimble_gap_event_listener, - nimble_hid_gap_event, NULL); + nimble_hid_gap_event, NULL); return rc; } diff --git a/components/esp_hid/src/nimble_hidh.c b/components/esp_hid/src/nimble_hidh.c index 55a21255598e..d86398119ad9 100644 --- a/components/esp_hid/src/nimble_hidh.c +++ b/components/esp_hid/src/nimble_hidh.c @@ -93,28 +93,28 @@ print_mbuf(const struct os_mbuf *om) static int nimble_on_read(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { int old_offset; MODLOG_DFLT(INFO, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); s_read_status = error->status; - switch(s_read_status) { - case 0: - MODLOG_DFLT(DEBUG, " attr_handle=%d value=", attr->handle); - old_offset = s_read_data_len; - s_read_data_len += OS_MBUF_PKTLEN(attr->om); - s_read_data_val = realloc(s_read_data_val, s_read_data_len + 1); // 1 extra byte to store null char - ble_hs_mbuf_to_flat(attr->om, s_read_data_val + old_offset, OS_MBUF_PKTLEN(attr->om), NULL); - print_mbuf(attr->om); - return 0; - case BLE_HS_EDONE: - s_read_data_val[s_read_data_len] = 0; // to insure strings are ended with \0 */ - s_read_status = 0; - SEND_CB(); - return 0; + switch (s_read_status) { + case 0: + MODLOG_DFLT(DEBUG, " attr_handle=%d value=", attr->handle); + old_offset = s_read_data_len; + s_read_data_len += OS_MBUF_PKTLEN(attr->om); + s_read_data_val = realloc(s_read_data_val, s_read_data_len + 1); // 1 extra byte to store null char + ble_hs_mbuf_to_flat(attr->om, s_read_data_val + old_offset, OS_MBUF_PKTLEN(attr->om), NULL); + print_mbuf(attr->om); + return 0; + case BLE_HS_EDONE: + s_read_data_val[s_read_data_len] = 0; // to insure strings are ended with \0 */ + s_read_status = 0; + SEND_CB(); + return 0; } return 0; } @@ -161,7 +161,7 @@ static int read_descr(uint16_t conn_handle, uint16_t handle, uint8_t **out, uint static int svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_svc *service, void *arg) + const struct ble_gatt_svc *service, void *arg) { int rc; struct ble_gatt_svc *service_result; @@ -211,7 +211,7 @@ svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, static int chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - const struct ble_gatt_chr *chr, void *arg) + const struct ble_gatt_chr *chr, void *arg) { struct ble_gatt_chr *chrs; int rc; @@ -221,8 +221,8 @@ chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, status = error->status; switch (error->status) { case 0: - ESP_LOGD(TAG,"Char discovered : def handle : %04x, val_handle : %04x, properties : %02x\n, uuid : %04x", - chr->def_handle, chr->val_handle,chr->properties, ble_uuid_u16(&chr->uuid.u)); + ESP_LOGD(TAG, "Char discovered : def handle : %04x, val_handle : %04x, properties : %02x\n, uuid : %04x", + chr->def_handle, chr->val_handle, chr->properties, ble_uuid_u16(&chr->uuid.u)); memcpy(chrs + chrs_discovered, chr, sizeof(struct ble_gatt_chr)); chrs_discovered++; break; @@ -249,8 +249,8 @@ chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error, static int desc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, - uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, - void *arg) + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, + void *arg) { int rc; struct ble_gatt_dsc *dscr; @@ -260,8 +260,8 @@ desc_disced(uint16_t conn_handle, const struct ble_gatt_error *error, status = error->status; switch (error->status) { case 0: - ESP_LOGD(TAG,"DISC discovered : handle : %04x, uuid : %04x", - dsc->handle, ble_uuid_u16(&dsc->uuid.u)); + ESP_LOGD(TAG, "DISC discovered : handle : %04x, uuid : %04x", + dsc->handle, ble_uuid_u16(&dsc->uuid.u)); memcpy(dscr + dscs_discovered, dsc, sizeof(struct ble_gatt_dsc)); dscs_discovered++; break; @@ -307,12 +307,12 @@ static void read_device_services(esp_hidh_dev_t *dev) int rc; rc = ble_gattc_disc_all_svcs(dev->ble.conn_id, svc_disced, service_result); - if(rc != 0) { + if (rc != 0) { ESP_LOGD(TAG, "Error discovering services : %d", rc); assert(rc != 0); } WAIT_CB(); - if(status != 0) { + if (status != 0) { ESP_LOGE(TAG, "failed to find services"); assert(status == 0); } @@ -351,8 +351,8 @@ static void read_device_services(esp_hidh_dev_t *dev) rc = ble_gattc_disc_all_chrs(dev->ble.conn_id, service_result[s].start_handle, service_result[s].end_handle, chr_disced, char_result); WAIT_CB(); - if(status != 0) { - ESP_LOGE(TAG, "failed to find chars for service : %d",s); + if (status != 0) { + ESP_LOGE(TAG, "failed to find chars for service : %d", s); assert(status == 0); } ccount = chrs_discovered; @@ -365,8 +365,8 @@ static void read_device_services(esp_hidh_dev_t *dev) if (suuid == BLE_SVC_GAP_UUID16) { if (dev->config.device_name == NULL && cuuid == BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME - && (char_result[c].properties & BLE_GATT_CHR_PROP_READ) != 0) { - if (read_char(dev->ble.conn_id, chandle,&rdata, &rlen) == 0 && rlen) { + && (char_result[c].properties & BLE_GATT_CHR_PROP_READ) != 0) { + if (read_char(dev->ble.conn_id, chandle, &rdata, &rlen) == 0 && rlen) { dev->config.device_name = (const char *)rdata; } } else { @@ -374,7 +374,7 @@ static void read_device_services(esp_hidh_dev_t *dev) } } else if (suuid == BLE_SVC_BAS_UUID16) { if (cuuid == BLE_SVC_BAS_CHR_UUID16_BATTERY_LEVEL && - (char_result[c].properties & BLE_GATT_CHR_PROP_READ) != 0) { + (char_result[c].properties & BLE_GATT_CHR_PROP_READ) != 0) { dev->ble.battery_handle = chandle; } else { continue; @@ -400,7 +400,7 @@ static void read_device_services(esp_hidh_dev_t *dev) } continue; } else { - if(cuuid == BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE) { + if (cuuid == BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE) { if (char_result[c].properties & BLE_GATT_CHR_PROP_READ) { if (read_char(dev->ble.conn_id, chandle, &rdata, &rlen) == 0 && rlen) { dev->protocol_mode[hidindex] = *((uint8_t *)rdata); @@ -457,17 +457,16 @@ static void read_device_services(esp_hidh_dev_t *dev) struct ble_gatt_dsc descr_result[20]; uint16_t dcount = 20; uint16_t chr_end_handle; - if(c + 1 < ccount) { + if (c + 1 < ccount) { chr_end_handle = char_result[c + 1].def_handle; - } - else { + } else { chr_end_handle = service_result[s].end_handle; } rc = ble_gattc_disc_all_dscs(dev->ble.conn_id, char_result[c].val_handle, chr_end_handle, desc_disced, descr_result); WAIT_CB(); - if(status != 0) { - ESP_LOGE(TAG, "failed to find discriptors for characteristic : %d",c); + if (status != 0) { + ESP_LOGE(TAG, "failed to find discriptors for characteristic : %d", c); assert(status == 0); } dcount = dscs_discovered; @@ -479,7 +478,7 @@ static void read_device_services(esp_hidh_dev_t *dev) if (suuid == BLE_SVC_BAS_UUID16) { if (duuid == BLE_GATT_DSC_CLT_CFG_UUID16 && - (char_result[c].properties & BLE_GATT_CHR_PROP_NOTIFY) != 0) { + (char_result[c].properties & BLE_GATT_CHR_PROP_NOTIFY) != 0) { dev->ble.battery_ccc_handle = dhandle; } } else if (suuid == BLE_SVC_HID_UUID16 && report != NULL) { @@ -549,12 +548,12 @@ static void read_device_services(esp_hidh_dev_t *dev) static int on_subscribe(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { uint16_t conn_id; - conn_id =*((uint16_t*) arg); + conn_id = *((uint16_t*) arg); assert(conn_id == conn_handle); @@ -572,22 +571,22 @@ static void register_for_notify(uint16_t conn_handle, uint16_t handle) int rc; value[0] = 1; value[1] = 0; - rc = ble_gattc_write_flat(conn_handle, handle, value, sizeof value, on_subscribe,(void *)&conn_handle); + rc = ble_gattc_write_flat(conn_handle, handle, value, sizeof value, on_subscribe, (void *)&conn_handle); if (rc != 0) { ESP_LOGE(TAG, "Error: Failed to subscribe to characteristic; " - "rc=%d\n", rc); + "rc=%d\n", rc); } WAIT_CB(); } static int on_write(uint16_t conn_handle, - const struct ble_gatt_error *error, - struct ble_gatt_attr *attr, - void *arg) + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) { uint16_t conn_id; - conn_id =*((uint16_t*) arg); + conn_id = *((uint16_t*) arg); assert(conn_id == conn_handle); @@ -652,7 +651,7 @@ esp_hidh_gattc_event_handler(struct ble_gap_event *event, void *arg) rc = ble_gap_conn_find(event->connect.conn_handle, &desc); assert(rc == 0); dev = esp_hidh_dev_get_by_bda(desc.peer_ota_addr.val); - if(!dev) { + if (!dev) { ESP_LOGE(TAG, "Connect received for unknown device"); } dev->status = -1; // set to not found and clear if HID service is found @@ -660,7 +659,7 @@ esp_hidh_gattc_event_handler(struct ble_gap_event *event, void *arg) /* Try to set the mtu to the max value */ rc = ble_att_set_preferred_mtu(BLE_ATT_MTU_MAX); - if(rc != 0) { + if (rc != 0) { ESP_LOGE(TAG, "att preferred mtu set failed"); } rc = ble_gattc_exchange_mtu(event->connect.conn_handle, NULL, NULL); @@ -671,9 +670,9 @@ esp_hidh_gattc_event_handler(struct ble_gap_event *event, void *arg) } else { MODLOG_DFLT(ERROR, "Error: Connection failed; status=%d\n", event->connect.status); - dev->status = event->connect.status; // ESP_GATT_CONN_FAIL_ESTABLISH; - dev->ble.conn_id = -1; - SEND_CB(); // return from connection + dev->status = event->connect.status; // ESP_GATT_CONN_FAIL_ESTABLISH; + dev->ble.conn_id = -1; + SEND_CB(); // return from connection } return 0; @@ -738,7 +737,7 @@ esp_hidh_gattc_event_handler(struct ble_gap_event *event, void *arg) esp_hidh_event_data_t *p_param = NULL; size_t event_data_size = sizeof(esp_hidh_event_data_t); - if(report->protocol_mode != dev->protocol_mode[report->map_index]) { + if (report->protocol_mode != dev->protocol_mode[report->map_index]) { /* only pass the notifications in the current protocol mode */ ESP_LOGD(TAG, "Wrong protocol mode, dropping notification"); return 0; @@ -861,9 +860,9 @@ static void esp_ble_hidh_dev_dump(esp_hidh_dev_t *dev, FILE *fp) while (report) { if (report->map_index == d) { fprintf(fp, " %8s %7s %6s, ID: %2u, Length: %3u, Permissions: 0x%02x, Handle: %3u, CCC Handle: %3u\n", - esp_hid_usage_str(report->usage), esp_hid_report_type_str(report->report_type), - esp_hid_protocol_mode_str(report->protocol_mode), report->report_id, report->value_len, - report->permissions, report->handle, report->ccc_handle); + esp_hid_usage_str(report->usage), esp_hid_report_type_str(report->report_type), + esp_hid_protocol_mode_str(report->protocol_mode), report->report_id, report->value_len, + report->permissions, report->handle, report->ccc_handle); } report = report->next; } @@ -883,10 +882,11 @@ static void esp_ble_hidh_event_handler_wrapper(void *event_handler_arg, esp_even esp_hidh_post_process_event_handler(event_handler_arg, event_base, event_id, event_data); } -static void nimble_host_synced(void) { -/* - no need to perform anything here -*/ +static void nimble_host_synced(void) +{ + /* + no need to perform anything here + */ } static void nimble_host_reset(int reason) diff --git a/tools/ci/astyle-rules.yml b/tools/ci/astyle-rules.yml index ebc9be71341e..bf49a32925b5 100644 --- a/tools/ci/astyle-rules.yml +++ b/tools/ci/astyle-rules.yml @@ -55,7 +55,6 @@ components_not_formatted_temporary: - "/components/esp_coex/" - "/components/esp_eth/" - "/components/esp_gdbstub/" - - "/components/esp_hid/" - "/components/esp_http_client/" - "/components/esp_http_server/" - "/components/esp_https_ota/" From 455dd4e78640492795e81243046b05ff1028b1e5 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Wed, 28 Feb 2024 10:13:24 +0800 Subject: [PATCH 07/33] docs(wdt): fixed spelling mistakes in wdt doc --- docs/en/api-reference/system/wdts.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/api-reference/system/wdts.rst b/docs/en/api-reference/system/wdts.rst index 68225032caaf..051a20b2416b 100644 --- a/docs/en/api-reference/system/wdts.rst +++ b/docs/en/api-reference/system/wdts.rst @@ -86,7 +86,7 @@ Neither critical sections or interrupt handlers should ever block waiting for an Task Watchdog Timer (TWDT) -------------------------- -The Task Watchdog Timer (TWDT) is used to monitor particular tasks, ensuring that they are able to execute within a given timeout period. The TWDT primarily watches the Idle Tasks of each CPU, however any task can subscribe to be watched by the TWDT. By watching the Idle Tasks of each CPU, the TWDT can detect instances of tasks running for a prolonged period of time wihtout yielding. This can be an indicator of poorly written code that spinloops on a peripheral, or a task that is stuck in an infinite loop. +The Task Watchdog Timer (TWDT) is used to monitor particular tasks, ensuring that they are able to execute within a given timeout period. The TWDT primarily watches the Idle Tasks of each CPU, however any task can subscribe to be watched by the TWDT. By watching the Idle Tasks of each CPU, the TWDT can detect instances of tasks running for a prolonged period of time without yielding. This can be an indicator of poorly written code that spinloops on a peripheral, or a task that is stuck in an infinite loop. .. only:: not esp32c2 From 30d5c36aaca1316ab71cb7535d41c739e1cdc542 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 28 Feb 2024 12:56:57 +0530 Subject: [PATCH 08/33] fix(nimble): Increase range of reattempt connection count --- components/bt/host/nimble/Kconfig.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index eec575c31f74..1163d4d7974c 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -523,7 +523,7 @@ config BT_NIMBLE_ENABLE_CONN_REATTEMPT config BT_NIMBLE_MAX_CONN_REATTEMPT int "Maximum number connection reattempts" - range 1 7 + range 1 255 default 3 depends on BT_NIMBLE_ENABLED && BT_NIMBLE_ENABLE_CONN_REATTEMPT help From 35e312c48ec44328f81d47520327a61f0cb51e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Wed, 7 Feb 2024 19:43:50 +0100 Subject: [PATCH 09/33] feat(fatfs): Allow expanding files with seeking and truncating functions Closes https://github.com/espressif/esp-idf/issues/13100 --- .../flash_wl/main/test_fatfs_flash_wl.c | 9 +- .../test_apps/sdcard/main/test_fatfs_sdmmc.c | 4 +- .../test_fatfs_common/test_fatfs_common.c | 153 +++++++++++---- .../test_fatfs_common/test_fatfs_common.h | 4 +- components/fatfs/vfs/vfs_fat.c | 181 ++++++++++++++---- components/vfs/include/esp_vfs.h | 8 +- 6 files changed, 277 insertions(+), 82 deletions(-) diff --git a/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c b/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c index 155769ceb0c6..66c9f6930dc2 100644 --- a/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c +++ b/components/fatfs/test_apps/flash_wl/main/test_fatfs_flash_wl.c @@ -190,7 +190,14 @@ TEST_CASE("(WL) can lseek", "[fatfs][wear_levelling]") TEST_CASE("(WL) can truncate", "[fatfs][wear_levelling]") { test_setup(); - test_fatfs_truncate_file("/spiflash/truncate.txt"); + test_fatfs_truncate_file("/spiflash/truncate.txt", true); + test_teardown(); +} + +TEST_CASE("(WL) can ftruncate", "[fatfs][wear_levelling]") +{ + test_setup(); + test_fatfs_ftruncate_file("/spiflash/ftrunc.txt", true); test_teardown(); } diff --git a/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c index 6d66dcd6de3d..3f709f0a3806 100644 --- a/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c +++ b/components/fatfs/test_apps/sdcard/main/test_fatfs_sdmmc.c @@ -186,7 +186,7 @@ TEST_CASE("(SD) can truncate", "[fatfs][sdmmc]") { sdmmc_card_t *card = NULL; test_setup_sdmmc(&card); - test_fatfs_truncate_file("/sdcard/truncate.txt"); + test_fatfs_truncate_file("/sdcard/truncate.txt", true); test_teardown_sdmmc(card); } @@ -194,7 +194,7 @@ TEST_CASE("(SD) can ftruncate", "[fatfs][sdmmc]") { sdmmc_card_t *card = NULL; test_setup_sdmmc(&card); - test_fatfs_ftruncate_file("/sdcard/ftrunc.txt"); + test_fatfs_ftruncate_file("/sdcard/ftrunc.txt", true); test_teardown_sdmmc(card); } diff --git a/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c index aa7be418c09d..56b2609d6cb5 100644 --- a/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c +++ b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "test_fatfs_common.h" +#include "ff.h" const char* fatfs_test_hello_str = "Hello, World!\n"; const char* fatfs_test_hello_str_utf = "世界,你好!\n"; @@ -252,7 +253,7 @@ void test_fatfs_lseek(const char* filename) } -void test_fatfs_truncate_file(const char* filename) +void test_fatfs_truncate_file(const char* filename, bool allow_expanding_files) { int read = 0; int truncated_len = 0; @@ -267,14 +268,44 @@ void test_fatfs_truncate_file(const char* filename) TEST_ASSERT_EQUAL(0, fclose(f)); + struct stat st; + size_t size; - // Extending file beyond size is not supported - TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input) + 1)); - TEST_ASSERT_EQUAL(errno, EPERM); + stat(filename, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(strlen(input), size); - TEST_ASSERT_EQUAL(-1, truncate(filename, -1)); - TEST_ASSERT_EQUAL(errno, EINVAL); + if (allow_expanding_files) { + size_t trunc_add = 2; + size_t new_size = strlen(input) + trunc_add; + TEST_ASSERT_EQUAL(0, truncate(filename, new_size)); + + stat(filename, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(new_size, size); + + f = fopen(filename, "rb"); + TEST_ASSERT_NOT_NULL(f); + + char expanded_output[sizeof(input) + trunc_add]; + memset(expanded_output, 42, sizeof(expanded_output)); // set to something else than 0 (42) + + read = fread(expanded_output, 1, sizeof(input) + trunc_add, f); + TEST_ASSERT_EQUAL(new_size, read); + TEST_ASSERT_EQUAL('Z', expanded_output[strlen(input) - 1]); // 'Z' character + TEST_ASSERT_EQUAL('\0', expanded_output[sizeof(input) + trunc_add - 3]); // zeroed expanded space + TEST_ASSERT_EQUAL('\0', expanded_output[sizeof(input) + trunc_add - 2]); // zeroed expanded space + TEST_ASSERT_EQUAL(42, expanded_output[sizeof(input) + trunc_add - 1]); // 42 set with memset, end of the array + + TEST_ASSERT_EQUAL(0, fclose(f)); + } else { + TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input) + 1)); + TEST_ASSERT_EQUAL(errno, EPERM); + + TEST_ASSERT_EQUAL(-1, truncate(filename, -1)); + TEST_ASSERT_EQUAL(errno, EINVAL); + } // Truncating should succeed const char truncated_1[] = "ABCDEFGHIJ"; @@ -282,6 +313,10 @@ void test_fatfs_truncate_file(const char* filename) TEST_ASSERT_EQUAL(0, truncate(filename, truncated_len)); + stat(filename, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(strlen(truncated_1), size); + f = fopen(filename, "rb"); TEST_ASSERT_NOT_NULL(f); @@ -293,28 +328,34 @@ void test_fatfs_truncate_file(const char* filename) TEST_ASSERT_EQUAL(0, fclose(f)); + if (allow_expanding_files) { + TEST_ASSERT_EQUAL(0, truncate(filename, truncated_len + 1)); + } else { + // Once truncated, the new file size should be the basis + // whether truncation should succeed or not when `allow_expanding_files == false` + TEST_ASSERT_EQUAL(-1, truncate(filename, truncated_len + 1)); + TEST_ASSERT_EQUAL(EPERM, errno); - // Once truncated, the new file size should be the basis - // whether truncation should succeed or not - TEST_ASSERT_EQUAL(-1, truncate(filename, truncated_len + 1)); - TEST_ASSERT_EQUAL(EPERM, errno); - - TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input))); - TEST_ASSERT_EQUAL(EPERM, errno); + TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input))); + TEST_ASSERT_EQUAL(EPERM, errno); - TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input) + 1)); - TEST_ASSERT_EQUAL(EPERM, errno); + TEST_ASSERT_EQUAL(-1, truncate(filename, strlen(input) + 1)); + TEST_ASSERT_EQUAL(EPERM, errno); + } TEST_ASSERT_EQUAL(-1, truncate(filename, -1)); TEST_ASSERT_EQUAL(EINVAL, errno); - // Truncating a truncated file should succeed const char truncated_2[] = "ABCDE"; truncated_len = strlen(truncated_2); TEST_ASSERT_EQUAL(0, truncate(filename, truncated_len)); + stat(filename, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(strlen(truncated_2), size); + f = fopen(filename, "rb"); TEST_ASSERT_NOT_NULL(f); @@ -327,29 +368,63 @@ void test_fatfs_truncate_file(const char* filename) TEST_ASSERT_EQUAL(0, fclose(f)); } -void test_fatfs_ftruncate_file(const char* filename) +void test_fatfs_ftruncate_file(const char* filename, bool allow_expanding_files) { int truncated_len = 0; const char input[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char output[sizeof(input)]; - int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC); + int fd = open(filename, O_RDWR | O_CREAT | O_TRUNC); TEST_ASSERT_NOT_EQUAL(-1, fd); TEST_ASSERT_EQUAL(strlen(input), write(fd, input, strlen(input))); - // Extending file beyond size is not supported - TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input) + 1)); - TEST_ASSERT_EQUAL(errno, EPERM); + struct stat st; + size_t size; - TEST_ASSERT_EQUAL(-1, ftruncate(fd, -1)); - TEST_ASSERT_EQUAL(errno, EINVAL); + fstat(fd, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(strlen(input), size); + + if (allow_expanding_files) { + size_t trunc_add = 2; + size_t new_size = strlen(input) + trunc_add; + TEST_ASSERT_EQUAL(0, ftruncate(fd, new_size)); + + fstat(fd, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(new_size, size); + + char expanded_output[sizeof(input) + trunc_add]; + memset(expanded_output, 42, sizeof(expanded_output)); // set to something else than 0 (42) + + lseek(fd, 0, SEEK_SET); + int r = read(fd, expanded_output, sizeof(input) + trunc_add); + TEST_ASSERT_NOT_EQUAL(-1, r); + TEST_ASSERT_EQUAL(new_size, r); + + TEST_ASSERT_EQUAL('Z', expanded_output[strlen(input) - 1]); // 'Z' character + TEST_ASSERT_EQUAL('\0', expanded_output[sizeof(input) + trunc_add - 3]); // zeroed expanded space + TEST_ASSERT_EQUAL('\0', expanded_output[sizeof(input) + trunc_add - 2]); // zeroed expanded space + TEST_ASSERT_EQUAL(42, expanded_output[sizeof(input) + trunc_add - 1]); // 42 set with memset, end of the array + } else { + TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input) + 1)); + TEST_ASSERT_EQUAL(errno, EPERM); + + TEST_ASSERT_EQUAL(-1, ftruncate(fd, -1)); + TEST_ASSERT_EQUAL(errno, EINVAL); + } // Truncating should succeed const char truncated_1[] = "ABCDEFGHIJ"; truncated_len = strlen(truncated_1); TEST_ASSERT_EQUAL(0, ftruncate(fd, truncated_len)); + + fstat(fd, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(truncated_len, size); + TEST_ASSERT_EQUAL(0, close(fd)); // open file for reading and validate the content @@ -367,25 +442,35 @@ void test_fatfs_ftruncate_file(const char* filename) // further truncate the file fd = open(filename, O_WRONLY); TEST_ASSERT_NOT_EQUAL(-1, fd); - // Once truncated, the new file size should be the basis - // whether truncation should succeed or not - TEST_ASSERT_EQUAL(-1, ftruncate(fd, truncated_len + 1)); - TEST_ASSERT_EQUAL(EPERM, errno); - TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input))); - TEST_ASSERT_EQUAL(EPERM, errno); + if (allow_expanding_files) { + TEST_ASSERT_EQUAL(0, ftruncate(fd, truncated_len + 1)); + } else { + // Once truncated, the new file size should be the basis + // whether truncation should succeed or not when `allow_expanding_files == false` + TEST_ASSERT_EQUAL(-1, ftruncate(fd, truncated_len + 1)); + TEST_ASSERT_EQUAL(EPERM, errno); - TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input) + 1)); - TEST_ASSERT_EQUAL(EPERM, errno); + TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input))); + TEST_ASSERT_EQUAL(EPERM, errno); - TEST_ASSERT_EQUAL(-1, ftruncate(fd, -1)); - TEST_ASSERT_EQUAL(EINVAL, errno); + TEST_ASSERT_EQUAL(-1, ftruncate(fd, strlen(input) + 1)); + TEST_ASSERT_EQUAL(EPERM, errno); + + TEST_ASSERT_EQUAL(-1, ftruncate(fd, -1)); + TEST_ASSERT_EQUAL(EINVAL, errno); + } // Truncating a truncated file should succeed const char truncated_2[] = "ABCDE"; truncated_len = strlen(truncated_2); TEST_ASSERT_EQUAL(0, ftruncate(fd, truncated_len)); + + fstat(fd, &st); + size = st.st_size; + TEST_ASSERT_EQUAL(truncated_len, size); + TEST_ASSERT_EQUAL(0, close(fd)); // open file for reading and validate the content diff --git a/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h index e7366fe1e110..4ae67937dd19 100644 --- a/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h +++ b/components/fatfs/test_apps/test_fatfs_common/test_fatfs_common.h @@ -45,9 +45,9 @@ void test_fatfs_open_max_files(const char* filename_prefix, size_t files_count); void test_fatfs_lseek(const char* filename); -void test_fatfs_truncate_file(const char* path); +void test_fatfs_truncate_file(const char* path, bool allow_expanding_files); -void test_fatfs_ftruncate_file(const char* path); +void test_fatfs_ftruncate_file(const char* path, bool allow_expanding_files); void test_fatfs_stat(const char* filename, const char* root_dir); diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index 55cfbd1f0e50..7c717c76c85c 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -16,6 +17,8 @@ #include "ff.h" #include "diskio_impl.h" +#define F_WRITE_MALLOC_ZEROING_BUF_SIZE_LIMIT 512 + typedef struct { char fat_drive[8]; /* FAT drive name */ char base_path[ESP_VFS_PATH_MAX]; /* base path in VFS where partition is registered */ @@ -981,6 +984,49 @@ static int vfs_fat_access(void* ctx, const char *path, int amode) return ret; } +static FRESULT f_write_zero_mem(FIL* fp, FSIZE_t data_size, FSIZE_t buf_size, UINT* bytes_written) +{ + if (fp == NULL || data_size <= 0 || buf_size <= 0) { + return FR_INVALID_PARAMETER; + } + + void* buf = ff_memalloc(buf_size); + if (buf == NULL) { + return FR_DISK_ERR; + } + memset(buf, 0, buf_size); + + FRESULT res = FR_OK; + UINT bw = 0; + FSIZE_t i = 0; + if (bytes_written != NULL) { + *bytes_written = 0; + } + + if (data_size > buf_size) { // prevent unsigned underflow + for (; i < (data_size - buf_size); i += buf_size) { // write chunks of buf_size + res = f_write(fp, buf, (UINT) buf_size, &bw); + if (res != FR_OK) { + goto out; + } + if (bytes_written != NULL) { + *bytes_written += bw; + } + } + } + + if (i < data_size) { // write the remaining data + res = f_write(fp, buf, (UINT) (data_size - i), &bw); + if (res == FR_OK && bytes_written != NULL) { + *bytes_written += bw; + } + } + +out: + ff_memfree(buf); + return res; +} + static int vfs_fat_truncate(void* ctx, const char *path, off_t length) { FRESULT res; @@ -1019,32 +1065,55 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length) goto out; } - long sz = f_size(file); - if (sz < length) { - _lock_release(&fat_ctx->lock); - ESP_LOGD(TAG, "truncate does not support extending size"); - errno = EPERM; - ret = -1; - goto close; - } + FSIZE_t seek_ptr_pos = (FSIZE_t) f_tell(file); // current seek pointer position + FSIZE_t sz = (FSIZE_t) f_size(file); // current file size (end of file position) res = f_lseek(file, length); - if (res != FR_OK) { - _lock_release(&fat_ctx->lock); - ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); - errno = fresult_to_errno(res); - ret = -1; - goto close; + if (res != FR_OK || f_tell(file) != length) { + goto lseek_or_write_fail; } - res = f_truncate(file); + if (sz < length) { + res = f_lseek(file, sz); // go to the previous end of file + if (res != FR_OK) { + goto lseek_or_write_fail; + } - if (res != FR_OK) { - _lock_release(&fat_ctx->lock); - ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); - errno = fresult_to_errno(res); - ret = -1; - goto close; + FSIZE_t new_free_space = ((FSIZE_t) length) - sz; + UINT written; + + if (new_free_space > UINT32_MAX) { + _lock_release(&fat_ctx->lock); + ESP_LOGE(TAG, "%s: Cannot extend the file more than 4GB at once", __func__); + ret = -1; + goto close; + } + + FSIZE_t buf_size_limit = F_WRITE_MALLOC_ZEROING_BUF_SIZE_LIMIT; + FSIZE_t buf_size = new_free_space < buf_size_limit ? new_free_space : buf_size_limit; + res = f_write_zero_mem(file, new_free_space, buf_size, &written); + + if (res != FR_OK) { + goto lseek_or_write_fail; + } else if (written != (UINT) new_free_space) { + res = FR_DISK_ERR; + goto lseek_or_write_fail; + } + + res = f_lseek(file, seek_ptr_pos); // return to the original position + if (res != FR_OK) { + goto lseek_or_write_fail; + } + } else { + res = f_truncate(file); + + if (res != FR_OK) { + _lock_release(&fat_ctx->lock); + ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); + errno = fresult_to_errno(res); + ret = -1; + goto close; + } } #if CONFIG_FATFS_IMMEDIATE_FSYNC @@ -1072,6 +1141,13 @@ static int vfs_fat_truncate(void* ctx, const char *path, off_t length) out: free(file); return ret; + +lseek_or_write_fail: + _lock_release(&fat_ctx->lock); + ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); + errno = fresult_to_errno(res); + ret = -1; + goto close; } static int vfs_fat_ftruncate(void* ctx, int fd, off_t length) @@ -1098,29 +1174,50 @@ static int vfs_fat_ftruncate(void* ctx, int fd, off_t length) goto out; } - long sz = f_size(file); - if (sz < length) { - ESP_LOGD(TAG, "ftruncate does not support extending size"); - errno = EPERM; - ret = -1; - goto out; - } + FSIZE_t seek_ptr_pos = (FSIZE_t) f_tell(file); // current seek pointer position + FSIZE_t sz = (FSIZE_t) f_size(file); // current file size (end of file position) res = f_lseek(file, length); - if (res != FR_OK) { - ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); - errno = fresult_to_errno(res); - ret = -1; - goto out; + if (res != FR_OK || f_tell(file) != length) { + goto fail; } - res = f_truncate(file); + if (sz < length) { + res = f_lseek(file, sz); // go to the previous end of file + if (res != FR_OK) { + goto fail; + } - if (res != FR_OK) { - ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); - errno = fresult_to_errno(res); - ret = -1; - goto out; + FSIZE_t new_free_space = ((FSIZE_t) length) - sz; + UINT written; + + if (new_free_space > UINT32_MAX) { + ESP_LOGE(TAG, "%s: Cannot extend the file more than 4GB at once", __func__); + ret = -1; + goto out; + } + + FSIZE_t buf_size_limit = F_WRITE_MALLOC_ZEROING_BUF_SIZE_LIMIT; + FSIZE_t buf_size = new_free_space < buf_size_limit ? new_free_space : buf_size_limit; + res = f_write_zero_mem(file, new_free_space, buf_size, &written); + + if (res != FR_OK) { + goto fail; + } else if (written != (UINT) new_free_space) { + res = FR_DISK_ERR; + goto fail; + } + + res = f_lseek(file, seek_ptr_pos); // return to the original position + if (res != FR_OK) { + goto fail; + } + } else { + res = f_truncate(file); + + if (res != FR_OK) { + goto fail; + } } #if CONFIG_FATFS_IMMEDIATE_FSYNC @@ -1135,6 +1232,12 @@ static int vfs_fat_ftruncate(void* ctx, int fd, off_t length) out: _lock_release(&fat_ctx->lock); return ret; + +fail: + ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); + errno = fresult_to_errno(res); + ret = -1; + goto out; } static int vfs_fat_utime(void *ctx, const char *path, const struct utimbuf *times) diff --git a/components/vfs/include/esp_vfs.h b/components/vfs/include/esp_vfs.h index f3358d50761f..f7cca42e712b 100644 --- a/components/vfs/include/esp_vfs.h +++ b/components/vfs/include/esp_vfs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,17 +46,17 @@ extern "C" { /** * Default value of flags member in esp_vfs_t structure. */ -#define ESP_VFS_FLAG_DEFAULT 0 +#define ESP_VFS_FLAG_DEFAULT (1 << 0) /** * Flag which indicates that FS needs extra context pointer in syscalls. */ -#define ESP_VFS_FLAG_CONTEXT_PTR 1 +#define ESP_VFS_FLAG_CONTEXT_PTR (1 << 1) /** * Flag which indicates that FS is located on read-only partition. */ -#define ESP_VFS_FLAG_READONLY_FS 2 +#define ESP_VFS_FLAG_READONLY_FS (1 << 2) /* * @brief VFS identificator used for esp_vfs_register_with_id() From 152f17236729f1d0b43afb6d54324e8e38549cb0 Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Tue, 20 Feb 2024 16:19:51 +0530 Subject: [PATCH 10/33] fix(esp_hw_support): update hmac toggle method due to discrepency in ROM code Need to update the HMAC enable/disable method due to discrepancy in ROM code across different targets for the esp_hmac_disable() API. --- components/esp_hw_support/esp_hmac.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/components/esp_hw_support/esp_hmac.c b/components/esp_hw_support/esp_hmac.c index f79899b97d37..34df0aac4ea9 100644 --- a/components/esp_hw_support/esp_hmac.c +++ b/components/esp_hw_support/esp_hmac.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -187,7 +187,9 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) ESP_LOGD(TAG, "HMAC computation in downstream mode is completed."); - ets_hmac_disable(); + HMAC_RCC_ATOMIC() { + hmac_ll_enable_bus_clock(false); + } esp_crypto_hmac_lock_release(); @@ -197,9 +199,17 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) esp_err_t esp_hmac_jtag_disable() { esp_crypto_hmac_lock_acquire(); - ets_hmac_enable(); + + HMAC_RCC_ATOMIC() { + hmac_ll_enable_bus_clock(true); + } + REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1); - ets_hmac_disable(); + + HMAC_RCC_ATOMIC() { + hmac_ll_enable_bus_clock(false); + } + esp_crypto_hmac_lock_release(); ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled."); @@ -234,7 +244,6 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id, } else { return ESP_OK; } - } esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) From 185e49b53ff6773ae41a5b4160802ba42480a025 Mon Sep 17 00:00:00 2001 From: Roland Dobai Date: Wed, 21 Feb 2024 12:46:39 +0100 Subject: [PATCH 11/33] fix(tools): Add additional Python installation checks Warn if IDF_PYTHON_ENV_PATH set to a suspicious path with different ESP-IDF version and/or Python version. Fail if the virtual environment was created for a different ESP-IDF version. Closes https://github.com/espressif/esp-idf/issues/13196 --- tools/idf_tools.py | 58 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/tools/idf_tools.py b/tools/idf_tools.py index 796d5c56707f..f4df447c2a9d 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -95,6 +95,9 @@ class WindowsError(OSError): # type: ignore IDF_TOOLS_EXPORT_CMD = os.environ.get('IDF_TOOLS_INSTALL_CMD') IDF_DL_URL = 'https://dl.espressif.com/dl/esp-idf' IDF_PIP_WHEELS_URL = os.environ.get('IDF_PIP_WHEELS_URL', 'https://dl.espressif.com/pypi') +PYTHON_VENV_DIR_TEMPLATE = 'idf{}_py{}_env' +PYTHON_VER_MAJOR_MINOR = f'{sys.version_info.major}.{sys.version_info.minor}' +VENV_VER_FILE = 'idf_version.txt' class GlobalVarsStore: @@ -1687,11 +1690,11 @@ def get_python_env_path() -> Tuple[str, str, str, str]: """ Returns tuple of Python environment path, Python env. path with subdir and full path from Python (i.e. with executable). """ - python_ver_major_minor = f'{sys.version_info.major}.{sys.version_info.minor}' - idf_version = get_idf_version() - idf_python_env_path = os.getenv('IDF_PYTHON_ENV_PATH') or os.path.join(g.idf_tools_path, 'python_env', - f'idf{idf_version}_py{python_ver_major_minor}_env') + idf_python_env_path = os.getenv('IDF_PYTHON_ENV_PATH') or os.path.join(g.idf_tools_path, + 'python_env', + PYTHON_VENV_DIR_TEMPLATE.format(idf_version, + PYTHON_VER_MAJOR_MINOR)) python_exe, subdir = get_python_exe_and_subdir() idf_python_export_path = os.path.join(idf_python_env_path, subdir) @@ -2122,6 +2125,23 @@ def process_tool( return tool_export_paths, tool_export_vars, tool_found +def check_python_venv_compatibility(idf_python_env_path: str, idf_version: str) -> None: + try: + with open(os.path.join(idf_python_env_path, VENV_VER_FILE), 'r') as f: + read_idf_version = f.read().strip() + if read_idf_version != idf_version: + fatal(f'Python environment is set to {idf_python_env_path} which was generated for ' + f'ESP-IDF {read_idf_version} instead of the current {idf_version}. ' + 'The issue can be solved by (1) removing the directory and re-running the install script, ' + 'or (2) unsetting the IDF_PYTHON_ENV_PATH environment variable, or (3) ' + 're-runing the install script from a clean shell where an ESP-IDF environment is ' + 'not active.') + raise SystemExit(1) + except OSError as e: + # perhaps the environment was generated before the support for VENV_VER_FILE was added + warn(f'Error while accessing the ESP-IDF version file in the Python environment: {e}') + + def action_export(args: Any) -> None: """ Exports all necessary environment variables and paths needed for tools used. @@ -2166,6 +2186,8 @@ def action_export(args: Any) -> None: if os.getenv('ESP_IDF_VERSION') != idf_version: export_vars['ESP_IDF_VERSION'] = idf_version + check_python_venv_compatibility(idf_python_env_path, idf_version) + idf_tools_dir = os.path.join(g.idf_path, 'tools') # type: ignore idf_tools_dir = to_shell_specific_paths([idf_tools_dir])[0] if current_path and idf_tools_dir not in current_path: @@ -2582,7 +2604,9 @@ def action_install_python_env(args): # type: ignore venv_can_upgrade = False - if not os.path.exists(virtualenv_python): + if os.path.exists(virtualenv_python): + check_python_venv_compatibility(idf_python_env_path, idf_version) + else: if subprocess.run([sys.executable, '-m', 'venv', '-h'], check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0: # venv available virtualenv_options = ['--clear'] # delete environment if already exists @@ -2592,10 +2616,34 @@ def action_install_python_env(args): # type: ignore venv_can_upgrade = True info(f'Creating a new Python environment in {idf_python_env_path}') + + try: + environ_idf_python_env_path = os.environ['IDF_PYTHON_ENV_PATH'] + correct_env_path = environ_idf_python_env_path.endswith(PYTHON_VENV_DIR_TEMPLATE.format(idf_version, + PYTHON_VER_MAJOR_MINOR)) + if not correct_env_path and re.search(PYTHON_VENV_DIR_TEMPLATE.format(r'\d+\.\d+', r'\d+\.\d+'), + environ_idf_python_env_path): + warn(f'IDF_PYTHON_ENV_PATH is set to {environ_idf_python_env_path} but it does not match ' + f'the detected {idf_version} ESP-IDF version and/or the used {PYTHON_VER_MAJOR_MINOR} ' + 'version of Python. If you have not set IDF_PYTHON_ENV_PATH intentionally then it is ' + 'recommended to re-run this script from a clean shell where an ESP-IDF environment is ' + 'not active.') + + except KeyError: + # if IDF_PYTHON_ENV_PATH not defined then the above checks can be skipped + pass + subprocess.check_call([sys.executable, '-m', 'venv', *virtualenv_options, idf_python_env_path], stdout=sys.stdout, stderr=sys.stderr) + + try: + with open(os.path.join(idf_python_env_path, VENV_VER_FILE), 'w') as f: + f.write(idf_version) + except OSError as e: + warn(f'Error while generating the ESP-IDF version file in the Python environment: {e}') + else: # The embeddable Python for Windows doesn't have the built-in venv module install_legacy_python_virtualenv(idf_python_env_path) From 836516b4099deab22e9938d3660943884feef129 Mon Sep 17 00:00:00 2001 From: redfast00 <10746993+redfast00@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:40:36 +0000 Subject: [PATCH 12/33] docs(esp32): add warning about authenticity of pre-encrypted ota --- examples/system/ota/pre_encrypted_ota/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/system/ota/pre_encrypted_ota/README.md b/examples/system/ota/pre_encrypted_ota/README.md index 948fe059d9c6..9c951326b373 100644 --- a/examples/system/ota/pre_encrypted_ota/README.md +++ b/examples/system/ota/pre_encrypted_ota/README.md @@ -9,6 +9,9 @@ Pre-encrypted firmware binary must be hosted on OTA update server. This firmware will be fetched and then decrypted on device before being flashed. This allows firmware to remain `confidential` on the OTA update channel irrespective of underlying transport (e.g., non-TLS). +> [!CAUTION] +> Using the Pre-encrypted Binary OTA provides confidentiality of the firmware, but it does not ensure authenticity of the firmware. For ensuring that the firmware is coming from trusted source, please consider enabling secure boot feature along with the Pre-encrypted binary OTA. Please refer to security guide in the ESP-IDF docs for more details. + ## ESP Encrypted Image Abstraction Layer This example uses `esp_encrypted_img` component hosted at [idf-extra-components/esp_encrypted_img](https://github.com/espressif/idf-extra-components/blob/master/esp_encrypted_img) and available though the [IDF component manager](https://components.espressif.com/component/espressif/esp_encrypted_img). From 1302fd70bad5a9e9006803370d7fb2943f012391 Mon Sep 17 00:00:00 2001 From: Peter Marcisovsky Date: Fri, 23 Feb 2024 11:52:45 +0100 Subject: [PATCH 13/33] ci: Add esp32s3 runner for usb device example tests - CI USB device tests are run on esp32s3 - usb_host env_marker removed - not used anymore - failing usb_device_ncm test fixed --- examples/peripherals/.build-test-rules.yml | 4 ++-- .../pytest_usb_device_composite.py | 4 ++-- .../usb/device/tusb_console/pytest_usb_device_console.py | 4 ++-- .../peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py | 4 ++-- .../usb/device/tusb_midi/pytest_usb_device_midi.py | 4 ++-- .../peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py | 2 +- .../peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py | 5 ++--- .../device/tusb_serial_device/pytest_usb_device_serial.py | 4 ++-- tools/ci/idf_pytest/constants.py | 1 - 9 files changed, 15 insertions(+), 17 deletions(-) diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index dbc92f515a96..b2c46d433cc5 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -424,7 +424,7 @@ examples/peripherals/usb/device: disable: - if: SOC_USB_OTG_SUPPORTED != 1 disable_test: - - if: IDF_TARGET not in ["esp32s2"] + - if: IDF_TARGET not in ["esp32s2", "esp32s3"] temporary: true reason: lack of runners with usb_device tag depends_components: @@ -437,7 +437,7 @@ examples/peripherals/usb/device/tusb_ncm: disable: - if: SOC_USB_OTG_SUPPORTED != 1 or SOC_WIFI_SUPPORTED != 1 disable_test: - - if: IDF_TARGET not in ["esp32s2"] + - if: IDF_TARGET not in ["esp32s2", "esp32s3"] temporary: true reason: lack of runners with usb_device tag depends_components: diff --git a/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py b/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py index 843b70312829..2f30ac4b3e59 100644 --- a/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py +++ b/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from time import sleep @@ -11,7 +11,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32p4 -@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32p4'], reason='lack of runners with usb_device tag') +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device def test_usb_composite_device_serial_example(dut: Dut) -> None: dut.expect_exact('Hello World!') diff --git a/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py b/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py index b32b19f5d852..37b0e5bfccb7 100644 --- a/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py +++ b/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from time import sleep @@ -11,7 +11,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32p4 -@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32p4'], reason='lack of runners with usb_device tag') +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device def test_usb_device_console_example(dut: Dut) -> None: dut.expect_exact('USB initialization DONE') diff --git a/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py b/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py index d3b41ff03876..25f62317877b 100644 --- a/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py +++ b/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut @@ -7,7 +7,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32p4 -@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32p4'], reason='lack of runners with usb_device tag') +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device def test_usb_device_hid_example(dut: Dut) -> None: dut.expect_exact('USB initialization DONE') diff --git a/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py b/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py index 2e9c7d05ba03..271591a17054 100644 --- a/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py +++ b/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut @@ -7,7 +7,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32p4 -@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32p4'], reason='lack of runners with usb_device tag') +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device def test_usb_device_midi_example(dut: Dut) -> None: dut.expect_exact('USB initialization DONE') diff --git a/examples/peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py b/examples/peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py index bac44fe8c11e..6e8124975066 100644 --- a/examples/peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py +++ b/examples/peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py @@ -7,7 +7,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32p4 -@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32p4'], reason='lack of runners with usb_device tag') +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device def test_usb_device_msc_example(dut: Dut) -> None: dut.expect('Mount storage') diff --git a/examples/peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py b/examples/peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py index e31841b8b94c..743e31de24d3 100644 --- a/examples/peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py +++ b/examples/peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import subprocess import time @@ -9,14 +9,13 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device def test_usb_device_ncm_example(dut: Dut) -> None: netif_mac = dut.expect(r'Network interface HW address: ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})') netif_mac = netif_mac.group(1).decode('utf-8') dut.expect_exact('USB NCM and WiFi initialized and started') dut.expect_exact('Returned from app_main()') - time.sleep(1) # Wait 1s for the network interface to appear + time.sleep(5) # Wait 5s for the network interface to appear out_bytes = subprocess.check_output('ifconfig', shell=True, timeout=5) out_str = out_bytes.decode('utf-8') print('expected network interface HW address: ', netif_mac) diff --git a/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py b/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py index 545b4ee3a4de..962490d84eb3 100644 --- a/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py +++ b/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from time import sleep @@ -11,7 +11,7 @@ @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.esp32p4 -@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32p4'], reason='lack of runners with usb_device tag') +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device def test_usb_device_serial_example(dut: Dut) -> None: dut.expect_exact('USB initialization DONE') diff --git a/tools/ci/idf_pytest/constants.py b/tools/ci/idf_pytest/constants.py index 8ab64183f04c..14236b076462 100644 --- a/tools/ci/idf_pytest/constants.py +++ b/tools/ci/idf_pytest/constants.py @@ -58,7 +58,6 @@ 'eth_dm9051': 'SPI Ethernet module with two DM9051', 'quad_psram': 'runners with quad psram', 'octal_psram': 'runners with octal psram', - 'usb_host': 'usb host runners', 'usb_host_flash_disk': 'usb host runners with USB flash disk attached', 'usb_device': 'usb device runners', 'ethernet_ota': 'ethernet OTA runners', From bafaf07c189669f7776d2a4d2251ba3b77fe4c80 Mon Sep 17 00:00:00 2001 From: Jakob Hasse Date: Sun, 18 Feb 2024 16:07:41 +0800 Subject: [PATCH 14/33] refactor(cxx): moved C++ init functions to cxx component * Also fixed setting the C++ exception emergency pool size correctly when C++ exceptions are disabled: __cxx_eh_arena_size_get() is now called again even if CONFIG_COMPILER_CXX_EXCEPTIONS=n --- components/cxx/CMakeLists.txt | 4 +- components/cxx/cxx_init.cpp | 50 ++++++++++++++++++++++++ components/esp_system/startup_funcs.c | 35 ----------------- components/esp_system/system_init_fn.txt | 2 +- 4 files changed, 54 insertions(+), 37 deletions(-) create mode 100644 components/cxx/cxx_init.cpp diff --git a/components/cxx/CMakeLists.txt b/components/cxx/CMakeLists.txt index a4075b34b521..a6e61100fc6c 100644 --- a/components/cxx/CMakeLists.txt +++ b/components/cxx/CMakeLists.txt @@ -6,8 +6,9 @@ endif() idf_component_register(SRCS "cxx_exception_stubs.cpp" "cxx_guards.cpp" + "cxx_init.cpp" # Make sure that pthread is in component list - PRIV_REQUIRES pthread) + PRIV_REQUIRES pthread esp_system) if(NOT CONFIG_CXX_EXCEPTIONS) set(WRAP_FUNCTIONS @@ -54,6 +55,7 @@ else() target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ gcc) endif() target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxa_guard_dummy") +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxx_init_dummy") # Force libpthread to appear later than libstdc++ in link line since libstdc++ depends on libpthread. # Furthermore, force libcxx to appear later than libgcc because some libgcc unwind code is wrapped, if C++ diff --git a/components/cxx/cxx_init.cpp b/components/cxx/cxx_init.cpp new file mode 100644 index 000000000000..7ade550d760c --- /dev/null +++ b/components/cxx/cxx_init.cpp @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_private/startup_internal.h" + +namespace { + const char *TAG = "C++ init"; +} + +#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS +// workaround for C++ exception large memory allocation +extern "C" void _Unwind_SetEnableExceptionFdeSorting(unsigned char enable); + +ESP_SYSTEM_INIT_FN(init_cxx_exceptions, SECONDARY, BIT(0), 205) +{ + ESP_EARLY_LOGD(TAG, "Setting C++ exception workarounds."); + _Unwind_SetEnableExceptionFdeSorting(0); + return ESP_OK; +} +#endif // CONFIG_COMPILER_CXX_EXCEPTIONS + +/** + * This function overwrites the same function of libsupc++ (part of libstdc++). + * Consequently, libsupc++ will then follow our configured exception emergency pool size. + * + * It will be called even with -fno-exception for user code since the stdlib still uses exceptions. + */ +extern "C" size_t __cxx_eh_arena_size_get(void) +{ +#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS + ESP_EARLY_LOGD(TAG, "Setting C++ exception emergency pool to %u.", CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE); + return CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE; +#else + ESP_EARLY_LOGD(TAG, "Setting C++ exception emergency pool to 0."); + return 0; +#endif +} + +/** + * Dummy function used to force linking this file. + * This works via -u __cxx_init_dummy flag in CMakeLists.txt + */ +extern "C" void __cxx_init_dummy(void) +{ +} diff --git a/components/esp_system/startup_funcs.c b/components/esp_system/startup_funcs.c index dc188f33f0e5..216c2a883ace 100644 --- a/components/esp_system/startup_funcs.c +++ b/components/esp_system/startup_funcs.c @@ -259,41 +259,6 @@ ESP_SYSTEM_INIT_FN(init_coexist, SECONDARY, BIT(0), 204) } #endif // CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE -#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS -/** - * This function overwrites a the same function of libsupc++ (part of libstdc++). - * Consequently, libsupc++ will then follow our configured exception emergency pool size. - * - * It will be called even with -fno-exception for user code since the stdlib still uses exceptions. - */ -size_t __cxx_eh_arena_size_get(void) -{ -#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS - return CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE; -#else - return 0; -#endif -} - -// workaround for C++ exception crashes -void _Unwind_SetNoFunctionContextInstall(unsigned char enable) __attribute__((weak, alias("_Unwind_SetNoFunctionContextInstall_Default"))); -// workaround for C++ exception large memory allocation -void _Unwind_SetEnableExceptionFdeSorting(unsigned char enable); - -static IRAM_ATTR void _Unwind_SetNoFunctionContextInstall_Default(unsigned char enable __attribute__((unused))) -{ - (void)0; -} - -ESP_SYSTEM_INIT_FN(init_cxx_exceptions, SECONDARY, BIT(0), 205) -{ - ESP_EARLY_LOGD(TAG, "Setting C++ exception workarounds."); - _Unwind_SetNoFunctionContextInstall(1); - _Unwind_SetEnableExceptionFdeSorting(0); - return ESP_OK; -} -#endif // CONFIG_COMPILER_CXX_EXCEPTIONS - #ifndef CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE ESP_SYSTEM_INIT_FN(init_disable_rtc_wdt, SECONDARY, BIT(0), 999) { diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 51db470feb84..75c02856c80b 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -86,7 +86,7 @@ SECONDARY: 140: init_dbg_stubs in components/app_trace/debug_stubs.c on BIT(0) SECONDARY: 201: init_pm in components/esp_system/startup_funcs.c on BIT(0) SECONDARY: 203: init_apb_dma in components/esp_system/startup_funcs.c on BIT(0) SECONDARY: 204: init_coexist in components/esp_system/startup_funcs.c on BIT(0) -SECONDARY: 205: init_cxx_exceptions in components/esp_system/startup_funcs.c on BIT(0) +SECONDARY: 205: init_cxx_exceptions in components/cxx/cxx_init.cpp on BIT(0) # usb_console needs to create an esp_timer at startup. # This can be done only after esp_timer initialization (esp_timer_init_os). From f9c9e18bca7f9f95bbb44b32547afc251142d455 Mon Sep 17 00:00:00 2001 From: Jakob Hasse Date: Thu, 22 Feb 2024 11:49:47 +0800 Subject: [PATCH 15/33] fix(linux): prevent build error on MacOS and optimize buffer usage on Linux --- components/console/linenoise/linenoise.c | 11 ++++++++++- .../FreeRTOS-Kernel/portable/linux/port_idf.c | 6 +++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/components/console/linenoise/linenoise.c b/components/console/linenoise/linenoise.c index 92fcab393d06..357d2c241554 100644 --- a/components/console/linenoise/linenoise.c +++ b/components/console/linenoise/linenoise.c @@ -107,7 +107,11 @@ #include #include #include -#include +#if !CONFIG_IDF_TARGET_LINUX +// On Linux, we don't need __fbufsize (see comments below), and +// __fbufsize not available on MacOS (which is also considered "Linux" target) +#include // for __fbufsize +#endif #include #include #include @@ -216,9 +220,14 @@ bool linenoiseIsDumbMode(void) { } static void flushWrite(void) { +// On Linux, we set stdout to unbuffered mode to facilitate interaction with tools. +// Performance on Linux is not considered as critical as on chip targets. Additionally, +// MacOS does not have __fbufsize. +#if !CONFIG_IDF_TARGET_LINUX if (__fbufsize(stdout) > 0) { fflush(stdout); } +#endif fsync(fileno(stdout)); } diff --git a/components/freertos/FreeRTOS-Kernel/portable/linux/port_idf.c b/components/freertos/FreeRTOS-Kernel/portable/linux/port_idf.c index a8823df715d1..04ad59fdb863 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/linux/port_idf.c +++ b/components/freertos/FreeRTOS-Kernel/portable/linux/port_idf.c @@ -50,9 +50,9 @@ static void main_task(void* args) int main(int argc, const char **argv) { - // This makes sure that stdio is flushed after each '\n' so that idf.py monitor - // reads the program output on time. - setvbuf(stdout, NULL, _IOLBF, 0); + // This makes sure that stdio is always syncronized so that idf.py monitor + // and other tools read text output on time. + setvbuf(stdout, NULL, _IONBF, 0); usleep(1000); BaseType_t res = xTaskCreatePinnedToCore(&main_task, "main", From 7075b61a6abdd2f84daf35b81f386aa975442b7e Mon Sep 17 00:00:00 2001 From: gaoxu Date: Thu, 29 Feb 2024 21:01:10 +0800 Subject: [PATCH 16/33] docs(uart): update lp uart and p4/c5 uart programming guide --- .../beta3/include/soc/Kconfig.soc_caps.in | 4 ++ .../soc/esp32c5/beta3/include/soc/soc_caps.h | 1 + .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 ++ components/soc/esp32c6/include/soc/soc_caps.h | 1 + .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 ++ components/soc/esp32p4/include/soc/soc_caps.h | 1 + docs/docs_not_updated/esp32c5.txt | 1 - docs/docs_not_updated/esp32p4.txt | 1 - docs/en/api-reference/peripherals/uart.rst | 43 ++++++++++--------- docs/zh_CN/api-reference/peripherals/uart.rst | 43 ++++++++++--------- 10 files changed, 59 insertions(+), 44 deletions(-) diff --git a/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in index 9ee4745d3f4f..f8d4368a55ed 100644 --- a/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in @@ -395,6 +395,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT bool default y +config SOC_UART_HAS_LP_UART + bool + default y + config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND bool default y diff --git a/components/soc/esp32c5/beta3/include/soc/soc_caps.h b/components/soc/esp32c5/beta3/include/soc/soc_caps.h index a35c6fd25590..9451ddbdc81a 100644 --- a/components/soc/esp32c5/beta3/include/soc/soc_caps.h +++ b/components/soc/esp32c5/beta3/include/soc/soc_caps.h @@ -480,6 +480,7 @@ // #define SOC_UART_SUPPORT_RTC_CLK (1) // TODO: [ESP32C5] IDF-8642 #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ +#define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */ // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 79b2b3b9c6b0..d86c442bde74 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1187,6 +1187,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT bool default y +config SOC_UART_HAS_LP_UART + bool + default y + config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index c4f060e2211d..1c8ff2b70c61 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -471,6 +471,7 @@ #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ +#define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */ // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 05ff6fcc614d..7c3445382ce7 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1299,6 +1299,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT bool default y +config SOC_UART_HAS_LP_UART + bool + default y + config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index cc30c7b77c2b..90c8a29fc112 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -539,6 +539,7 @@ #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ +#define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */ // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) diff --git a/docs/docs_not_updated/esp32c5.txt b/docs/docs_not_updated/esp32c5.txt index bf93d3e42c5c..24d43cc0d8a4 100644 --- a/docs/docs_not_updated/esp32c5.txt +++ b/docs/docs_not_updated/esp32c5.txt @@ -147,7 +147,6 @@ api-reference/peripherals/sd_pullup_requirements.rst api-reference/peripherals/spi_master.rst api-reference/peripherals/index.rst api-reference/peripherals/sdmmc_host.rst -api-reference/peripherals/uart.rst api-reference/peripherals/ecdsa.rst api-reference/peripherals/rmt.rst api-reference/kconfig.rst diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index d8b1098c141e..ec5d80e67015 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -83,7 +83,6 @@ api-reference/peripherals/i2c.rst api-reference/peripherals/dedic_gpio.rst api-reference/peripherals/sd_pullup_requirements.rst api-reference/peripherals/index.rst -api-reference/peripherals/uart.rst api-reference/network/esp_openthread.rst api-reference/network/esp_dpp.rst api-reference/network/esp_now.rst diff --git a/docs/en/api-reference/peripherals/uart.rst b/docs/en/api-reference/peripherals/uart.rst index c1844b2c58ec..fe9afb589ccd 100644 --- a/docs/en/api-reference/peripherals/uart.rst +++ b/docs/en/api-reference/peripherals/uart.rst @@ -12,7 +12,7 @@ The {IDF_TARGET_NAME} chip has {IDF_TARGET_SOC_UART_HP_NUM} UART controllers (al Each UART controller is independently configurable with parameters such as baud rate, data bit length, bit ordering, number of stop bits, parity bit, etc. All the regular UART controllers are compatible with UART-enabled devices from various manufacturers and can also support Infrared Data Association (IrDA) protocols. -.. only:: SOC_UART_LP_NUM +.. only:: SOC_UART_HAS_LP_UART Additionally, the {IDF_TARGET_NAME} chip has one low-power (LP) UART controller. It is the cut-down version of regular UART. Usually, the LP UART controller only support basic UART functionality with a much smaller RAM size, and does not support IrDA or RS485 protocols. For a full list of difference between UART and LP UART, please refer to the **{IDF_TARGET_NAME} Technical Reference Manual** > **UART Controller (UART)** > **Features** [`PDF <{IDF_TARGET_TRM_EN_URL}#uart>`__]). @@ -30,6 +30,10 @@ The overview describes how to establish communication between an {IDF_TARGET_NAM Steps 1 to 3 comprise the configuration stage. Step 4 is where the UART starts operating. Steps 5 and 6 are optional. +.. only:: SOC_UART_HAS_LP_UART + + Additionally, when using the LP UART Controller you need to pay attention to :ref:`uart-api-lp-uart-driver`. + The UART driver's functions identify each of the UART controllers using :cpp:type:`uart_port_t`. This identification is needed for all the following function calls. @@ -239,38 +243,35 @@ The API provides a convenient way to handle specific interrupts discussed in thi - Disable the interrupt using :cpp:func:`uart_disable_pattern_det_intr` +.. _uart-api-deleting-driver: + +Deleting a Driver +^^^^^^^^^^^^^^^^^ + +If the communication established with :cpp:func:`uart_driver_install` is no longer required, the driver can be removed to free allocated resources by calling :cpp:func:`uart_driver_delete`. + + Macros ^^^^^^ The API also defines several macros. For example, :c:macro:`UART_HW_FIFO_LEN` defines the length of hardware FIFO buffers; :c:macro:`UART_BITRATE_MAX` gives the maximum baud rate supported by the UART controllers, etc. +.. only:: SOC_UART_HAS_LP_UART -.. only:: SOC_UART_LP_NUM + .. _uart-api-lp-uart-driver: Use LP UART Controller with HP Core ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - The UART driver also supports to control the LP UART controller when the chip is in active mode. The configuration steps for the LP UART are no difference with the steps for a normal UART controller, except: - - 1. The port number for the LP UART controller is defined by :c:macro:`LP_UART_NUM_0`. - 2. The available clock sources for the LP UART controller can be found in :cpp:type:`lp_uart_sclk_t`. - 3. The size of the hardware FIFO for the LP UART controller is much smaller, which is defined in :c:macro:`SOC_LP_UART_FIFO_LEN`. + The UART driver also supports to control the LP UART controller when the chip is in active mode. The configuration steps for the LP UART are the same as the steps for a normal UART controller, except: - .. only:: SOC_LP_GPIO_MATRIX_SUPPORTED + .. list:: - 4. The GPIO pins for the LP UART controller can only be selected from the LP GPIO pins. - - .. only:: not SOC_LP_GPIO_MATRIX_SUPPORTED - - 4. The GPIO pins for the LP UART controller are unalterable, because there is no LP GPIO matrix on the target. Please see **{IDF_TARGET_NAME} Technical Reference Manual** > **IO MUX and GPIO Matrix (GPIO, IO MUX)** > **LP IO MUX Functions List** [`PDF <{IDF_TARGET_TRM_EN_URL}#lp-io-mux-func-list>`__] for the specific pin numbers. - - -.. _uart-api-deleting-driver: - -Deleting a Driver -^^^^^^^^^^^^^^^^^ - -If the communication established with :cpp:func:`uart_driver_install` is no longer required, the driver can be removed to free allocated resources by calling :cpp:func:`uart_driver_delete`. + - The port number for the LP UART controller is defined by :c:macro:`LP_UART_NUM_0`. + - The available clock sources for the LP UART controller can be found in :cpp:type:`lp_uart_sclk_t`. + - The size of the hardware FIFO for the LP UART controller is much smaller, which is defined in :c:macro:`SOC_LP_UART_FIFO_LEN`. + :SOC_LP_GPIO_MATRIX_SUPPORTED: - The GPIO pins for the LP UART controller can only be selected from the LP GPIO pins. + :not SOC_LP_GPIO_MATRIX_SUPPORTED: - The GPIO pins for the LP UART controller are unalterable, because there is no LP GPIO matrix on the target. Please see **{IDF_TARGET_NAME} Technical Reference Manual** > **IO MUX and GPIO Matrix (GPIO, IO MUX)** > **LP IO MUX Functions List** [`PDF <{IDF_TARGET_TRM_EN_URL}#lp-io-mux-func-list>`__] for the specific pin numbers. Overview of RS485 Specific Communication 0ptions diff --git a/docs/zh_CN/api-reference/peripherals/uart.rst b/docs/zh_CN/api-reference/peripherals/uart.rst index 0db37d0aa91a..608fa135ef1b 100644 --- a/docs/zh_CN/api-reference/peripherals/uart.rst +++ b/docs/zh_CN/api-reference/peripherals/uart.rst @@ -12,7 +12,7 @@ 每个 UART 控制器可以独立配置波特率、数据位长度、位顺序、停止位位数、奇偶校验位等参数。所有具备完整功能的 UART 控制器都能与不同制造商的 UART 设备兼容,并且支持红外数据协会 (IrDA) 定义的标准协议。 -.. only:: SOC_UART_LP_NUM +.. only:: SOC_UART_HAS_LP_UART 此外,{IDF_TARGET_NAME} 芯片还有一个满足低功耗需求的 LP UART 控制器。LP UART 是原 UART 的功能剪裁版本。它只支持基础 UART 功能,不支持 IrDA 或 RS485 协议,并且只有一块较小的 RAM 存储空间。想要全面了解的 UART 及 LP UART 功能区别,请参考 **{IDF_TARGET_NAME} 技术参考手册** > UART 控制器 (UART) > 主要特性 [`PDF <{IDF_TARGET_TRM_EN_URL}#uart>`__]。 @@ -30,6 +30,10 @@ 步骤 1 到 3 为配置阶段,步骤 4 为 UART 运行阶段,步骤 5 和 6 为可选步骤。 +.. only:: SOC_UART_HAS_LP_UART + + 此外,LP UART 控制器的编程需要注意 :ref:`uart-api-lp-uart-driver`。 + UART 驱动程序函数通过 :cpp:type:`uart_port_t` 识别不同的 UART 控制器。调用以下所有函数均需此标识。 @@ -239,38 +243,35 @@ API 提供了一种便利的方法来处理本文所讨论的特定中断,即 - 禁用中断:调用 :cpp:func:`uart_disable_pattern_det_intr` +.. _uart-api-deleting-driver: + +删除驱动程序 +^^^^^^^^^^^^^^^^^^^^^^^ + +如不再需要与 :cpp:func:`uart_driver_install` 建立通信,则可调用 :cpp:func:`uart_driver_delete` 删除驱动程序,释放已分配的资源。 + + 宏指令 ^^^^^^^^^^^^ API 还定义了一些宏指令。例如,:c:macro:`UART_HW_FIFO_LEN` 定义了硬件 FIFO 缓冲区的长度,:c:macro:`UART_BITRATE_MAX` 定义了 UART 控制器支持的最大波特率。 +.. only:: SOC_UART_HAS_LP_UART -.. only:: SOC_UART_LP_NUM + .. _uart-api-lp-uart-driver: 使用主核驱动 LP UART 控制器 - ^^^^^^^^^^^^^^^^^^^^^^^^ + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UART 驱动程序还适配了在 Active 模式下对 LP UART 控制器的驱动。LP UART 的配置流程和普通 UART 没有本质上的差别,除了有以下几点需要注意: - 1. LP UART 控制器的端口号为 :c:macro:`LP_UART_NUM_0`。 - 2. LP UART 控制器的可选时钟源可以在 :cpp:type:`lp_uart_sclk_t` 中找到。 - 3. LP UART 控制器的硬件 FIFO 大小要远小于普通 UART 控制器的硬件 FIFO 大小,其值为 :c:macro:`SOC_LP_UART_FIFO_LEN`。 - - .. only:: SOC_LP_GPIO_MATRIX_SUPPORTED + .. list:: - 4. LP UART 控制器的 GPIO 引脚只能从 LP GPIO 引脚中选择。 - - .. only:: not SOC_LP_GPIO_MATRIX_SUPPORTED - - 4. 由于该芯片没有 LP GPIO 交换矩阵,LP UART 控制器的 GPIO 引脚不可改变。具体的引脚号请查看 **{IDF_TARGET_NAME} 技术参考手册** > **IO MUX 和 GPIO 交换矩阵 (GPIO, IO MUX)** > **LP IO MUX 管脚功能列表** [`PDF <{IDF_TARGET_TRM_CN_URL}#lp-io-mux-func-list>`__]。 - - -.. _uart-api-deleting-driver: - -删除驱动程序 -^^^^^^^^^^^^^^^^^^^^^^^ - -如不再需要与 :cpp:func:`uart_driver_install` 建立通信,则可调用 :cpp:func:`uart_driver_delete` 删除驱动程序,释放已分配的资源。 + - LP UART 控制器的端口号为 :c:macro:`LP_UART_NUM_0`。 + - LP UART 控制器的可选时钟源可以在 :cpp:type:`lp_uart_sclk_t` 中找到。 + - LP UART 控制器的硬件 FIFO 大小要远小于普通 UART 控制器的硬件 FIFO 大小,其值为 :c:macro:`SOC_LP_UART_FIFO_LEN`。 + :SOC_LP_GPIO_MATRIX_SUPPORTED: - LP UART 控制器的 GPIO 引脚只能从 LP GPIO 引脚中选择。 + :not SOC_LP_GPIO_MATRIX_SUPPORTED: - 由于该芯片没有 LP GPIO 交换矩阵,LP UART 控制器的 GPIO 引脚不可改变。具体的引脚号请查看 **{IDF_TARGET_NAME} 技术参考手册** > **IO MUX 和 GPIO 交换矩阵 (GPIO, IO MUX)** > **LP IO MUX 管脚功能列表** [`PDF <{IDF_TARGET_TRM_CN_URL}#lp-io-mux-func-list>`__]。 RS485 特定通信模式简介 From c755a62329061d3075c52b7799ff32200cf37e82 Mon Sep 17 00:00:00 2001 From: Markus Ebner Date: Thu, 29 Feb 2024 22:24:21 +0100 Subject: [PATCH 17/33] fix(esp_lcd): Flush rgb lcd PSRAM framebuffers after allocation Flush PSRAM framebuffers after allocation to avoid visual corruption. Merges https://github.com/espressif/esp-idf/pull/13294 Closes https://github.com/espressif/esp-idf/issues/13293 --- components/esp_lcd/rgb/esp_lcd_panel_rgb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c index 40110ca4a002..0502dbe16dd6 100644 --- a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c @@ -153,10 +153,14 @@ static esp_err_t lcd_rgb_panel_alloc_frame_buffers(const esp_lcd_rgb_panel_confi if (fb_in_psram) { // the low level malloc function will help check the validation of alignment rgb_panel->fbs[i] = heap_caps_aligned_calloc(psram_trans_align, 1, rgb_panel->fb_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + ESP_RETURN_ON_FALSE(rgb_panel->fbs[i], ESP_ERR_NO_MEM, TAG, "no mem for frame buffer"); + // calloc not only allocates but also zero's the buffer. We have to make sure this is + // properly committed to the PSRAM, otherwise all sorts of visual corruption will happen. + ESP_RETURN_ON_ERROR(esp_cache_msync(rgb_panel->fbs[i], rgb_panel->fb_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M), TAG, "cache write back failed"); } else { rgb_panel->fbs[i] = heap_caps_aligned_calloc(sram_trans_align, 1, rgb_panel->fb_size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + ESP_RETURN_ON_FALSE(rgb_panel->fbs[i], ESP_ERR_NO_MEM, TAG, "no mem for frame buffer"); } - ESP_RETURN_ON_FALSE(rgb_panel->fbs[i], ESP_ERR_NO_MEM, TAG, "no mem for frame buffer"); } } From 2b2b3be98f9e938aa286892add5f966653b3e639 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Thu, 29 Feb 2024 18:29:24 +0800 Subject: [PATCH 18/33] feat(temperature_sensor): Add new support for temperature sensor ETM on ESP32C6/H2 --- components/esp_driver_tsens/CMakeLists.txt | 3 + .../include/driver/temperature_sensor_etm.h | 64 +++++++++++++ .../esp_driver_tsens/src/temperature_sensor.c | 15 +-- .../src/temperature_sensor_etm.c | 96 +++++++++++++++++++ .../include/esp_private/etm_interface.h | 1 + .../include/hal/temperature_sensor_ll.h | 14 ++- .../include/hal/temperature_sensor_ll.h | 14 ++- .../include/hal/temperature_sensor_ll.h | 14 ++- .../include/hal/temperature_sensor_types.h | 19 +++- .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32c6/include/soc/soc_caps.h | 1 + .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32h2/include/soc/soc_caps.h | 1 + .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32p4/include/soc/soc_caps.h | 1 + 15 files changed, 244 insertions(+), 11 deletions(-) create mode 100644 components/esp_driver_tsens/include/driver/temperature_sensor_etm.h create mode 100644 components/esp_driver_tsens/src/temperature_sensor_etm.c diff --git a/components/esp_driver_tsens/CMakeLists.txt b/components/esp_driver_tsens/CMakeLists.txt index b202242c7ff3..be0e65609f1c 100644 --- a/components/esp_driver_tsens/CMakeLists.txt +++ b/components/esp_driver_tsens/CMakeLists.txt @@ -3,6 +3,9 @@ set(priv_req efuse) set(public_include "include") if(CONFIG_SOC_TEMP_SENSOR_SUPPORTED) list(APPEND srcs "src/temperature_sensor.c") + if(CONFIG_SOC_TEMPERATURE_SENSOR_SUPPORT_ETM) + list(APPEND srcs "src/temperature_sensor_etm.c") + endif() endif() idf_component_register(SRCS ${srcs} diff --git a/components/esp_driver_tsens/include/driver/temperature_sensor_etm.h b/components/esp_driver_tsens/include/driver/temperature_sensor_etm.h new file mode 100644 index 000000000000..3e030375d587 --- /dev/null +++ b/components/esp_driver_tsens/include/driver/temperature_sensor_etm.h @@ -0,0 +1,64 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" +#include "esp_etm.h" +#include "driver/temperature_sensor.h" +#include "hal/temperature_sensor_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Temperature Sensor ETM event configuration + */ +typedef struct { + temperature_sensor_etm_event_type_t event_type; /*!< Temperature Sensor ETM event type */ +} temperature_sensor_etm_event_config_t; + +/** + * @brief Get the ETM event for Temperature Sensor + * + * @note The created ETM event object can be deleted later by calling `esp_etm_del_event` + * + * @param[in] tsens Temperature Sensor handle, allocated by `temperature_sensor_install()` + * @param[in] config Temperature Sensor ETM event configuration + * @param[out] out_event Returned ETM event handle + * @return + * - ESP_OK: Get ETM event successfully + * - ESP_ERR_INVALID_ARG: Get ETM event failed because of invalid argument + * - ESP_FAIL: Get ETM event failed because of other error + */ +esp_err_t temperature_sensor_new_etm_event(temperature_sensor_handle_t tsens, const temperature_sensor_etm_event_config_t *config, esp_etm_event_handle_t *out_event); + +/** + * @brief Temperature Sensor ETM task configuration + */ +typedef struct { + temperature_sensor_etm_task_type_t task_type; /*!< Temperature Sensor ETM task type */ +} temperature_sensor_etm_task_config_t; + +/** + * @brief Get the ETM task for Temperature Sensor + * + * @note The created ETM event object can be deleted later by calling `esp_etm_del_event` + * + * @param[in] tsens Temperature Sensor, allocated by `temperature_sensor_install()` + * @param[in] config Temperature Sensor ETM event configuration + * @param[out] out_task Returned ETM event handle + * @return + * - ESP_OK: Get ETM event successfully + * - ESP_ERR_INVALID_ARG: Get ETM event failed because of invalid argument + * - ESP_FAIL: Get ETM event failed because of other error + */ +esp_err_t temperature_sensor_new_etm_task(temperature_sensor_handle_t tsens, const temperature_sensor_etm_task_config_t *config, esp_etm_task_handle_t *out_task); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_tsens/src/temperature_sensor.c b/components/esp_driver_tsens/src/temperature_sensor.c index 22faa43d7654..b8067bcc99d1 100644 --- a/components/esp_driver_tsens/src/temperature_sensor.c +++ b/components/esp_driver_tsens/src/temperature_sensor.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -106,6 +106,9 @@ esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_co ESP_GOTO_ON_FALSE(tsens != NULL, ESP_ERR_NO_MEM, err, TAG, "no mem for temp sensor"); tsens->clk_src = tsens_config->clk_src; + temperature_sensor_power_acquire(); + temperature_sensor_ll_clk_sel(tsens->clk_src); + ESP_GOTO_ON_ERROR(temperature_sensor_attribute_table_sort(), err, TAG, "Table sort failed"); ESP_GOTO_ON_ERROR(temperature_sensor_choose_best_range(tsens, tsens_config), err, TAG, "Cannot select the correct range"); @@ -140,6 +143,7 @@ esp_err_t temperature_sensor_uninstall(temperature_sensor_handle_t tsens) ESP_RETURN_ON_ERROR(esp_intr_free(tsens->temp_sensor_isr_handle), TAG, "uninstall interrupt service failed"); } #endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT + temperature_sensor_power_release(); free(tsens); return ESP_OK; @@ -175,8 +179,6 @@ esp_err_t temperature_sensor_enable(temperature_sensor_handle_t tsens) temperature_sensor_ll_sample_enable(true); #endif // SOC_TEMPERATURE_SENSOR_INTR_SUPPORT - temperature_sensor_ll_clk_sel(tsens->clk_src); - temperature_sensor_power_acquire(); // After enabling/reseting the temperature sensor, // the output value gradually approaches the true temperature // value as the measurement time increases. 300us is recommended. @@ -190,7 +192,6 @@ esp_err_t temperature_sensor_disable(temperature_sensor_handle_t tsens) ESP_RETURN_ON_FALSE(tsens, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "tsens not enabled yet"); - temperature_sensor_power_release(); #if SOC_TEMPERATURE_SENSOR_INTR_SUPPORT temperature_sensor_ll_wakeup_enable(false); temperature_sensor_ll_sample_enable(false); @@ -259,7 +260,7 @@ esp_err_t temperature_sensor_set_absolute_threshold(temperature_sensor_handle_t { esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed"); - ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state"); + ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in enable state"); ESP_RETURN_ON_FALSE(abs_cfg, ESP_ERR_INVALID_ARG, TAG, "Invalid callback configuration"); temperature_sensor_ll_set_sample_rate(0xffff); @@ -274,7 +275,7 @@ esp_err_t temperature_sensor_set_delta_threshold(temperature_sensor_handle_t tse { esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed"); - ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state"); + ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in enable state"); ESP_RETURN_ON_FALSE(delta_cfg, ESP_ERR_INVALID_ARG, TAG, "Invalid callback configuration"); temperature_sensor_ll_set_sample_rate(0xffff); @@ -289,7 +290,7 @@ esp_err_t temperature_sensor_register_callbacks(temperature_sensor_handle_t tsen { esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed"); - ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state"); + ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in enable state"); ESP_RETURN_ON_FALSE(cbs, ESP_ERR_INVALID_ARG, TAG, "callback group pointer is invalid"); #if CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE diff --git a/components/esp_driver_tsens/src/temperature_sensor_etm.c b/components/esp_driver_tsens/src/temperature_sensor_etm.c new file mode 100644 index 000000000000..b6059e509233 --- /dev/null +++ b/components/esp_driver_tsens/src/temperature_sensor_etm.c @@ -0,0 +1,96 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_etm.h" +#include "esp_check.h" +#include "esp_private/etm_interface.h" +#include "hal/temperature_sensor_ll.h" +#include "driver/temperature_sensor_etm.h" +#include "esp_heap_caps.h" +#if CONFIG_ETM_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif +#include "esp_log.h" + +#define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT + +static const char *TAG = "tsens-etm"; + +static esp_err_t temperature_sensor_del_etm_event(esp_etm_event_t *event) +{ + free(event); + return ESP_OK; +} + +static esp_err_t temperature_sensor_del_etm_task(esp_etm_task_t *task) +{ + free(task); + return ESP_OK; +} + +esp_err_t temperature_sensor_new_etm_event(temperature_sensor_handle_t tsens, const temperature_sensor_etm_event_config_t *config, esp_etm_event_handle_t *out_event) +{ +#if CONFIG_ETM_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif + esp_etm_event_t *event = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(tsens && config && out_event, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(config->event_type < TEMPERATURE_SENSOR_EVENT_MAX, ESP_ERR_INVALID_ARG, err, TAG, "invalid event type"); + event = heap_caps_calloc(1, sizeof(esp_etm_event_t), ETM_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(event, ESP_ERR_NO_MEM, err, TAG, "no memory for ETM event"); + + uint32_t event_id = TEMPERATURE_SENSOR_LL_ETM_EVENT_TABLE(config->event_type); + ESP_GOTO_ON_FALSE(event_id != 0, ESP_ERR_NOT_SUPPORTED, err, TAG, "not supported event type"); + + // fill the ETM event object + event->event_id = event_id; + event->trig_periph = ETM_TRIG_PERIPH_TSENS; + event->del = temperature_sensor_del_etm_event; + ESP_LOGD(TAG, "new event @%p, event_id=%"PRIu32, event, event_id); + *out_event = event; + return ESP_OK; + +err: + if (event) { + temperature_sensor_del_etm_event(event); + } + return ret; +} + +esp_err_t temperature_sensor_new_etm_task(temperature_sensor_handle_t tsens, const temperature_sensor_etm_task_config_t *config, esp_etm_task_handle_t *out_task) +{ +#if CONFIG_ETM_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif + esp_etm_task_t *task = NULL; + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(tsens && config && out_task, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + ESP_GOTO_ON_FALSE(config->task_type < TEMPERATURE_SENSOR_TASK_MAX, ESP_ERR_INVALID_ARG, err, TAG, "invalid task type"); + task = heap_caps_calloc(1, sizeof(esp_etm_task_t), ETM_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(task, ESP_ERR_NO_MEM, err, TAG, "no memory for ETM task"); + + uint32_t task_id = TEMPERATURE_SENSOR_LL_ETM_TASK_TABLE(config->task_type); + ESP_GOTO_ON_FALSE(task_id != 0, ESP_ERR_NOT_SUPPORTED, err, TAG, "not supported task type"); + + // fill the ETM task object + task->task_id = task_id; + task->trig_periph = ETM_TRIG_PERIPH_TSENS; + task->del = temperature_sensor_del_etm_task; + ESP_LOGD(TAG, "new task @%p, task_id=%"PRIu32, task, task_id); + *out_task = task; + return ESP_OK; + +err: + if (task) { + temperature_sensor_del_etm_task(task); + } + return ret; +} diff --git a/components/esp_hw_support/include/esp_private/etm_interface.h b/components/esp_hw_support/include/esp_private/etm_interface.h index a7c7e4253886..04c02964f92c 100644 --- a/components/esp_hw_support/include/esp_private/etm_interface.h +++ b/components/esp_hw_support/include/esp_private/etm_interface.h @@ -26,6 +26,7 @@ typedef enum { ETM_TRIG_PERIPH_SYSTIMER, /*!< ETM trigger source: Systimer */ ETM_TRIG_PERIPH_MCPWM, /*!< ETM trigger source: MCPWM */ ETM_TRIG_PERIPH_ANA_CMPR, /*!< ETM trigger source: Analog Comparator */ + ETM_TRIG_PERIPH_TSENS, /*!< ETM trigger source: Temperature Sensor */ } etm_trigger_peripheral_t; /** diff --git a/components/hal/esp32c6/include/hal/temperature_sensor_ll.h b/components/hal/esp32c6/include/hal/temperature_sensor_ll.h index 17ac106e08ba..4c73df1a1fa7 100644 --- a/components/hal/esp32c6/include/hal/temperature_sensor_ll.h +++ b/components/hal/esp32c6/include/hal/temperature_sensor_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,6 +25,7 @@ #include "soc/soc_caps.h" #include "soc/pcr_struct.h" #include "soc/interrupts.h" +#include "soc/soc_etm_source.h" #include "hal/temperature_sensor_types.h" #include "hal/assert.h" #include "hal/misc.h" @@ -41,6 +42,17 @@ extern "C" { #define TEMPERATURE_SENSOR_LL_INTR_MASK APB_SARADC_APB_SARADC_TSENS_INT_ST +#define TEMPERATURE_SENSOR_LL_ETM_EVENT_TABLE(event) \ + (uint32_t [TEMPERATURE_SENSOR_EVENT_MAX]){ \ + [TEMPERATURE_SENSOR_EVENT_OVER_LIMIT] = TMPSNSR_EVT_OVER_LIMIT, \ + }[event] + +#define TEMPERATURE_SENSOR_LL_ETM_TASK_TABLE(task) \ + (uint32_t [TEMPERATURE_SENSOR_TASK_MAX]){ \ + [TEMPERATURE_SENSOR_TASK_START] = TMPSNSR_TASK_START_SAMPLE, \ + [TEMPERATURE_SENSOR_TASK_STOP] = TMPSNSR_TASK_STOP_SAMPLE, \ + }[task] + typedef enum { TEMPERATURE_SENSOR_LL_WAKE_ABSOLUTE = 0, TEMPERATURE_SENSOR_LL_WAKE_DELTA = 1, diff --git a/components/hal/esp32h2/include/hal/temperature_sensor_ll.h b/components/hal/esp32h2/include/hal/temperature_sensor_ll.h index 6007f05c5114..71e9d8750729 100644 --- a/components/hal/esp32h2/include/hal/temperature_sensor_ll.h +++ b/components/hal/esp32h2/include/hal/temperature_sensor_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,7 @@ #include "soc/soc_caps.h" #include "soc/pcr_struct.h" #include "soc/interrupts.h" +#include "soc/soc_etm_source.h" #include "hal/temperature_sensor_types.h" #include "hal/assert.h" #include "hal/misc.h" @@ -40,6 +41,17 @@ extern "C" { #define TEMPERATURE_SENSOR_LL_INTR_MASK APB_SARADC_APB_SARADC_TSENS_INT_ST +#define TEMPERATURE_SENSOR_LL_ETM_EVENT_TABLE(event) \ + (uint32_t [TEMPERATURE_SENSOR_EVENT_MAX]){ \ + [TEMPERATURE_SENSOR_EVENT_OVER_LIMIT] = TMPSNSR_EVT_OVER_LIMIT, \ + }[event] + +#define TEMPERATURE_SENSOR_LL_ETM_TASK_TABLE(task) \ + (uint32_t [TEMPERATURE_SENSOR_TASK_MAX]){ \ + [TEMPERATURE_SENSOR_TASK_START] = TMPSNSR_TASK_START_SAMPLE, \ + [TEMPERATURE_SENSOR_TASK_STOP] = TMPSNSR_TASK_STOP_SAMPLE, \ + }[task] + typedef enum { TEMPERATURE_SENSOR_LL_WAKE_ABSOLUTE = 0, TEMPERATURE_SENSOR_LL_WAKE_DELTA = 1, diff --git a/components/hal/esp32p4/include/hal/temperature_sensor_ll.h b/components/hal/esp32p4/include/hal/temperature_sensor_ll.h index 637bcb697c00..72c76d227327 100644 --- a/components/hal/esp32p4/include/hal/temperature_sensor_ll.h +++ b/components/hal/esp32p4/include/hal/temperature_sensor_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,7 @@ #include "soc/soc.h" #include "soc/soc_caps.h" #include "soc/interrupts.h" +#include "soc/soc_etm_source.h" #include "hal/temperature_sensor_types.h" #include "hal/assert.h" #include "hal/misc.h" @@ -40,6 +41,17 @@ extern "C" { #define TEMPERATURE_SENSOR_LL_INTR_MASK TSENS_COCPU_TSENS_WAKE_INT_ST +#define TEMPERATURE_SENSOR_LL_ETM_EVENT_TABLE(event) \ + (uint32_t [TEMPERATURE_SENSOR_EVENT_MAX]){ \ + [TEMPERATURE_SENSOR_EVENT_OVER_LIMIT] = TMPSNSR_EVT_OVER_LIMIT, \ + }[event] + +#define TEMPERATURE_SENSOR_LL_ETM_TASK_TABLE(task) \ + (uint32_t [TEMPERATURE_SENSOR_TASK_MAX]){ \ + [TEMPERATURE_SENSOR_TASK_START] = TMPSNSR_TASK_START_SAMPLE, \ + [TEMPERATURE_SENSOR_TASK_STOP] = TMPSNSR_TASK_STOP_SAMPLE, \ + }[task] + typedef enum { TEMPERATURE_SENSOR_LL_WAKE_ABSOLUTE = 0, TEMPERATURE_SENSOR_LL_WAKE_DELTA = 1, diff --git a/components/hal/include/hal/temperature_sensor_types.h b/components/hal/include/hal/temperature_sensor_types.h index 0ffc0e4af8ef..886e36d6e44e 100644 --- a/components/hal/include/hal/temperature_sensor_types.h +++ b/components/hal/include/hal/temperature_sensor_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,23 @@ typedef soc_periph_temperature_sensor_clk_src_t temperature_sensor_clk_src_t; typedef int temperature_sensor_clk_src_t; #endif // SOC_TEMP_SENSOR_SUPPORTED +/** + * @brief temperature sensor event types enum + */ +typedef enum { + TEMPERATURE_SENSOR_EVENT_OVER_LIMIT, /*!< Temperature sensor over limit event */ + TEMPERATURE_SENSOR_EVENT_MAX, /*!< Maximum number of temperature sensor events */ +} temperature_sensor_etm_event_type_t; + +/** + * @brief temperature sensor task types enum + */ +typedef enum { + TEMPERATURE_SENSOR_TASK_START, /*!< Temperature sensor start task */ + TEMPERATURE_SENSOR_TASK_STOP, /*!< Temperature sensor stop task */ + TEMPERATURE_SENSOR_TASK_MAX, /*!< Maximum number of temperature sensor tasks */ +} temperature_sensor_etm_task_type_t; + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 79b2b3b9c6b0..6899fc934004 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1331,6 +1331,10 @@ config SOC_TEMPERATURE_SENSOR_INTR_SUPPORT bool default y +config SOC_TEMPERATURE_SENSOR_SUPPORT_ETM + bool + default y + config SOC_WIFI_HW_TSF bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index c4f060e2211d..0158d91037c1 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -535,6 +535,7 @@ #define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1) #define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1) #define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1) +#define SOC_TEMPERATURE_SENSOR_SUPPORT_ETM (1) /*------------------------------------ WI-FI CAPS ------------------------------------*/ #define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */ diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 385bd0abde50..c8014abbff99 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1299,6 +1299,10 @@ config SOC_TEMPERATURE_SENSOR_INTR_SUPPORT bool default y +config SOC_TEMPERATURE_SENSOR_SUPPORT_ETM + bool + default y + config SOC_BLE_SUPPORTED bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index d024c53146e1..122a2d4eb97e 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -515,6 +515,7 @@ #define SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC (1) #define SOC_TEMPERATURE_SENSOR_SUPPORT_XTAL (1) #define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1) +#define SOC_TEMPERATURE_SENSOR_SUPPORT_ETM (1) /*---------------------------------- Bluetooth CAPS ----------------------------------*/ #define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */ diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 05ff6fcc614d..bc480533e25d 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1399,6 +1399,10 @@ config SOC_TSENS_IS_INDEPENDENT_FROM_ADC bool default y +config SOC_TEMPERATURE_SENSOR_SUPPORT_ETM + bool + default y + config SOC_MEM_TCM_SUPPORTED bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index cc30c7b77c2b..74e5871d74b5 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -591,6 +591,7 @@ #define SOC_TEMPERATURE_SENSOR_LP_PLL_SUPPORT (1) #define SOC_TEMPERATURE_SENSOR_INTR_SUPPORT (1) #define SOC_TSENS_IS_INDEPENDENT_FROM_ADC (1) /*!< Temperature sensor is a separate module, not share regs with ADC */ +#define SOC_TEMPERATURE_SENSOR_SUPPORT_ETM (1) /*-------------------------- Memory CAPS --------------------------*/ #define SOC_MEM_TCM_SUPPORTED (1) From c6be2584a7c538be866d379dac7779bf94d71dd6 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Thu, 29 Feb 2024 18:30:51 +0800 Subject: [PATCH 19/33] test(temperature_sensor): Add new test for temperature sensor ETM on ESP32C6/H2 --- .../temperature_sensor/main/CMakeLists.txt | 6 +- .../main/test_temperature_etm.c | 87 +++++++++++++++++++ .../main/test_temperature_sensor.c | 2 +- 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_etm.c diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/main/CMakeLists.txt b/components/esp_driver_tsens/test_apps/temperature_sensor/main/CMakeLists.txt index e250ba0ae4bd..5d45e0615adc 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/main/CMakeLists.txt +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/main/CMakeLists.txt @@ -2,8 +2,12 @@ set(srcs "test_app_main.c" "test_temperature_sensor.c" "test_temperature_phy.c") +if(CONFIG_SOC_TEMPERATURE_SENSOR_SUPPORT_ETM) + list(APPEND srcs "test_temperature_etm.c") +endif() + # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity esp_wifi test_utils nvs_flash esp_driver_tsens + PRIV_REQUIRES unity esp_wifi test_utils nvs_flash esp_driver_tsens esp_driver_gpio WHOLE_ARCHIVE) diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_etm.c b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_etm.c new file mode 100644 index 000000000000..e9eb171932a7 --- /dev/null +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_etm.c @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "unity.h" +#include "unity_test_utils.h" +#include "esp_attr.h" +#include "driver/gpio_etm.h" +#include "driver/gpio.h" +#include "driver/temperature_sensor_etm.h" +#include "driver/temperature_sensor.h" +#include "soc/soc_etm_struct.h" + +TEST_CASE("temperature sensor alarm cause gpio pull up", "[etm]") +{ + const uint32_t output_gpio = 5; + // temperature sensor alarm ---> ETM channel A ---> GPIO toggle + printf("allocate etm channel\r\n"); + esp_etm_channel_config_t etm_config = {}; + esp_etm_channel_handle_t etm_channel_a; + TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_a)); + + printf("allocate GPIO etm task\r\n"); + esp_etm_task_handle_t gpio_task = NULL; + gpio_etm_task_config_t gpio_task_config = { + .action = GPIO_ETM_TASK_ACTION_TOG, + }; + TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config, &gpio_task)); + // set gpio number for the gpio etm primitives + TEST_ESP_OK(gpio_etm_task_add_gpio(gpio_task, output_gpio)); + + printf("initialize gpio\r\n"); + gpio_set_level(output_gpio, 0); + gpio_config_t task_gpio_config = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = 1ULL << output_gpio, + }; + TEST_ESP_OK(gpio_config(&task_gpio_config)); + + float tsens_out; + temperature_sensor_config_t temp_sensor = TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50); + temperature_sensor_handle_t temp_handle = NULL; + TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle)); + TEST_ESP_OK(temperature_sensor_enable(temp_handle)); + + temperature_sensor_abs_threshold_config_t threshold_cfg = { + .high_threshold = 50, + .low_threshold = -10, + }; + TEST_ESP_OK(temperature_sensor_set_absolute_threshold(temp_handle, &threshold_cfg)); + printf("Temperature sensor started\n"); + + temperature_sensor_etm_event_config_t tsens_etm_event = { + .event_type = TEMPERATURE_SENSOR_EVENT_OVER_LIMIT, + }; + + esp_etm_event_handle_t tsens_evt; + + TEST_ESP_OK(temperature_sensor_new_etm_event(temp_handle, &tsens_etm_event, &tsens_evt)); + + printf("connect event and task to the channel\r\n"); + TEST_ESP_OK(esp_etm_channel_connect(etm_channel_a, tsens_evt, gpio_task)); + + printf("enable etm channel\r\n"); + TEST_ESP_OK(esp_etm_channel_enable(etm_channel_a)); + + uint32_t cnt = 20; + while (cnt--) { + TEST_ESP_OK(temperature_sensor_get_celsius(temp_handle, &tsens_out)); + printf("Temperature out celsius %f°C\n", tsens_out); + vTaskDelay(100); + } + + TEST_ESP_OK(temperature_sensor_disable(temp_handle)); + TEST_ESP_OK(temperature_sensor_uninstall(temp_handle)); + // delete etm primitives + TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task, output_gpio)); + TEST_ESP_OK(esp_etm_del_task(gpio_task)); + TEST_ESP_OK(esp_etm_del_event(tsens_evt)); + TEST_ESP_OK(esp_etm_channel_disable(etm_channel_a)); + TEST_ESP_OK(esp_etm_del_channel(etm_channel_a)); +} diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.c b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.c index 6bc7fe4e86ea..37c1b7e81a8a 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.c +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.c @@ -110,6 +110,7 @@ TEST_CASE("Temperature sensor callback test", "[temperature_sensor]") temperature_sensor_config_t temp_sensor = TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50); temperature_sensor_handle_t temp_handle = NULL; TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle)); + TEST_ESP_OK(temperature_sensor_enable(temp_handle)); temperature_sensor_event_callbacks_t cbs = { .on_threshold = temp_sensor_cbs_test, @@ -124,7 +125,6 @@ TEST_CASE("Temperature sensor callback test", "[temperature_sensor]") TEST_ESP_OK(temperature_sensor_set_absolute_threshold(temp_handle, &threshold_cfg)); temperature_sensor_register_callbacks(temp_handle, &cbs, &temperature_alarm); - TEST_ESP_OK(temperature_sensor_enable(temp_handle)); #if CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE printf("disable flash cache and check if we can still get temperature intr\r\n"); for (int i = 0; i < 100; i++) { From c21cdf0a1f13bb8c3ce9479557b8461c9ec66850 Mon Sep 17 00:00:00 2001 From: Marek Fiala Date: Fri, 23 Feb 2024 17:17:47 +0100 Subject: [PATCH 20/33] feat(tools): produce correct err code in export/install .bat scripts Plus unify labels to begin with underscore --- export.bat | 23 +++++++++++++++++++---- install.bat | 45 ++++++++++++++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/export.bat b/export.bat index 8210b40c5ddd..c37c6060d047 100644 --- a/export.bat +++ b/export.bat @@ -4,12 +4,20 @@ if defined MSYSTEM ( goto :eof ) +set SCRIPT_EXIT_CODE=0 + :: Missing requirements check set MISSING_REQUIREMENTS= python.exe --version >NUL 2>NUL -if %errorlevel% neq 0 set "MISSING_REQUIREMENTS= python &echo\" +if %errorlevel% neq 0 ( + set SCRIPT_EXIT_CODE=%errorlevel% + set "MISSING_REQUIREMENTS= python &echo\" +) git.exe --version >NUL 2>NUL -if %errorlevel% neq 0 set "MISSING_REQUIREMENTS=%MISSING_REQUIREMENTS% git" +if %errorlevel% neq 0 ( + set SCRIPT_EXIT_CODE=%errorlevel% + set "MISSING_REQUIREMENTS=%MISSING_REQUIREMENTS% git" +) if not "%MISSING_REQUIREMENTS%" == "" goto :__error_missing_requirements @@ -34,7 +42,10 @@ echo Adding ESP-IDF tools to PATH... :: but that way it is impossible to get the exit code of idf_tools.py. set "IDF_TOOLS_EXPORTS_FILE=%TEMP%\idf_export_vars.tmp" python.exe "%IDF_PATH%\tools\idf_tools.py" export --format key-value >"%IDF_TOOLS_EXPORTS_FILE%" -if %errorlevel% neq 0 goto :__end +if %errorlevel% neq 0 ( + set SCRIPT_EXIT_CODE=%errorlevel% + goto :__end +) for /f "usebackq tokens=1,2 eol=# delims==" %%a in ("%IDF_TOOLS_EXPORTS_FILE%") do ( call set "%%a=%%b" @@ -55,7 +66,10 @@ DOSKEY parttool.py=python.exe "%IDF_PATH%\components\partition_table\parttool.py echo Checking if Python packages are up to date... python.exe "%IDF_PATH%\tools\idf_tools.py" check-python-dependencies -if %errorlevel% neq 0 goto :__end +if %errorlevel% neq 0 ( + set SCRIPT_EXIT_CODE=%errorlevel% + goto :__end +) python.exe "%IDF_PATH%\tools\idf_tools.py" uninstall --dry-run > UNINSTALL_OUTPUT SET /p UNINSTALL=NUL 2>NUL -if %errorlevel% neq 0 set "MISSING_REQUIREMENTS= python &echo\" +if %errorlevel% neq 0 ( + set SCRIPT_EXIT_CODE=%errorlevel% + set "MISSING_REQUIREMENTS= python &echo\" +) git.exe --version >NUL 2>NUL -if %errorlevel% neq 0 set "MISSING_REQUIREMENTS=%MISSING_REQUIREMENTS% git" +if %errorlevel% neq 0 ( + set SCRIPT_EXIT_CODE=%errorlevel% + set "MISSING_REQUIREMENTS=%MISSING_REQUIREMENTS% git" +) -if not "%MISSING_REQUIREMENTS%" == "" goto :error_missing_requirements +if not "%MISSING_REQUIREMENTS%" == "" goto :__error_missing_requirements :: Infer IDF_PATH from script location set IDF_PATH=%~dp0 set IDF_PATH=%IDF_PATH:~0,-1% :: Print help if requested -if /I "%1" == "/?" goto :help -if /I "%1" == "-h" goto :help -if /I "%1" == "--help" goto :help +if /I "%1" == "/?" goto :__help +if /I "%1" == "-h" goto :__help +if /I "%1" == "--help" goto :__help for /f "delims=" %%i in ('python.exe "%IDF_PATH%\tools\install_util.py" extract targets "%*"') do set TARGETS=%%i echo Installing ESP-IDF tools python.exe "%IDF_PATH%\tools\idf_tools.py" install --targets=%TARGETS% -if %errorlevel% neq 0 goto :end +if %errorlevel% neq 0 ( + set SCRIPT_EXIT_CODE=%errorlevel% + goto :__end +) for /f "delims=" %%i in ('python.exe "%IDF_PATH%\tools\install_util.py" extract features "%*"') do set FEATURES=%%i echo Setting up Python environment python.exe "%IDF_PATH%\tools\idf_tools.py" install-python-env --features=%FEATURES% -if %errorlevel% neq 0 goto :end +if %errorlevel% neq 0 ( + set SCRIPT_EXIT_CODE=%errorlevel% + goto :__end +) echo All done! You can now run: echo export.bat -goto :end +goto :__end -:error_missing_requirements +:__error_missing_requirements echo. echo Error^: The following tools are not installed in your environment. echo. @@ -47,10 +61,11 @@ goto :end echo Please use the Windows Tool installer for setting up your environment. echo Download link: https://dl.espressif.com/dl/esp-idf/ echo For more details please visit our website: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/windows-setup.html - goto :end + goto :__end -:help +:__help python.exe "%IDF_PATH%\tools\install_util.py" print_help bat - goto :end + goto :__end -:end +:__end +exit /b %SCRIPT_EXIT_CODE% From ee02b71f1c1c0eb42667832bbaafa5ffeee85b6e Mon Sep 17 00:00:00 2001 From: wanlei Date: Mon, 26 Feb 2024 11:29:46 +0800 Subject: [PATCH 21/33] feat(esp32c61): introduce target esp32c61 --- Kconfig | 8 +++++++ .../src/bootloader_flash_config_esp32c61.c | 0 components/bt/controller/esp32c61/Kconfig.in | 0 components/esp_adc/esp32c61/include/.gitkeep | 0 components/esp_driver_uart/CMakeLists.txt | 23 ++++++++++--------- .../esp_hw_support/include/esp_chip_info.h | 1 + .../include/soc/esp32c61/.gitkeep | 0 .../port/esp32c61/CMakeLists.txt | 0 .../port/esp32c61/cpu_region_protect.c | 0 .../port/esp32c61/esp_clk_tree.c | 0 .../esp_hw_support/port/esp32c61/io_mux.c | 0 .../esp_mm/port/esp32c61/ext_mem_layout.c | 0 components/esp_phy/esp32c61/include/.gitkeep | 0 components/esp_rom/esp32c61/.gitkeep | 0 components/esp_rom/include/esp32c61/.gitkeep | 0 .../esp_system/ld/esp32c61/memory.ld.in | 0 .../esp_system/ld/esp32c61/sections.ld.in | 0 .../port/soc/esp32c61/CMakeLists.txt | 0 .../esp_system/port/soc/esp32c61/Kconfig.cpu | 0 .../port/soc/esp32c61/Kconfig.system | 0 components/hal/esp32c61/include/.gitkeep | 0 components/heap/port/esp32c61/memory_layout.c | 0 components/idf_test/include/esp32c61/.gitkeep | 0 components/soc/esp32c61/gpio_periph.c | 0 components/soc/esp32c61/interrupts.c | 0 components/soc/esp32c61/uart_periph.c | 0 tools/ci/check_build_test_rules.py | 2 ++ tools/cmake/dfu.cmake | 2 ++ tools/cmake/toolchain-esp32c61.cmake | 18 +++++++++++++++ tools/idf_py_actions/constants.py | 7 +++--- tools/tools.json | 9 +++++--- 31 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c61.c create mode 100644 components/bt/controller/esp32c61/Kconfig.in create mode 100644 components/esp_adc/esp32c61/include/.gitkeep create mode 100644 components/esp_hw_support/include/soc/esp32c61/.gitkeep create mode 100644 components/esp_hw_support/port/esp32c61/CMakeLists.txt create mode 100644 components/esp_hw_support/port/esp32c61/cpu_region_protect.c create mode 100644 components/esp_hw_support/port/esp32c61/esp_clk_tree.c create mode 100644 components/esp_hw_support/port/esp32c61/io_mux.c create mode 100644 components/esp_mm/port/esp32c61/ext_mem_layout.c create mode 100644 components/esp_phy/esp32c61/include/.gitkeep create mode 100644 components/esp_rom/esp32c61/.gitkeep create mode 100644 components/esp_rom/include/esp32c61/.gitkeep create mode 100644 components/esp_system/ld/esp32c61/memory.ld.in create mode 100644 components/esp_system/ld/esp32c61/sections.ld.in create mode 100644 components/esp_system/port/soc/esp32c61/CMakeLists.txt create mode 100644 components/esp_system/port/soc/esp32c61/Kconfig.cpu create mode 100644 components/esp_system/port/soc/esp32c61/Kconfig.system create mode 100644 components/hal/esp32c61/include/.gitkeep create mode 100644 components/heap/port/esp32c61/memory_layout.c create mode 100644 components/idf_test/include/esp32c61/.gitkeep create mode 100644 components/soc/esp32c61/gpio_periph.c create mode 100644 components/soc/esp32c61/interrupts.c create mode 100644 components/soc/esp32c61/uart_periph.c create mode 100644 tools/cmake/toolchain-esp32c61.cmake diff --git a/Kconfig b/Kconfig index 1c6b973c4475..fe4e12f86374 100644 --- a/Kconfig +++ b/Kconfig @@ -151,6 +151,13 @@ mainmenu "Espressif IoT Development Framework Configuration" select FREERTOS_UNICORE select IDF_TARGET_ARCH_RISCV + config IDF_TARGET_ESP32C61 + bool + default "y" if IDF_TARGET="esp32c61" + select FREERTOS_UNICORE + select IDF_TARGET_ARCH_RISCV + select IDF_ENV_FPGA + config IDF_TARGET_LINUX bool default "y" if IDF_TARGET="linux" @@ -167,6 +174,7 @@ mainmenu "Espressif IoT Development Framework Configuration" default 0x0012 if IDF_TARGET_ESP32P4 default 0x0011 if IDF_TARGET_ESP32C5 && IDF_TARGET_ESP32C5_BETA3_VERSION # TODO: IDF-9197 default 0x0017 if IDF_TARGET_ESP32C5 && IDF_TARGET_ESP32C5_MP_VERSION # TODO: IDF-9197 + default 0x0014 if IDF_TARGET_ESP32C61 default 0xFFFF diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c61.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c61.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/bt/controller/esp32c61/Kconfig.in b/components/bt/controller/esp32c61/Kconfig.in new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_adc/esp32c61/include/.gitkeep b/components/esp_adc/esp32c61/include/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_driver_uart/CMakeLists.txt b/components/esp_driver_uart/CMakeLists.txt index e6046edd67a0..c489cab2863d 100644 --- a/components/esp_driver_uart/CMakeLists.txt +++ b/components/esp_driver_uart/CMakeLists.txt @@ -4,16 +4,17 @@ if(CONFIG_SOC_UART_SUPPORTED) list(APPEND srcs "src/uart.c") endif() -idf_component_register(SRCS ${srcs} - INCLUDE_DIRS ${public_include} - PRIV_REQUIRES esp_pm esp_driver_gpio esp_ringbuf - LDFRAGMENTS "linker.lf" - ) +idf_component_register( + SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES esp_pm esp_driver_gpio esp_ringbuf + LDFRAGMENTS "linker.lf" +) -if(CONFIG_VFS_SUPPORT_IO) - target_link_libraries(${COMPONENT_LIB} PUBLIC idf::vfs) - target_sources(${COMPONENT_LIB} PRIVATE "src/uart_vfs.c") - if(CONFIG_ESP_CONSOLE_UART) - target_link_libraries(${COMPONENT_LIB} INTERFACE "-u uart_vfs_include_dev_init") - endif() +if(CONFIG_VFS_SUPPORT_IO AND CONFIG_SOC_UART_SUPPORTED) + target_link_libraries(${COMPONENT_LIB} PUBLIC idf::vfs) + target_sources(${COMPONENT_LIB} PRIVATE "src/uart_vfs.c") + if(CONFIG_ESP_CONSOLE_UART) + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u uart_vfs_include_dev_init") + endif() endif() diff --git a/components/esp_hw_support/include/esp_chip_info.h b/components/esp_hw_support/include/esp_chip_info.h index afe1d811e830..ec5cb68d0436 100644 --- a/components/esp_hw_support/include/esp_chip_info.h +++ b/components/esp_hw_support/include/esp_chip_info.h @@ -33,6 +33,7 @@ typedef enum { CHIP_ESP32C5 = 23, //!< ESP32-C5 MP #endif CHIP_ESP32P4 = 18, //!< ESP32-P4 + CHIP_ESP32C61= 20, //!< ESP32-C61 CHIP_POSIX_LINUX = 999, //!< The code is running on POSIX/Linux simulator } esp_chip_model_t; diff --git a/components/esp_hw_support/include/soc/esp32c61/.gitkeep b/components/esp_hw_support/include/soc/esp32c61/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_hw_support/port/esp32c61/CMakeLists.txt b/components/esp_hw_support/port/esp32c61/CMakeLists.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_hw_support/port/esp32c61/cpu_region_protect.c b/components/esp_hw_support/port/esp32c61/cpu_region_protect.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_hw_support/port/esp32c61/esp_clk_tree.c b/components/esp_hw_support/port/esp32c61/esp_clk_tree.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_hw_support/port/esp32c61/io_mux.c b/components/esp_hw_support/port/esp32c61/io_mux.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_mm/port/esp32c61/ext_mem_layout.c b/components/esp_mm/port/esp32c61/ext_mem_layout.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_phy/esp32c61/include/.gitkeep b/components/esp_phy/esp32c61/include/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_rom/esp32c61/.gitkeep b/components/esp_rom/esp32c61/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_rom/include/esp32c61/.gitkeep b/components/esp_rom/include/esp32c61/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_system/ld/esp32c61/memory.ld.in b/components/esp_system/ld/esp32c61/memory.ld.in new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_system/ld/esp32c61/sections.ld.in b/components/esp_system/ld/esp32c61/sections.ld.in new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_system/port/soc/esp32c61/CMakeLists.txt b/components/esp_system/port/soc/esp32c61/CMakeLists.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_system/port/soc/esp32c61/Kconfig.cpu b/components/esp_system/port/soc/esp32c61/Kconfig.cpu new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/esp_system/port/soc/esp32c61/Kconfig.system b/components/esp_system/port/soc/esp32c61/Kconfig.system new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/hal/esp32c61/include/.gitkeep b/components/hal/esp32c61/include/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/heap/port/esp32c61/memory_layout.c b/components/heap/port/esp32c61/memory_layout.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/idf_test/include/esp32c61/.gitkeep b/components/idf_test/include/esp32c61/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/soc/esp32c61/gpio_periph.c b/components/soc/esp32c61/gpio_periph.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/soc/esp32c61/interrupts.c b/components/soc/esp32c61/interrupts.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/components/soc/esp32c61/uart_periph.c b/components/soc/esp32c61/uart_periph.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/ci/check_build_test_rules.py b/tools/ci/check_build_test_rules.py index 4c3b6b4ae56a..e2fff3bcda88 100755 --- a/tools/ci/check_build_test_rules.py +++ b/tools/ci/check_build_test_rules.py @@ -35,6 +35,7 @@ 'esp32c5': 'ESP32-C5', 'esp32h2': 'ESP32-H2', 'esp32p4': 'ESP32-P4', + 'esp32c61': 'ESP32-C61', 'linux': 'Linux', } @@ -48,6 +49,7 @@ 'ESP32-C5': 'esp32c5', 'ESP32-H2': 'esp32h2', 'ESP32-P4': 'esp32p4', + 'ESP32-C61': 'esp32c61', 'Linux': 'linux', } diff --git a/tools/cmake/dfu.cmake b/tools/cmake/dfu.cmake index 4f58cd283d19..3c77d1cd51b9 100644 --- a/tools/cmake/dfu.cmake +++ b/tools/cmake/dfu.cmake @@ -15,6 +15,8 @@ function(__add_dfu_targets) return() elseif("${target}" STREQUAL "esp32c6") return() + elseif("${target}" STREQUAL "esp32c61") + return() elseif("${target}" STREQUAL "esp32c5") return() elseif("${target}" STREQUAL "esp32h2") diff --git a/tools/cmake/toolchain-esp32c61.cmake b/tools/cmake/toolchain-esp32c61.cmake new file mode 100644 index 000000000000..6415daa59b74 --- /dev/null +++ b/tools/cmake/toolchain-esp32c61.cmake @@ -0,0 +1,18 @@ +include($ENV{IDF_PATH}/tools/cmake/utilities.cmake) + +set(CMAKE_SYSTEM_NAME Generic) + +set(CMAKE_C_COMPILER riscv32-esp-elf-gcc) +set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++) +set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc) +set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-) + +remove_duplicated_flags("-march=rv32imac_zicsr_zifencei ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) +set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE) +remove_duplicated_flags("-march=rv32imac_zicsr_zifencei ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) +set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE) + +remove_duplicated_flags("-nostartfiles -march=rv32imac_zicsr_zifencei --specs=nosys.specs \ + ${CMAKE_EXE_LINKER_FLAGS}" + UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS) +set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE) diff --git a/tools/idf_py_actions/constants.py b/tools/idf_py_actions/constants.py index 6a7835835e7d..a22fb17a7c47 100644 --- a/tools/idf_py_actions/constants.py +++ b/tools/idf_py_actions/constants.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import collections import multiprocessing import os import platform -from typing import Dict, Union +from typing import Dict +from typing import Union GENERATORS: Dict[str, Union[str, Dict, list]] = collections.OrderedDict([ # - command: build command line @@ -33,7 +34,7 @@ URL_TO_DOC = 'https://docs.espressif.com/projects/esp-idf' SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2'] -PREVIEW_TARGETS = ['linux', 'esp32p4', 'esp32c5'] +PREVIEW_TARGETS = ['linux', 'esp32p4', 'esp32c5', 'esp32c61'] OPENOCD_TAGET_CONFIG_DEFAULT = '-f interface/ftdi/esp32_devkitj_v1.cfg -f target/{target}.cfg' OPENOCD_TAGET_CONFIG: Dict[str, str] = { diff --git a/tools/tools.json b/tools/tools.json index a1e844dfe13c..7fe241bca034 100644 --- a/tools/tools.json +++ b/tools/tools.json @@ -94,7 +94,8 @@ "esp32c6", "esp32c5", "esp32h2", - "esp32p4" + "esp32p4", + "esp32c61" ], "version_cmd": [ "riscv32-esp-elf-gdb-no-python", @@ -249,7 +250,8 @@ "esp32c2", "esp32c6", "esp32c5", - "esp32h2" + "esp32h2", + "esp32c61" ], "version_cmd": [ "clang", @@ -314,7 +316,8 @@ "esp32c2", "esp32c6", "esp32c5", - "esp32h2" + "esp32h2", + "esp32c61" ], "version_cmd": [ "riscv32-esp-elf-gcc", From edf49a92b7452016de203c169ac75a548e0fa496 Mon Sep 17 00:00:00 2001 From: Ondrej Kosta Date: Fri, 1 Mar 2024 16:51:53 +0100 Subject: [PATCH 22/33] fix(esp_eth): Removed -Wno-format in esp_eth component --- components/esp_eth/CMakeLists.txt | 3 -- components/esp_eth/src/esp_eth_mac_dm9051.c | 13 +++++---- components/esp_eth/src/esp_eth_mac_esp.c | 13 +++++---- .../esp_eth/src/esp_eth_mac_ksz8851snl.c | 29 ++++++++++--------- components/esp_eth/src/esp_eth_mac_w5500.c | 17 ++++++----- components/esp_eth/src/esp_eth_netif_glue.c | 13 +++++---- components/esp_eth/src/esp_eth_phy_ip101.c | 2 ++ components/esp_eth/src/esp_eth_phy_ksz80xx.c | 7 +++-- .../esp_eth/src/esp_eth_phy_ksz8851snl.c | 2 +- 9 files changed, 52 insertions(+), 47 deletions(-) diff --git a/components/esp_eth/CMakeLists.txt b/components/esp_eth/CMakeLists.txt index 3756598cda00..071cb776d808 100644 --- a/components/esp_eth/CMakeLists.txt +++ b/components/esp_eth/CMakeLists.txt @@ -63,9 +63,6 @@ idf_component_register(SRCS "${srcs}" LDFRAGMENTS ${ld_fragments} REQUIRES esp_event # For using "ESP_EVENT_DECLARE_BASE" in header file PRIV_REQUIRES ${priv_requires}) -if(CONFIG_ETH_ENABLED) - target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") -endif() if(CONFIG_ETH_ENABLED) if(CONFIG_ETH_USE_SPI_ETHERNET) diff --git a/components/esp_eth/src/esp_eth_mac_dm9051.c b/components/esp_eth/src/esp_eth_mac_dm9051.c index eedfd39d42a3..f2d3116de7dc 100644 --- a/components/esp_eth/src/esp_eth_mac_dm9051.c +++ b/components/esp_eth/src/esp_eth_mac_dm9051.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "driver/gpio.h" #include "driver/spi_master.h" #include "esp_attr.h" @@ -95,7 +96,7 @@ static void *dm9051_spi_init(const void *spi_config) NULL, err, TAG, "incorrect SPI frame format (command_bits/address_bits)"); } ESP_GOTO_ON_FALSE(spi_bus_add_device(dm9051_config->spi_host_id, &spi_devcfg, &spi->hdl) == ESP_OK, - NULL, err, TAG, "adding device to SPI host #%d failed", dm9051_config->spi_host_id + 1); + NULL, err, TAG, "adding device to SPI host #%i failed", dm9051_config->spi_host_id + 1); /* create mutex */ spi->lock = xSemaphoreCreateMutex(); @@ -632,7 +633,7 @@ static esp_err_t emac_dm9051_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t uint8_t tcr = 0; ESP_GOTO_ON_FALSE(length <= ETH_MAX_PACKET_SIZE, ESP_ERR_INVALID_ARG, err, - TAG, "frame size is too big (actual %u, maximum %u)", length, ETH_MAX_PACKET_SIZE); + TAG, "frame size is too big (actual %" PRIu32 ", maximum %d)", length, ETH_MAX_PACKET_SIZE); int64_t wait_time = esp_timer_get_time(); do { @@ -698,7 +699,7 @@ static esp_err_t dm9051_get_recv_byte_count(emac_dm9051_t *emac, uint16_t *size) if (header.status & 0xBF) { /* erroneous frames should not be forwarded by DM9051, however, if it happens, just skip it */ dm9051_skip_recv_frame(emac, rx_len); - ESP_GOTO_ON_FALSE(false, ESP_FAIL, err, TAG, "receive status error: %xH", header.status); + ESP_GOTO_ON_FALSE(false, ESP_FAIL, err, TAG, "receive status error: %" PRIx8 "H", header.status); } *size = rx_len; } @@ -733,7 +734,7 @@ static esp_err_t dm9051_alloc_recv_buf(emac_dm9051_t *emac, uint8_t **buf, uint3 // frames larger than expected will be truncated uint16_t copy_len = rx_len > *length ? *length : rx_len; // runt frames are not forwarded, but check the length anyway since it could be corrupted at SPI bus - ESP_GOTO_ON_FALSE(copy_len >= ETH_MIN_PACKET_SIZE - ETH_CRC_LEN, ESP_ERR_INVALID_SIZE, err, TAG, "invalid frame length %u", copy_len); + ESP_GOTO_ON_FALSE(copy_len >= ETH_MIN_PACKET_SIZE - ETH_CRC_LEN, ESP_ERR_INVALID_SIZE, err, TAG, "invalid frame length %" PRIu16, copy_len); *buf = malloc(copy_len); if (*buf != NULL) { dm9051_auto_buf_info_t *buff_info = (dm9051_auto_buf_info_t *)*buf; @@ -876,7 +877,7 @@ static void emac_dm9051_task(void *arg) ESP_LOGE(TAG, "received frame was truncated"); free(buffer); } else { - ESP_LOGD(TAG, "receive len=%u", buf_len); + ESP_LOGD(TAG, "receive len=%" PRIu32, buf_len); /* pass the buffer to stack (e.g. TCP/IP layer) */ emac->eth->stack_input(emac->eth, buffer, buf_len); } @@ -886,7 +887,7 @@ static void emac_dm9051_task(void *arg) free(buffer); } } else if (frame_len) { - ESP_LOGE(TAG, "invalid combination of frame_len(%u) and buffer pointer(%p)", frame_len, buffer); + ESP_LOGE(TAG, "invalid combination of frame_len(%" PRIu32 ") and buffer pointer(%p)", frame_len, buffer); } } else if (ret == ESP_ERR_NO_MEM) { ESP_LOGE(TAG, "no mem for receive buffer"); diff --git a/components/esp_eth/src/esp_eth_mac_esp.c b/components/esp_eth/src/esp_eth_mac_esp.c index 33455dc42192..82efca1835cf 100644 --- a/components/esp_eth/src/esp_eth_mac_esp.c +++ b/components/esp_eth/src/esp_eth_mac_esp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "esp_private/periph_ctrl.h" #include "esp_attr.h" #include "esp_log.h" @@ -217,7 +218,7 @@ static esp_err_t emac_esp32_set_speed(esp_eth_mac_t *mac, eth_speed_t speed) } #endif emac_hal_set_speed(&emac->hal, speed); - ESP_LOGD(TAG, "working in %dMbps", speed == ETH_SPEED_10M ? 10 : 100); + ESP_LOGD(TAG, "working in %iMbps", speed == ETH_SPEED_10M ? 10 : 100); return ESP_OK; } return ret; @@ -334,7 +335,7 @@ static void emac_esp32_rx_task(void *arg) ESP_LOGE(TAG, "received frame was truncated"); free(buffer); } else { - ESP_LOGD(TAG, "receive len= %d", recv_len); + ESP_LOGD(TAG, "receive len= %" PRIu32, recv_len); emac->eth->stack_input(emac->eth, buffer, recv_len); } /* if allocation failed and there is a waiting frame */ @@ -368,7 +369,7 @@ static esp_err_t emac_config_pll_clock(emac_esp32_t *emac) esp_err_t ret = periph_rtc_apll_freq_set(expt_freq, &real_freq); ESP_RETURN_ON_FALSE(ret != ESP_ERR_INVALID_ARG, ESP_FAIL, TAG, "Set APLL clock coefficients failed"); if (ret == ESP_ERR_INVALID_STATE) { - ESP_LOGW(TAG, "APLL is occupied already, it is working at %d Hz", real_freq); + ESP_LOGW(TAG, "APLL is occupied already, it is working at %" PRIu32 " Hz", real_freq); } #elif CONFIG_IDF_TARGET_ESP32P4 // the RMII reference comes from the MPLL @@ -376,7 +377,7 @@ static esp_err_t emac_config_pll_clock(emac_esp32_t *emac) emac->use_pll = true; esp_err_t ret = periph_rtc_mpll_freq_set(expt_freq * 2, &real_freq); // cannot set 50MHz at MPLL, the nearest possible freq is 100 MHz if (ret == ESP_ERR_INVALID_STATE) { - ESP_LOGW(TAG, "MPLL is occupied already, it is working at %d Hz", real_freq); + ESP_LOGW(TAG, "MPLL is occupied already, it is working at %" PRIu32 " Hz", real_freq); } // Set divider of MPLL clock if (real_freq > RMII_CLK_HZ) { @@ -388,7 +389,7 @@ static esp_err_t emac_config_pll_clock(emac_esp32_t *emac) #endif // If the difference of real RMII CLK frequency is not within 50 ppm, i.e. 2500 Hz, the (A/M)PLL is unusable ESP_RETURN_ON_FALSE(abs((int)real_freq - (int)expt_freq) <= 2500, - ESP_ERR_INVALID_STATE, TAG, "The (A/M)PLL is working at an unusable frequency %lu Hz", real_freq); + ESP_ERR_INVALID_STATE, TAG, "The (A/M)PLL is working at an unusable frequency %" PRIu32 " Hz", real_freq); return ESP_OK; } @@ -651,7 +652,7 @@ static esp_err_t esp_emac_config_data_interface(const eth_esp32_emac_config_t *e } break; default: - ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC Data Interface:%d", esp32_emac_config->interface); + ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC Data Interface:%i", esp32_emac_config->interface); } err: return ret; diff --git a/components/esp_eth/src/esp_eth_mac_ksz8851snl.c b/components/esp_eth/src/esp_eth_mac_ksz8851snl.c index 7aad57d2a4ec..76fa5d998743 100644 --- a/components/esp_eth/src/esp_eth_mac_ksz8851snl.c +++ b/components/esp_eth/src/esp_eth_mac_ksz8851snl.c @@ -7,6 +7,7 @@ */ #include +#include #include "esp_log.h" #include "esp_check.h" #include "esp_cpu.h" @@ -103,7 +104,7 @@ static void *ksz8851_spi_init(const void *spi_config) // SPI device init ESP_GOTO_ON_FALSE(spi_bus_add_device(ksz8851snl_config->spi_host_id, ksz8851snl_config->spi_devcfg, &spi->hdl) == ESP_OK, NULL, - err, TAG, "adding device to SPI host #%d failed", ksz8851snl_config->spi_host_id + 1); + err, TAG, "adding device to SPI host #%i failed", ksz8851snl_config->spi_host_id + 1); ret = spi; return ret; err: @@ -203,7 +204,7 @@ static esp_err_t ksz8851_read_reg(emac_ksz8851snl_t *emac, uint32_t reg_addr, ui ret = ESP_ERR_TIMEOUT; } ksz8851_mutex_unlock(emac); - ESP_LOGV(TAG, "reading reg 0x%02x == 0x%02x", reg_addr, *value); + ESP_LOGV(TAG, "reading reg 0x%02" PRIx32 " = 0x%02" PRIx16, reg_addr, *value); err: return ret; @@ -213,7 +214,7 @@ static esp_err_t ksz8851_write_reg(emac_ksz8851snl_t *emac, uint32_t reg_addr, u { esp_err_t ret = ESP_OK; ESP_GOTO_ON_FALSE((reg_addr & ~KSZ8851_VALID_ADDRESS_MASK) == 0U, ESP_ERR_INVALID_ARG, err, TAG, "address is out of bounds"); - ESP_LOGV(TAG, "writing reg 0x%02x = 0x%02x", reg_addr, value); + ESP_LOGV(TAG, "writing reg 0x%02" PRIx32 " = 0x%02" PRIx16, reg_addr, value); // NOTE(v.chistyakov): select upper or lower word inside a dword const unsigned byte_mask = 0x3U << (KSZ8851_SPI_BYTE_MASK_SHIFT + (reg_addr & 0x2U)); @@ -236,9 +237,9 @@ static esp_err_t ksz8851_set_bits(emac_ksz8851snl_t *emac, uint32_t address, uin { esp_err_t ret = ESP_OK; uint16_t old; - ESP_GOTO_ON_ERROR(ksz8851_read_reg(emac, address, &old), err, TAG, "failed to read reg 0x%x", address); + ESP_GOTO_ON_ERROR(ksz8851_read_reg(emac, address, &old), err, TAG, "failed to read reg 0x%" PRIx32, address); old |= value; - ESP_GOTO_ON_ERROR(ksz8851_write_reg(emac, address, old), err, TAG, "failed to write reg 0x%x", address); + ESP_GOTO_ON_ERROR(ksz8851_write_reg(emac, address, old), err, TAG, "failed to write reg 0x%" PRIx32, address); err: return ret; } @@ -247,9 +248,9 @@ static esp_err_t ksz8851_clear_bits(emac_ksz8851snl_t *emac, uint32_t address, u { esp_err_t ret = ESP_OK; uint16_t old; - ESP_GOTO_ON_ERROR(ksz8851_read_reg(emac, address, &old), err, TAG, "failed to read reg 0x%x", address); + ESP_GOTO_ON_ERROR(ksz8851_read_reg(emac, address, &old), err, TAG, "failed to read reg 0x%" PRIx32, address); old &= ~value; - ESP_GOTO_ON_ERROR(ksz8851_write_reg(emac, address, old), err, TAG, "failed to write reg 0x%x", address); + ESP_GOTO_ON_ERROR(ksz8851_write_reg(emac, address, old), err, TAG, "failed to write reg 0x%" PRIx32, address); err: return ret; } @@ -288,7 +289,7 @@ static esp_err_t init_verify_chipid(emac_ksz8851snl_t *emac) uint8_t family_id = (id & CIDER_FAMILY_ID_MASK) >> CIDER_FAMILY_ID_SHIFT; uint8_t chip_id = (id & CIDER_CHIP_ID_MASK) >> CIDER_CHIP_ID_SHIFT; uint8_t revision = (id & CIDER_REVISION_ID_MASK) >> CIDER_REVISION_ID_SHIFT; - ESP_LOGI(TAG, "Family ID = 0x%x\t Chip ID = 0x%x\t Revision ID = 0x%x", family_id, chip_id, revision); + ESP_LOGI(TAG, "Family ID = 0x%" PRIx8 "\t Chip ID = 0x%" PRIx8 "\t Revision ID = 0x%" PRIx8, family_id, chip_id, revision); ESP_GOTO_ON_FALSE(family_id == CIDER_KSZ8851SNL_FAMILY_ID, ESP_FAIL, err, TAG, "wrong family id"); ESP_GOTO_ON_FALSE(chip_id == CIDER_KSZ8851SNL_CHIP_ID, ESP_FAIL, err, TAG, "wrong chip id"); return ESP_OK; @@ -400,7 +401,7 @@ static esp_err_t emac_ksz8851snl_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint { static unsigned s_frame_id = 0U; - ESP_LOGV(TAG, "transmitting frame of size %u", length); + ESP_LOGV(TAG, "transmitting frame of size %" PRIu32, length); esp_err_t ret = ESP_OK; emac_ksz8851snl_t *emac = __containerof(mac, emac_ksz8851snl_t, parent); // Lock SPI since once `SDA Start DMA Access` bit is set, all registers access are disabled. @@ -409,13 +410,13 @@ static esp_err_t emac_ksz8851snl_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint } ESP_GOTO_ON_FALSE(length <= KSZ8851_QMU_PACKET_LENGTH, ESP_ERR_INVALID_ARG, err, - TAG, "frame size is too big (actual %u, maximum %u)", length, ETH_MAX_PACKET_SIZE); + TAG, "frame size is too big (actual %" PRIu32 ", maximum %d)", length, ETH_MAX_PACKET_SIZE); // NOTE(v.chistyakov): 4 bytes header + length aligned to 4 bytes unsigned transmit_length = 4U + ((length + 3U) & ~0x3U); uint16_t free_space; ESP_GOTO_ON_ERROR(ksz8851_read_reg(emac, KSZ8851_TXMIR, &free_space), err, TAG, "TXMIR read failed"); - ESP_GOTO_ON_FALSE(transmit_length <= free_space, ESP_FAIL, err, TAG, "TXQ free space (%d) < send length (%d)", free_space, + ESP_GOTO_ON_FALSE(transmit_length <= free_space, ESP_FAIL, err, TAG, "TXQ free space (%" PRIu16 ") < send length (%" PRIu16 ")", free_space, transmit_length); emac->tx_buffer[0] = ++s_frame_id & TXSR_TXFID_MASK; @@ -474,7 +475,7 @@ static esp_err_t emac_ksz8851_alloc_recv_buf(emac_ksz8851snl_t *emac, uint8_t ** // frames larger than expected will be truncated uint16_t copy_len = rx_len > *length ? *length : rx_len; // runt frames are not forwarded, but check the length anyway since it could be corrupted at SPI bus - ESP_GOTO_ON_FALSE(copy_len >= ETH_MIN_PACKET_SIZE - ETH_CRC_LEN, ESP_ERR_INVALID_SIZE, err, TAG, "invalid frame length %u", copy_len); + ESP_GOTO_ON_FALSE(copy_len >= ETH_MIN_PACKET_SIZE - ETH_CRC_LEN, ESP_ERR_INVALID_SIZE, err, TAG, "invalid frame length %" PRIu16, copy_len); *buf = malloc(copy_len); if (*buf != NULL) { ksz8851_auto_buf_info_t *buff_info = (ksz8851_auto_buf_info_t *)*buf; @@ -789,7 +790,7 @@ static void emac_ksz8851snl_task(void *arg) ESP_LOGE(TAG, "received frame was truncated"); free(buffer); } else { - ESP_LOGD(TAG, "receive len=%u", buf_len); + ESP_LOGD(TAG, "receive len=%" PRIu32, buf_len); /* pass the buffer to stack (e.g. TCP/IP layer) */ emac->eth->stack_input(emac->eth, buffer, buf_len); } @@ -799,7 +800,7 @@ static void emac_ksz8851snl_task(void *arg) free(buffer); } } else if (frame_len) { - ESP_LOGE(TAG, "invalid combination of frame_len(%u) and buffer pointer(%p)", frame_len, buffer); + ESP_LOGE(TAG, "invalid combination of frame_len(%" PRIu32 ") and buffer pointer(%p)", frame_len, buffer); } } else if (ret == ESP_ERR_NO_MEM) { ESP_LOGE(TAG, "no mem for receive buffer"); diff --git a/components/esp_eth/src/esp_eth_mac_w5500.c b/components/esp_eth/src/esp_eth_mac_w5500.c index 6c9240f7b5e8..895585160366 100644 --- a/components/esp_eth/src/esp_eth_mac_w5500.c +++ b/components/esp_eth/src/esp_eth_mac_w5500.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "driver/gpio.h" #include "driver/spi_master.h" #include "esp_attr.h" @@ -84,7 +85,7 @@ static void *w5500_spi_init(const void *spi_config) NULL, err, TAG, "incorrect SPI frame format (command_bits/address_bits)"); } ESP_GOTO_ON_FALSE(spi_bus_add_device(w5500_config->spi_host_id, &spi_devcfg, &spi->hdl) == ESP_OK, NULL, - err, TAG, "adding device to SPI host #%d failed", w5500_config->spi_host_id + 1); + err, TAG, "adding device to SPI host #%i failed", w5500_config->spi_host_id + 1); /* create mutex */ spi->lock = xSemaphoreCreateMutex(); ESP_GOTO_ON_FALSE(spi->lock, NULL, err, TAG, "create lock failed"); @@ -326,7 +327,7 @@ static esp_err_t w5500_verify_id(emac_w5500_t *emac) vTaskDelay(pdMS_TO_TICKS(10)); } - ESP_LOGE(TAG, "W5500 version mismatched, expected 0x%02x, got 0x%02x", W5500_CHIP_VERSION, version); + ESP_LOGE(TAG, "W5500 version mismatched, expected 0x%02x, got 0x%02" PRIx8, W5500_CHIP_VERSION, version); return ESP_ERR_INVALID_VERSION; err: return ret; @@ -570,11 +571,11 @@ static esp_err_t emac_w5500_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t uint16_t offset = 0; ESP_GOTO_ON_FALSE(length <= ETH_MAX_PACKET_SIZE, ESP_ERR_INVALID_ARG, err, - TAG, "frame size is too big (actual %u, maximum %u)", length, ETH_MAX_PACKET_SIZE); + TAG, "frame size is too big (actual %" PRIu32 ", maximum %u)", length, ETH_MAX_PACKET_SIZE); // check if there're free memory to store this packet uint16_t free_size = 0; ESP_GOTO_ON_ERROR(w5500_get_tx_free_size(emac, &free_size), err, TAG, "get free size failed"); - ESP_GOTO_ON_FALSE(length <= free_size, ESP_ERR_NO_MEM, err, TAG, "free size (%d) < send length (%d)", free_size, length); + ESP_GOTO_ON_FALSE(length <= free_size, ESP_ERR_NO_MEM, err, TAG, "free size (%" PRIu16 ") < send length (%" PRIu32 ")", free_size, length); // get current write pointer ESP_GOTO_ON_ERROR(w5500_read(emac, W5500_REG_SOCK_TX_WR(0), &offset, sizeof(offset)), err, TAG, "read TX WR failed"); offset = __builtin_bswap16(offset); @@ -624,7 +625,7 @@ static esp_err_t emac_w5500_alloc_recv_buf(emac_w5500_t *emac, uint8_t **buf, ui // frames larger than expected will be truncated copy_len = rx_len > *length ? *length : rx_len; // runt frames are not forwarded by W5500 (tested on target), but check the length anyway since it could be corrupted at SPI bus - ESP_GOTO_ON_FALSE(copy_len >= ETH_MIN_PACKET_SIZE - ETH_CRC_LEN, ESP_ERR_INVALID_SIZE, err, TAG, "invalid frame length %u", copy_len); + ESP_GOTO_ON_FALSE(copy_len >= ETH_MIN_PACKET_SIZE - ETH_CRC_LEN, ESP_ERR_INVALID_SIZE, err, TAG, "invalid frame length %" PRIu32, copy_len); *buf = malloc(copy_len); if (*buf != NULL) { emac_w5500_auto_buf_info_t *buff_info = (emac_w5500_auto_buf_info_t *)*buf; @@ -677,7 +678,7 @@ static esp_err_t emac_w5500_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t * // 2 bytes of header offset += 2; // read the payload - ESP_GOTO_ON_ERROR(w5500_read_buffer(emac, emac->rx_buffer, copy_len, offset), err, TAG, "read payload failed, len=%d, offset=%d", rx_len, offset); + ESP_GOTO_ON_ERROR(w5500_read_buffer(emac, emac->rx_buffer, copy_len, offset), err, TAG, "read payload failed, len=%" PRIu16 ", offset=%" PRIu16, rx_len, offset); memcpy(buf, emac->rx_buffer, copy_len); offset += rx_len; // update read pointer @@ -782,7 +783,7 @@ static void emac_w5500_task(void *arg) ESP_LOGE(TAG, "received frame was truncated"); free(buffer); } else { - ESP_LOGD(TAG, "receive len=%u", buf_len); + ESP_LOGD(TAG, "receive len=%" PRIu32, buf_len); /* pass the buffer to stack (e.g. TCP/IP layer) */ emac->eth->stack_input(emac->eth, buffer, buf_len); } @@ -791,7 +792,7 @@ static void emac_w5500_task(void *arg) free(buffer); } } else if (frame_len) { - ESP_LOGE(TAG, "invalid combination of frame_len(%u) and buffer pointer(%p)", frame_len, buffer); + ESP_LOGE(TAG, "invalid combination of frame_len(%" PRIu32 ") and buffer pointer(%p)", frame_len, buffer); } } else if (ret == ESP_ERR_NO_MEM) { ESP_LOGE(TAG, "no mem for receive buffer"); diff --git a/components/esp_eth/src/esp_eth_netif_glue.c b/components/esp_eth/src/esp_eth_netif_glue.c index 44de659b3fd8..ad33eb0d2f68 100644 --- a/components/esp_eth/src/esp_eth_netif_glue.c +++ b/components/esp_eth/src/esp_eth_netif_glue.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include "esp_netif.h" #include "esp_eth_driver.h" #include "esp_eth_netif_glue.h" @@ -76,7 +77,7 @@ static void eth_action_start(void *handler_args, esp_event_base_t base, int32_t { esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data; esp_eth_netif_glue_t *netif_glue = handler_args; - ESP_LOGD(TAG, "eth_action_start: %p, %p, %d, %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); + ESP_LOGD(TAG, "eth_action_start: %p, %p, %" PRIi32 ", %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); if (netif_glue->eth_driver == eth_handle) { esp_netif_action_start(netif_glue->base.netif, base, event_id, event_data); } @@ -86,7 +87,7 @@ static void eth_action_stop(void *handler_args, esp_event_base_t base, int32_t e { esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data; esp_eth_netif_glue_t *netif_glue = handler_args; - ESP_LOGD(TAG, "eth_action_stop: %p, %p, %d, %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); + ESP_LOGD(TAG, "eth_action_stop: %p, %p, %" PRIi32 ", %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); if (netif_glue->eth_driver == eth_handle) { esp_netif_action_stop(netif_glue->base.netif, base, event_id, event_data); } @@ -96,7 +97,7 @@ static void eth_action_connected(void *handler_args, esp_event_base_t base, int3 { esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data; esp_eth_netif_glue_t *netif_glue = handler_args; - ESP_LOGD(TAG, "eth_action_connected: %p, %p, %d, %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); + ESP_LOGD(TAG, "eth_action_connected: %p, %p, %" PRIi32 ", %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); if (netif_glue->eth_driver == eth_handle) { eth_speed_t speed; esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &speed); @@ -109,7 +110,7 @@ static void eth_action_disconnected(void *handler_args, esp_event_base_t base, i { esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data; esp_eth_netif_glue_t *netif_glue = handler_args; - ESP_LOGD(TAG, "eth_action_disconnected: %p, %p, %d, %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); + ESP_LOGD(TAG, "eth_action_disconnected: %p, %p, %" PRIi32 ", %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); if (netif_glue->eth_driver == eth_handle) { esp_netif_action_disconnected(netif_glue->base.netif, base, event_id, event_data); } @@ -119,7 +120,7 @@ static void eth_action_got_ip(void *handler_args, esp_event_base_t base, int32_t { ip_event_got_ip_t *ip_event = (ip_event_got_ip_t *)event_data; esp_eth_netif_glue_t *netif_glue = handler_args; - ESP_LOGD(TAG, "eth_action_got_ip: %p, %p, %d, %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); + ESP_LOGD(TAG, "eth_action_got_ip: %p, %p, %" PRIi32 ", %p, %p", netif_glue, base, event_id, event_data, *(esp_eth_handle_t *)event_data); if (netif_glue->base.netif == ip_event->esp_netif) { esp_netif_action_got_ip(ip_event->esp_netif, base, event_id, event_data); } diff --git a/components/esp_eth/src/esp_eth_phy_ip101.c b/components/esp_eth/src/esp_eth_phy_ip101.c index a32a3bffb6ff..c9a187d690ac 100644 --- a/components/esp_eth/src/esp_eth_phy_ip101.c +++ b/components/esp_eth/src/esp_eth_phy_ip101.c @@ -6,6 +6,8 @@ #include #include #include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "esp_log.h" #include "esp_check.h" #include "freertos/FreeRTOS.h" diff --git a/components/esp_eth/src/esp_eth_phy_ksz80xx.c b/components/esp_eth/src/esp_eth_phy_ksz80xx.c index 2102acdf8832..aec0e70b80b2 100644 --- a/components/esp_eth/src/esp_eth_phy_ksz80xx.c +++ b/components/esp_eth/src/esp_eth_phy_ksz80xx.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include +#include #include "esp_log.h" #include "esp_check.h" #include "esp_eth_phy_802_3.h" @@ -74,7 +75,7 @@ static esp_err_t ksz80xx_update_link_duplex_speed(phy_ksz80xx_t * ksz80xx) /* when link up, read negotiation result */ if (link == ETH_LINK_UP) { uint32_t reg_value = 0; - ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ksz80xx->op_mode_reg, ®_value), err, TAG, "read %#04x failed", ksz80xx->op_mode_reg); + ESP_GOTO_ON_ERROR(eth->phy_reg_read(eth, addr, ksz80xx->op_mode_reg, ®_value), err, TAG, "read %#04" PRIx32 " failed", ksz80xx->op_mode_reg); uint8_t op_mode = (reg_value >> ksz80xx->op_mode_offset) & 0x07; switch (op_mode) { case 1: //10Base-T half-duplex @@ -170,7 +171,7 @@ static esp_err_t ksz80xx_init(esp_eth_phy_t *phy) break; } } - ESP_GOTO_ON_FALSE(supported_model_name != NULL && ksz80xx_init_model(ksz80xx), ESP_FAIL, err, TAG, "unsupported model number: %#04x", ksz80xx->model_number); + ESP_GOTO_ON_FALSE(supported_model_name != NULL && ksz80xx_init_model(ksz80xx), ESP_FAIL, err, TAG, "unsupported model number: %#04" PRIx8, ksz80xx->model_number); ESP_LOGI(TAG, "auto detected phy KSZ80%s", supported_model_name); return ESP_OK; err: diff --git a/components/esp_eth/src/esp_eth_phy_ksz8851snl.c b/components/esp_eth/src/esp_eth_phy_ksz8851snl.c index 982c1c9b24d9..d520000bd65a 100644 --- a/components/esp_eth/src/esp_eth_phy_ksz8851snl.c +++ b/components/esp_eth/src/esp_eth_phy_ksz8851snl.c @@ -242,7 +242,7 @@ static esp_err_t phy_ksz8851_set_addr(esp_eth_phy_t *phy, uint32_t addr) { phy_ksz8851snl_t *ksz8851 = __containerof(phy, phy_ksz8851snl_t, parent); ksz8851->addr = addr; - ESP_LOGD(TAG, "setting PHY addr to %u", addr); + ESP_LOGD(TAG, "setting PHY addr to %" PRIu32, addr); return ESP_OK; } From 72f00d7c6d1124d90587e53f0ceadac5a3258cbd Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Thu, 7 Dec 2023 10:11:41 +0100 Subject: [PATCH 23/33] feat(usb/host): Update ISOC scheduler for HS endpoints USB-OTG uses 'sched_info' field of HCTSIZ register to schedule transactions in USB microframes. --- components/hal/include/hal/usb_dwc_hal.h | 16 +-- components/hal/include/hal/usb_dwc_ll.h | 34 ++++++ components/hal/usb_dwc_hal.c | 53 +++++++-- components/usb/hcd_dwc.c | 96 ++++++++-------- .../usb/test_apps/hcd/main/test_hcd_common.c | 1 - .../usb/test_apps/hcd/main/test_hcd_isoc.c | 106 +++++++++++++++++- 6 files changed, 238 insertions(+), 68 deletions(-) diff --git a/components/hal/include/hal/usb_dwc_hal.h b/components/hal/include/hal/usb_dwc_hal.h index 2ee7104b6f0b..9b2a2c3bc30b 100644 --- a/components/hal/include/hal/usb_dwc_hal.h +++ b/components/hal/include/hal/usb_dwc_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -141,7 +141,8 @@ typedef struct { }; struct { unsigned int interval; /**< The interval of the endpoint in frames (FS) or microframes (HS) */ - uint32_t phase_offset_frames; /**< Phase offset in number of frames */ + uint32_t offset; /**< Offset of this channel in the periodic scheduler */ + bool is_hs; /**< This endpoint is HighSpeed. Needed for Periodic Frame List (HAL layer) scheduling */ } periodic; /**< Characteristic for periodic (interrupt/isochronous) endpoints only */ } usb_dwc_hal_ep_char_t; @@ -425,17 +426,6 @@ static inline void usb_dwc_hal_port_set_frame_list(usb_dwc_hal_context_t *hal, u hal->frame_list_len = len; } -/** - * @brief Get the pointer to the periodic scheduling frame list - * - * @param hal Context of the HAL layer - * @return uint32_t* Base address of the periodic scheduling frame list - */ -static inline uint32_t *usb_dwc_hal_port_get_frame_list(usb_dwc_hal_context_t *hal) -{ - return hal->periodic_frame_list; -} - /** * @brief Enable periodic scheduling * diff --git a/components/hal/include/hal/usb_dwc_ll.h b/components/hal/include/hal/usb_dwc_ll.h index 44c7fca824e8..49ade5040512 100644 --- a/components/hal/include/hal/usb_dwc_ll.h +++ b/components/hal/include/hal/usb_dwc_ll.h @@ -818,6 +818,40 @@ static inline void usb_dwc_ll_hctsiz_init(volatile usb_dwc_host_chan_regs_t *cha chan->hctsiz_reg.val = hctsiz.val; } +static inline void usb_dwc_ll_hctsiz_set_sched_info(volatile usb_dwc_host_chan_regs_t *chan, int tokens_per_frame, int offset) +{ + // @see USB-OTG databook: Table 5-47 + // This function is relevant only for HS + usb_dwc_hctsiz_reg_t hctsiz; + hctsiz.val = chan->hctsiz_reg.val; + uint8_t sched_info_val; + switch (tokens_per_frame) { + case 1: + offset %= 8; // If the required offset > 8, we must wrap around to SCHED_INFO size = 8 + sched_info_val = 0b00000001; + break; + case 2: + offset %= 4; + sched_info_val = 0b00010001; + break; + case 4: + offset %= 2; + sched_info_val = 0b01010101; + break; + case 8: + offset = 0; + sched_info_val = 0b11111111; + break; + default: + abort(); + break; + } + sched_info_val <<= offset; + hctsiz.xfersize &= ~(0xFF); + hctsiz.xfersize |= sched_info_val; + chan->hctsiz_reg.val = hctsiz.val; +} + // ---------------------------- HCDMAi Register -------------------------------- static inline void usb_dwc_ll_hcdma_set_qtd_list_addr(volatile usb_dwc_host_chan_regs_t *chan, void *dmaaddr, uint32_t qtd_idx) diff --git a/components/hal/usb_dwc_hal.c b/components/hal/usb_dwc_hal.c index 7cc4ae7f8395..bcc8870ed474 100644 --- a/components/hal/usb_dwc_hal.c +++ b/components/hal/usb_dwc_hal.c @@ -6,7 +6,8 @@ #include #include -#include +#include // For memset() +#include // For abort() #include "sdkconfig.h" #include "soc/chip_revision.h" #include "soc/usb_dwc_cfg.h" @@ -335,12 +336,48 @@ void usb_dwc_hal_chan_set_ep_char(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t chan_obj->type = ep_char->type; //If this is a periodic endpoint/channel, set its schedule in the frame list if (ep_char->type == USB_DWC_XFER_TYPE_ISOCHRONOUS || ep_char->type == USB_DWC_XFER_TYPE_INTR) { - HAL_ASSERT((int)ep_char->periodic.interval <= (int)hal->frame_list_len); //Interval cannot exceed the length of the frame list - //Find the effective offset in the frame list (in case the phase_offset_frames > interval) - int offset = ep_char->periodic.phase_offset_frames % ep_char->periodic.interval; - //Schedule the channel in the frame list - for (int i = offset; i < hal->frame_list_len; i+= ep_char->periodic.interval) { - hal->periodic_frame_list[i] |= 1 << chan_obj->flags.chan_idx; + unsigned int interval_frame_list = ep_char->periodic.interval; + unsigned int offset_frame_list = ep_char->periodic.offset; + // Periodic Frame List works with USB frames. For HS endpoints we must divide interval[microframes] by 8 to get interval[frames] + if (ep_char->periodic.is_hs) { + interval_frame_list /= 8; + offset_frame_list /= 8; + } + // Interval in Periodic Frame List must be power of 2. + // This is not a HW restriction. It is just a lot easier to schedule channels like this. + if (interval_frame_list >= (int)hal->frame_list_len) { // Upper limits is Periodic Frame List length + interval_frame_list = (int)hal->frame_list_len; + } else if (interval_frame_list >= 32) { + interval_frame_list = 32; + } else if (interval_frame_list >= 16) { + interval_frame_list = 16; + } else if (interval_frame_list >= 8) { + interval_frame_list = 8; + } else if (interval_frame_list >= 4) { + interval_frame_list = 4; + } else if (interval_frame_list >= 2) { + interval_frame_list = 2; + } else { // Lower limit is 1 + interval_frame_list = 1; + } + // Schedule the channel in the frame list + for (int i = 0; i < hal->frame_list_len; i+= interval_frame_list) { + int index = (offset_frame_list + i) % hal->frame_list_len; + hal->periodic_frame_list[index] |= 1 << chan_obj->flags.chan_idx; + } + // For HS endpoints we must write to sched_info field of HCTSIZ register to schedule microframes + if (ep_char->periodic.is_hs) { + unsigned int tokens_per_frame; + if (ep_char->periodic.interval >= 8) { + tokens_per_frame = 1; // 1 token every 8 microframes + } else if (ep_char->periodic.interval >= 4) { + tokens_per_frame = 2; // 1 token every 4 microframes + } else if (ep_char->periodic.interval >= 2) { + tokens_per_frame = 4; // 1 token every 2 microframes + } else { + tokens_per_frame = 8; // 1 token every microframe + } + usb_dwc_ll_hctsiz_set_sched_info(chan_obj->regs, tokens_per_frame, ep_char->periodic.offset); } } } @@ -490,7 +527,7 @@ usb_dwc_hal_chan_event_t usb_dwc_hal_chan_decode_intr(usb_dwc_hal_chan_t *chan_o */ chan_event = USB_DWC_HAL_CHAN_EVENT_NONE; } else { - abort(); //Should never reach this point + abort(); } return chan_event; } diff --git a/components/usb/hcd_dwc.c b/components/usb/hcd_dwc.c index f529ff1b3e09..3171467e72f6 100644 --- a/components/usb/hcd_dwc.c +++ b/components/usb/hcd_dwc.c @@ -60,8 +60,10 @@ #define XFER_LIST_LEN_CTRL 3 // One descriptor for each stage #define XFER_LIST_LEN_BULK 2 // One descriptor for transfer, one to support an extra zero length packet +// Same length as the frame list makes it easier to schedule. Must be power of 2 +// FS: Must be 2-64. HS: Must be 8-256. See USB-OTG databook Table 5-47 #define XFER_LIST_LEN_INTR FRAME_LIST_LEN -#define XFER_LIST_LEN_ISOC FRAME_LIST_LEN // Same length as the frame list makes it easier to schedule. Must be power of 2 +#define XFER_LIST_LEN_ISOC FRAME_LIST_LEN // ------------------------ Flags -------------------------- @@ -1745,27 +1747,14 @@ static void pipe_set_ep_char(const hcd_pipe_config_t *pipe_config, usb_transfer_ } else { interval_value = (1 << (pipe_config->ep_desc->bInterval - 1)); } - // Round down interval to nearest power of 2 - if (interval_value >= 32) { - interval_value = 32; - } else if (interval_value >= 16) { - interval_value = 16; - } else if (interval_value >= 8) { - interval_value = 8; - } else if (interval_value >= 4) { - interval_value = 4; - } else if (interval_value >= 2) { - interval_value = 2; - } else if (interval_value >= 1) { - interval_value = 1; - } ep_char->periodic.interval = interval_value; // We are the Nth pipe to be allocated. Use N as a phase offset unsigned int xfer_list_len = (type == USB_TRANSFER_TYPE_INTR) ? XFER_LIST_LEN_INTR : XFER_LIST_LEN_ISOC; - ep_char->periodic.phase_offset_frames = pipe_idx & (xfer_list_len - 1); + ep_char->periodic.offset = (pipe_idx % xfer_list_len) % interval_value; + ep_char->periodic.is_hs = (pipe_config->dev_speed == USB_SPEED_HIGH); } else { ep_char->periodic.interval = 0; - ep_char->periodic.phase_offset_frames = 0; + ep_char->periodic.offset = 0; } } @@ -2219,14 +2208,16 @@ static inline void _buffer_fill_intr(dma_buffer_block_t *buffer, usb_transfer_t buffer->flags.intr.zero_len_packet = zero_len_packet; } -static inline void _buffer_fill_isoc(dma_buffer_block_t *buffer, usb_transfer_t *transfer, bool is_in, int mps, int interval, int start_idx) +static inline void IRAM_ATTR _buffer_fill_isoc(dma_buffer_block_t *buffer, usb_transfer_t *transfer, bool is_in, int mps, int interval, int start_idx) { assert(interval > 0); + assert(__builtin_popcount(interval) == 1); // Isochronous interval must be power of 2 according to USB2.0 specification int total_num_desc = transfer->num_isoc_packets * interval; assert(total_num_desc <= XFER_LIST_LEN_ISOC); int desc_idx = start_idx; int bytes_filled = 0; - // For each packet, fill in a descriptor and a interval-1 blank descriptor after it + // Zeroize the whole QTD, so we can focus only on the active descriptors + memset(buffer->xfer_desc_list, 0, XFER_LIST_LEN_ISOC * sizeof(usb_dwc_ll_dma_qtd_t)); for (int pkt_idx = 0; pkt_idx < transfer->num_isoc_packets; pkt_idx++) { int xfer_len = transfer->isoc_packet_desc[pkt_idx].num_bytes; uint32_t flags = (is_in) ? USB_DWC_HAL_XFER_DESC_FLAG_IN : 0; @@ -2236,16 +2227,8 @@ static inline void _buffer_fill_isoc(dma_buffer_block_t *buffer, usb_transfer_t } usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, desc_idx, &transfer->data_buffer[bytes_filled], xfer_len, flags); bytes_filled += xfer_len; - if (++desc_idx >= XFER_LIST_LEN_ISOC) { - desc_idx = 0; - } - // Clear descriptors for unscheduled frames - for (int i = 0; i < interval - 1; i++) { - usb_dwc_hal_xfer_desc_clear(buffer->xfer_desc_list, desc_idx); - if (++desc_idx >= XFER_LIST_LEN_ISOC) { - desc_idx = 0; - } - } + desc_idx += interval; + desc_idx %= XFER_LIST_LEN_ISOC; } // Update buffer members and flags buffer->flags.isoc.num_qtds = total_num_desc; @@ -2254,7 +2237,7 @@ static inline void _buffer_fill_isoc(dma_buffer_block_t *buffer, usb_transfer_t buffer->flags.isoc.next_start_idx = desc_idx; } -static void _buffer_fill(pipe_t *pipe) +static void IRAM_ATTR _buffer_fill(pipe_t *pipe) { // Get an URB from the pending tailq urb_t *urb = TAILQ_FIRST(&pipe->pending_urb_tailq); @@ -2276,29 +2259,46 @@ static void _buffer_fill(pipe_t *pipe) break; } case USB_DWC_XFER_TYPE_ISOCHRONOUS: { - uint32_t start_idx; + uint16_t start_idx; + // Interval in frames (FS) or microframes (HS). But it does not matter here, as each QTD represents one transaction in a frame or microframe + unsigned int interval = pipe->ep_char.periodic.interval; + if (interval > XFER_LIST_LEN_ISOC) { + // Each QTD in the list corresponds to one frame/microframe. Interval > Descriptor_list does not make sense here. + interval = XFER_LIST_LEN_ISOC; + } if (pipe->multi_buffer_control.buffer_num_to_exec == 0) { // There are no more previously filled buffers to execute. We need to calculate a new start index based on HFNUM and the pipe's schedule - uint32_t cur_frame_num = usb_dwc_hal_port_get_cur_frame_num(pipe->port->hal); - uint32_t cur_mod_idx_no_offset = (cur_frame_num - pipe->ep_char.periodic.phase_offset_frames) & (XFER_LIST_LEN_ISOC - 1); // Get the modulated index (i.e., the Nth desc in the descriptor list) - // This is the non-offset modulated QTD index of the last scheduled interval - uint32_t last_interval_mod_idx_no_offset = (cur_mod_idx_no_offset / pipe->ep_char.periodic.interval) * pipe->ep_char.periodic.interval; // Floor divide and the multiply again - uint32_t next_interval_idx_no_offset = (last_interval_mod_idx_no_offset + pipe->ep_char.periodic.interval); - // We want at least a half interval or 2 frames of buffer space - if (next_interval_idx_no_offset - cur_mod_idx_no_offset > (pipe->ep_char.periodic.interval / 2) - && next_interval_idx_no_offset - cur_mod_idx_no_offset >= 2) { - start_idx = (next_interval_idx_no_offset + pipe->ep_char.periodic.phase_offset_frames) & (XFER_LIST_LEN_ISOC - 1); - } else { - // Not enough time until the next schedule, add another interval to it. - start_idx = (next_interval_idx_no_offset + pipe->ep_char.periodic.interval + pipe->ep_char.periodic.phase_offset_frames) & (XFER_LIST_LEN_ISOC - 1); + uint16_t cur_frame_num = usb_dwc_hal_port_get_cur_frame_num(pipe->port->hal); + start_idx = cur_frame_num + 1; // This is the next frame that the periodic scheduler will fetch + uint16_t rem_time = usb_dwc_ll_hfnum_get_frame_time_rem(pipe->port->hal->dev); + + // If there is not enough time remaining in this frame, consider the next frame as start index + // The remaining time is in USB PHY clocks. The threshold value is time between buffer fill and execute (6-11us) = 180 + 5 x num_packets + if (rem_time < 195 + 5 * transfer->num_isoc_packets) { + if (rem_time > 165 + 5 * transfer->num_isoc_packets) { + // If the remaining time is +-15 PHY clocks around the threshold value we cannot be certain whether we will schedule it in time for this frame + // Busy wait 10us to be sure that we are at the beginning of next frame/microframe + esp_rom_delay_us(10); + } + start_idx++; + } + + // Only every (interval + offset) transfer belongs to this channel + // Following calculation effectively rounds up to nearest (interval + offset) + if (interval > 1) { + uint32_t interval_offset = (start_idx - pipe->ep_char.periodic.offset) % interval; // Can be <0, interval) + if (interval_offset > 0) { + start_idx += interval - interval_offset; + } } + start_idx %= XFER_LIST_LEN_ISOC; } else { // Start index is based on previously filled buffer uint32_t prev_buffer_idx = (pipe->multi_buffer_control.wr_idx - 1) & (NUM_BUFFERS - 1); dma_buffer_block_t *prev_filled_buffer = pipe->buffers[prev_buffer_idx]; start_idx = prev_filled_buffer->flags.isoc.next_start_idx; } - _buffer_fill_isoc(buffer_to_fill, transfer, is_in, mps, (int)pipe->ep_char.periodic.interval, start_idx); + _buffer_fill_isoc(buffer_to_fill, transfer, is_in, mps, (int)interval, start_idx); break; } case USB_DWC_XFER_TYPE_BULK: { @@ -2324,7 +2324,7 @@ static void _buffer_fill(pipe_t *pipe) pipe->multi_buffer_control.buffer_num_to_exec++; } -static void _buffer_exec(pipe_t *pipe) +static void IRAM_ATTR _buffer_exec(pipe_t *pipe) { assert(pipe->multi_buffer_control.rd_idx != pipe->multi_buffer_control.wr_idx || pipe->multi_buffer_control.buffer_num_to_exec > 0); dma_buffer_block_t *buffer_to_exec = pipe->buffers[pipe->multi_buffer_control.rd_idx]; @@ -2621,6 +2621,12 @@ esp_err_t hcd_urb_enqueue(hcd_pipe_handle_t pipe_hdl, urb_t *urb) // Check that URB has not already been enqueued HCD_CHECK(urb->hcd_ptr == NULL && urb->hcd_var == URB_HCD_STATE_IDLE, ESP_ERR_INVALID_STATE); pipe_t *pipe = (pipe_t *)pipe_hdl; + // Check if the ISOC pipe can handle all packets: + // In case the pipe's interval is too long and there are too many ISOC packets, they might not fit into the transfer descriptor list + HCD_CHECK( + !((pipe->ep_char.type == USB_DWC_XFER_TYPE_ISOCHRONOUS) && (urb->transfer.num_isoc_packets * pipe->ep_char.periodic.interval > XFER_LIST_LEN_ISOC)), + ESP_ERR_INVALID_SIZE + ); // Sync user's data from cache to memory. For OUT and CTRL transfers CACHE_SYNC_DATA_BUFFER_C2M(pipe, urb); diff --git a/components/usb/test_apps/hcd/main/test_hcd_common.c b/components/usb/test_apps/hcd/main/test_hcd_common.c index 219e552cc467..25145c3f249e 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_common.c +++ b/components/usb/test_apps/hcd/main/test_hcd_common.c @@ -236,7 +236,6 @@ hcd_pipe_handle_t test_hcd_pipe_alloc(hcd_port_handle_t port_hdl, const usb_ep_d //Create a queue for pipe callback to queue up pipe events QueueHandle_t pipe_evt_queue = xQueueCreate(EVENT_QUEUE_LEN, sizeof(pipe_event_msg_t)); TEST_ASSERT_NOT_NULL(pipe_evt_queue); - printf("Creating pipe\n"); hcd_pipe_config_t pipe_config = { .callback = pipe_callback, .callback_arg = (void *)pipe_evt_queue, diff --git a/components/usb/test_apps/hcd/main/test_hcd_isoc.c b/components/usb/test_apps/hcd/main/test_hcd_isoc.c index 1e0124246b4e..aff0440b499b 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_isoc.c +++ b/components/usb/test_apps/hcd/main/test_hcd_isoc.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include "soc/usb_dwc_cfg.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "unity.h" @@ -18,6 +19,7 @@ #define ISOC_PACKET_SIZE MOCK_ISOC_EP_MPS #define URB_DATA_BUFF_SIZE (NUM_PACKETS_PER_URB * ISOC_PACKET_SIZE) #define POST_ENQUEUE_DELAY_US 20 +#define ENQUEUE_DELAY (OTG_HSPHY_INTERFACE ? 100 : 500) // With this delay we want to enqueue the URBs at different times /* Test HCD ISOC pipe URBs @@ -95,6 +97,108 @@ TEST_CASE("Test HCD isochronous pipe URBs", "[isoc][full_speed]") test_hcd_wait_for_disconn(port_hdl, false); } +/* +Test HCD ISOC pipe URBs with all channels and intervals combinations + +Purpose: + - Test that the ISOC scheduler correctly schedules all channels and intervals + +Procedure: + - Setup HCD and wait for connection + - Allocate default pipe and enumerate the device + - Allocate an isochronous pipe and multiple URBs. Each URB should contain multiple packets to test HCD's ability to + schedule an URB across multiple intervals. + - Repeat for all channels and intervals + - Enqueue those URBs + - Expect HCD_PIPE_EVENT_URB_DONE for each URB. Verify that data is correct using logic analyzer + - Deallocate URBs + - Teardown +*/ +TEST_CASE("Test HCD isochronous pipe URBs all", "[isoc][full_speed]") +{ + usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection + //The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing + TEST_ASSERT_EQUAL(ESP_OK, hcd_port_set_fifo_bias(port_hdl, HCD_PORT_FIFO_BIAS_PTX)); + vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS) + + //Enumerate and reset device + hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor) + uint8_t dev_addr = test_hcd_enum_device(default_pipe); + + urb_t *urb_list[NUM_URBS]; + hcd_pipe_handle_t unused_pipes[OTG_NUM_HOST_CHAN]; + + // For all channels + for (int channel = 0; channel < OTG_NUM_HOST_CHAN - 1; channel++) { + // Allocate unused pipes, so the active isoc_out_pipe uses different channel index + for (int ch = 0; ch < channel; ch++) { + unused_pipes[ch] = test_hcd_pipe_alloc(port_hdl, &mock_isoc_out_ep_desc, dev_addr + 1, port_speed); + } + + // For all intervals + for (int interval = 1; interval <= 6; interval++) { + + vTaskDelay(5); + unsigned num_packets_per_urb = 32; // This is maximum number of packets if interval = 1. This is limited by FRAME_LIST_LEN + num_packets_per_urb >>= (interval - 1); + //Create ISOC OUT pipe + usb_ep_desc_t isoc_out_ep = mock_isoc_out_ep_desc; // Implicit copy + isoc_out_ep.bInterval = interval; + isoc_out_ep.bEndpointAddress = interval; // So you can see the bInterval value in trace + hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &isoc_out_ep, channel + 1, port_speed); // Channel number represented in dev_num, so you can see it in trace + + //Initialize URBs + for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { + urb_list[urb_idx] = test_hcd_alloc_urb(num_packets_per_urb, num_packets_per_urb * ISOC_PACKET_SIZE); + urb_list[urb_idx]->transfer.num_bytes = num_packets_per_urb * ISOC_PACKET_SIZE; + urb_list[urb_idx]->transfer.context = URB_CONTEXT_VAL; + for (int pkt_idx = 0; pkt_idx < num_packets_per_urb; pkt_idx++) { + urb_list[urb_idx]->transfer.isoc_packet_desc[pkt_idx].num_bytes = ISOC_PACKET_SIZE; + //Each packet will consist of the same byte, but each subsequent packet's byte will increment (i.e., packet 0 transmits all 0x0, packet 1 transmits all 0x1) + memset(&urb_list[urb_idx]->transfer.data_buffer[pkt_idx * ISOC_PACKET_SIZE], (urb_idx * num_packets_per_urb) + pkt_idx, ISOC_PACKET_SIZE); + } + } + + // Add a delay so we start scheduling the transactions at different time in USB frame + esp_rom_delay_us(ENQUEUE_DELAY * interval + ENQUEUE_DELAY * channel); + + //Enqueue URBs + for (int i = 0; i < NUM_URBS; i++) { + TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(isoc_out_pipe, urb_list[i])); + } + //Wait for each done event from each URB + for (int i = 0; i < NUM_URBS; i++) { + test_hcd_expect_pipe_event(isoc_out_pipe, HCD_PIPE_EVENT_URB_DONE); + } + //Dequeue URBs + for (int urb_idx = 0; urb_idx < NUM_URBS; urb_idx++) { + urb_t *urb = hcd_urb_dequeue(isoc_out_pipe); + TEST_ASSERT_EQUAL(urb_list[urb_idx], urb); + TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context); + //Overall URB status and overall number of bytes + TEST_ASSERT_EQUAL(num_packets_per_urb * ISOC_PACKET_SIZE, urb->transfer.actual_num_bytes); + TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed"); + for (int pkt_idx = 0; pkt_idx < num_packets_per_urb; pkt_idx++) { + TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.isoc_packet_desc[pkt_idx].status, "Transfer NOT completed"); + } + } + //Free URB list and pipe + for (int i = 0; i < NUM_URBS; i++) { + test_hcd_free_urb(urb_list[i]); + } + test_hcd_pipe_free(isoc_out_pipe); + } + + // Free unused pipes + for (int ch = 0; ch < channel; ch++) { + test_hcd_pipe_free(unused_pipes[ch]); + } + } + test_hcd_pipe_free(default_pipe); + //Cleanup + test_hcd_wait_for_disconn(port_hdl, false); +} + /* Test a port sudden disconnect with an active ISOC pipe From f9800e0726d628e99bc380d947a9ce3ea56d1e56 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Thu, 11 Jan 2024 20:59:08 +0800 Subject: [PATCH 24/33] feat(efuse): Move efuse-related init steps into the component --- components/efuse/CMakeLists.txt | 12 +- components/efuse/src/esp_efuse_startup.c | 157 ++++++++++++++++++ components/efuse/src/esp_efuse_utility.c | 10 +- components/esp_app_format/esp_app_desc.c | 8 - components/esp_system/CMakeLists.txt | 4 +- components/esp_system/port/cpu_start.c | 5 - .../port/soc/esp32/system_internal.c | 1 - .../port/soc/esp32c2/system_internal.c | 1 - .../port/soc/esp32c3/system_internal.c | 1 - .../port/soc/esp32s2/system_internal.c | 1 - components/esp_system/startup_funcs.c | 92 ---------- components/esp_system/system_init_fn.txt | 7 +- .../system/g1_components/CMakeLists.txt | 6 +- 13 files changed, 178 insertions(+), 127 deletions(-) create mode 100644 components/efuse/src/esp_efuse_startup.c diff --git a/components/efuse/CMakeLists.txt b/components/efuse/CMakeLists.txt index 123ea9f09e2a..464b624c2734 100644 --- a/components/efuse/CMakeLists.txt +++ b/components/efuse/CMakeLists.txt @@ -32,10 +32,20 @@ list(APPEND srcs "src/esp_efuse_api.c" "src/esp_efuse_utility.c" "src/efuse_controller/keys/${type}/esp_efuse_api_key.c") -idf_component_register(SRCS "${srcs}" +if(BOOTLOADER_BUILD) + idf_component_register(SRCS "${srcs}" PRIV_REQUIRES bootloader_support soc spi_flash INCLUDE_DIRS "${include_dirs}" PRIV_INCLUDE_DIRS "${private_include}") +else() + list(APPEND srcs "src/esp_efuse_startup.c") + idf_component_register(SRCS "${srcs}" + PRIV_REQUIRES bootloader_support soc spi_flash esp_system esp_partition esp_app_format + INCLUDE_DIRS "${include_dirs}" + PRIV_INCLUDE_DIRS "${private_include}") + # Forces the linker to include esp_efuse_startup.c + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_efuse_startup_include_func") +endif() if(target) set(TOOL_TARGET -t ${target}) diff --git a/components/efuse/src/esp_efuse_startup.c b/components/efuse/src/esp_efuse_startup.c new file mode 100644 index 000000000000..4734ed3e0f95 --- /dev/null +++ b/components/efuse/src/esp_efuse_startup.c @@ -0,0 +1,157 @@ +/* + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" +#include "hal/efuse_hal.h" +#include "rom/efuse.h" +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "esp_check.h" +#include "esp_efuse_utility.h" +#include "esp_system.h" +#include "esp_flash_encrypt.h" +#include "esp_secure_boot.h" +#include "esp_log.h" +#include "esp_private/startup_internal.h" +#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH +#include "esp_partition.h" +#endif +#include "sdkconfig.h" + +#if __has_include("esp_app_desc.h") +#include "esp_app_desc.h" +#endif + +static __attribute__((unused)) const char *TAG = "efuse_init"; + +ESP_SYSTEM_INIT_FN(init_efuse_check, CORE, BIT(0), 1) +{ + // (Only for C3): We check if the efuse BLOCK0 has certain coding errors then reset the chip. + if (esp_efuse_check_errors() != ESP_OK) { + esp_restart(); + } + return ESP_OK; +} + +// It comes after init_show_app_info to print the consistent application information. +ESP_SYSTEM_INIT_FN(init_efuse_show_app_info, CORE, BIT(0), 21) +{ + if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { + ESP_EARLY_LOGI(TAG, "Min chip rev: v%d.%d", CONFIG_ESP_REV_MIN_FULL / 100, CONFIG_ESP_REV_MIN_FULL % 100); + ESP_EARLY_LOGI(TAG, "Max chip rev: v%d.%d %s", CONFIG_ESP_REV_MAX_FULL / 100, CONFIG_ESP_REV_MAX_FULL % 100, + efuse_hal_get_disable_wafer_version_major() ? "(constraint ignored)" : ""); + unsigned revision = efuse_hal_chip_revision(); + ESP_EARLY_LOGI(TAG, "Chip rev: v%d.%d", revision / 100, revision % 100); + } + return ESP_OK; +} + +#ifdef CONFIG_EFUSE_VIRTUAL +static void init_efuse_virtual(void) +{ + ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); +#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH + // For efuse virtual mode we need to seed virtual efuses from flash + // esp_flash must be initialized in advance because here we read the efuse partition. + const esp_partition_t *efuse_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_EFUSE_EM, NULL); + if (efuse_partition) { + esp_efuse_init_virtual_mode_in_flash(efuse_partition->address, efuse_partition->size); + } +#else // !CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH + // For efuse virtual mode we need to seed virtual efuses from efuse_regs. + esp_efuse_utility_update_virt_blocks(); +#endif // !CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH +} +#endif // CONFIG_EFUSE_VIRTUAL + +static esp_err_t init_efuse_secure(void) +{ +#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK + // For anti-rollback case, recheck security version before we boot-up the current application + const esp_app_desc_t *desc = esp_app_get_description(); + ESP_RETURN_ON_FALSE(esp_efuse_check_secure_version(desc->secure_version), ESP_FAIL, TAG, "Incorrect secure version of app"); +#endif + +#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED + esp_flash_encryption_init_checks(); +#endif + +#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT) + // Note: in some configs this may read flash, so placed after flash init + esp_secure_boot_init_checks(); +#endif + +#if SOC_EFUSE_ECDSA_USE_HARDWARE_K + if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY, NULL)) { + // ECDSA key purpose block is present and hence permanently enable + // the hardware TRNG supplied k mode (most secure mode) + ESP_RETURN_ON_ERROR(esp_efuse_write_field_bit(ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K), TAG, "Failed to enable hardware k mode"); + } +#endif + +#if CONFIG_SECURE_DISABLE_ROM_DL_MODE + // Permanently disable ROM download mode + ESP_RETURN_ON_ERROR(esp_efuse_disable_rom_download_mode(), TAG, "Failed to disable ROM download mode"); +#endif + +#if CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE + // Permanently disable ROM secure download mode + ESP_RETURN_ON_ERROR(esp_efuse_enable_rom_secure_download_mode(), TAG, "Failed to enable Secure Download mode"); +#endif + +#if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE + // ESP32 only: Permanently disable BASIC ROM Console feature + esp_efuse_disable_basic_rom_console(); +#endif + return ESP_OK; +} + +// Set efuse ROM_LOG_MODE on first boot +// For CONFIG_BOOT_ROM_LOG_ALWAYS_ON (default) or undefined (ESP32), leave +// ROM_LOG_MODE undefined (no need to call this function during startup) +#if CONFIG_BOOT_ROM_LOG_ALWAYS_OFF +#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ALWAYS_OFF +#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW +#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_LOW +#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH +#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_HIGH +#endif + +#ifdef ROM_LOG_MODE +static esp_err_t init_efuse_rom_log(void) +{ + // Applicable for any chips except ESP32: Permanently disable ROM startup logs + if (ets_efuse_get_uart_print_control() != ROM_LOG_MODE) { + esp_err_t error = esp_efuse_set_rom_log_scheme(ROM_LOG_MODE); + error = (error == ESP_ERR_NOT_SUPPORTED) ? ESP_OK : error; + ESP_RETURN_ON_ERROR(error, TAG, "Failed to set ROM log scheme"); + } + return ESP_OK; +} +#endif // ROM_LOG_MODE + +ESP_SYSTEM_INIT_FN(init_efuse, CORE, BIT(0), 140) +{ + esp_err_t error = ESP_OK; + +#ifdef CONFIG_EFUSE_VIRTUAL + init_efuse_virtual(); +#endif + + error = init_efuse_secure(); + ESP_RETURN_ON_ERROR(error, TAG, "Failed in secure eFuse init"); + +#ifdef ROM_LOG_MODE + error = init_efuse_rom_log(); +#endif + + return error; +} + +void esp_efuse_startup_include_func(void) +{ + // Hook to force the linker to include this file +} diff --git a/components/efuse/src/esp_efuse_utility.c b/components/efuse/src/esp_efuse_utility.c index 941b91b7c38b..e01190a824ff 100644 --- a/components/efuse/src/esp_efuse_utility.c +++ b/components/efuse/src/esp_efuse_utility.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,14 +23,6 @@ static volatile unsigned s_burn_counter = 0; // Array for emulate efuse registers. #ifdef CONFIG_EFUSE_VIRTUAL uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK]; - -#ifndef BOOTLOADER_BUILD -#ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH -/* Call the update function to seed virtual efuses during initialization */ -__attribute__((constructor)) void esp_efuse_utility_update_virt_blocks(void); -#endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH -#endif // NOT BOOTLOADER_BUILD - #endif // CONFIG_EFUSE_VIRTUAL extern const esp_efuse_range_addr_t range_read_addr_blocks[]; diff --git a/components/esp_app_format/esp_app_desc.c b/components/esp_app_format/esp_app_desc.c index 075e6f426576..1f468fc2343e 100644 --- a/components/esp_app_format/esp_app_desc.c +++ b/components/esp_app_format/esp_app_desc.c @@ -10,7 +10,6 @@ #include "esp_app_desc.h" #include "sdkconfig.h" -#include "hal/efuse_hal.h" #include "esp_log.h" #include "esp_private/startup_internal.h" @@ -125,13 +124,6 @@ ESP_SYSTEM_INIT_FN(init_show_app_info, CORE, BIT(0), 20) esp_app_get_elf_sha256(buf, sizeof(buf)); ESP_EARLY_LOGI(TAG, "ELF file SHA256: %s...", buf); ESP_EARLY_LOGI(TAG, "ESP-IDF: %s", esp_app_desc.idf_ver); - - // TODO: To be moved to the eFuse initialization routine - ESP_EARLY_LOGI(TAG, "Min chip rev: v%d.%d", CONFIG_ESP_REV_MIN_FULL / 100, CONFIG_ESP_REV_MIN_FULL % 100); - ESP_EARLY_LOGI(TAG, "Max chip rev: v%d.%d %s", CONFIG_ESP_REV_MAX_FULL / 100, CONFIG_ESP_REV_MAX_FULL % 100, - efuse_hal_get_disable_wafer_version_major() ? "(constraint ignored)" : ""); - unsigned revision = efuse_hal_chip_revision(); - ESP_EARLY_LOGI(TAG, "Chip rev: v%d.%d", revision / 100, revision % 100); } return ESP_OK; } diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index a3276ad2c2d0..4aec377dcb78 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -67,9 +67,7 @@ else() # [refactor-todo] requirements due to init code, # should be removable once using component init functions # link-time registration is used. - # [refactor-todo] esp_partition required for virtual efuse - # init code. Move to esp_efuse component. - bootloader_support efuse esp_partition esp_pm + bootloader_support esp_pm LDFRAGMENTS "linker.lf" "app.lf") add_subdirectory(port) diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index aef3bd3633f8..2e6d5f29f640 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -14,11 +14,9 @@ #include "esp_log.h" #include "esp_chip_info.h" -#include "esp_efuse.h" #include "esp_private/cache_err_int.h" #include "esp_clk_internal.h" -#include "esp_rom_efuse.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" #include "esp_rom_caps.h" @@ -499,9 +497,6 @@ void IRAM_ATTR call_start_cpu0(void) extern void esp_config_l2_cache_mode(void); esp_config_l2_cache_mode(); #endif - if (esp_efuse_check_errors() != ESP_OK) { - esp_restart(); - } #if ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE #if CONFIG_APP_BUILD_TYPE_ELF_RAM diff --git a/components/esp_system/port/soc/esp32/system_internal.c b/components/esp_system/port/soc/esp32/system_internal.c index 6a051a56e286..e0e837e3faad 100644 --- a/components/esp_system/port/soc/esp32/system_internal.c +++ b/components/esp_system/port/soc/esp32/system_internal.c @@ -8,7 +8,6 @@ #include "esp_system.h" #include "esp_private/system_internal.h" #include "esp_attr.h" -#include "esp_efuse.h" #include "esp_log.h" #include "esp_ipc_isr.h" #include "sdkconfig.h" diff --git a/components/esp_system/port/soc/esp32c2/system_internal.c b/components/esp_system/port/soc/esp32c2/system_internal.c index 1bf0b847cde4..c9ef82971cbe 100644 --- a/components/esp_system/port/soc/esp32c2/system_internal.c +++ b/components/esp_system/port/soc/esp32c2/system_internal.c @@ -9,7 +9,6 @@ #include "esp_system.h" #include "esp_private/system_internal.h" #include "esp_attr.h" -#include "esp_efuse.h" #include "esp_log.h" #include "riscv/rv_utils.h" #include "esp_rom_uart.h" diff --git a/components/esp_system/port/soc/esp32c3/system_internal.c b/components/esp_system/port/soc/esp32c3/system_internal.c index f93a470c898b..15273a9b9367 100644 --- a/components/esp_system/port/soc/esp32c3/system_internal.c +++ b/components/esp_system/port/soc/esp32c3/system_internal.c @@ -9,7 +9,6 @@ #include "esp_system.h" #include "esp_private/system_internal.h" #include "esp_attr.h" -#include "esp_efuse.h" #include "esp_log.h" #include "riscv/rv_utils.h" #include "esp_rom_uart.h" diff --git a/components/esp_system/port/soc/esp32s2/system_internal.c b/components/esp_system/port/soc/esp32s2/system_internal.c index 1c3f3ed48275..2a8d985d392c 100644 --- a/components/esp_system/port/soc/esp32s2/system_internal.c +++ b/components/esp_system/port/soc/esp32s2/system_internal.c @@ -9,7 +9,6 @@ #include "esp_system.h" #include "esp_private/system_internal.h" #include "esp_attr.h" -#include "esp_efuse.h" #include "esp_log.h" #include "esp32s2/rom/cache.h" #include "esp_rom_uart.h" diff --git a/components/esp_system/startup_funcs.c b/components/esp_system/startup_funcs.c index 58f0bcfdef5b..3468f6cc977a 100644 --- a/components/esp_system/startup_funcs.c +++ b/components/esp_system/startup_funcs.c @@ -17,11 +17,6 @@ #include "spi_flash_mmap.h" #include "esp_flash_internal.h" #include "esp_newlib.h" -#include "esp_efuse.h" -#include "esp_efuse_table.h" -#include "esp_flash_encrypt.h" -#include "esp_partition.h" -#include "esp_secure_boot.h" #include "esp_xt_wdt.h" #include "esp_cpu.h" #include "esp_private/startup_internal.h" @@ -29,16 +24,11 @@ #include "hal/wdt_hal.h" #include "hal/uart_types.h" #include "hal/uart_ll.h" -#include "hal/efuse_hal.h" #if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE #include "private/esp_coexist_internal.h" #endif -#if __has_include("esp_app_desc.h") -#include "esp_app_desc.h" -#endif - #if CONFIG_PM_ENABLE #include "esp_pm.h" #include "esp_private/pm_impl.h" @@ -132,88 +122,6 @@ ESP_SYSTEM_INIT_FN(init_flash, CORE, BIT(0), 130) } #endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP -#ifdef CONFIG_EFUSE_VIRTUAL -ESP_SYSTEM_INIT_FN(init_virtual_efuse, CORE, BIT(0), 140) -{ - ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!"); -#ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH - const esp_partition_t *efuse_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_EFUSE_EM, NULL); - if (efuse_partition) { - esp_efuse_init_virtual_mode_in_flash(efuse_partition->address, efuse_partition->size); - } -#endif - return ESP_OK; -} -#endif // CONFIG_EFUSE_VIRTUAL - -ESP_SYSTEM_INIT_FN(init_secure, CORE, BIT(0), 150) -{ -#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK - // For anti-rollback case, recheck security version before we boot-up the current application - const esp_app_desc_t *desc = esp_app_get_description(); - ESP_RETURN_ON_FALSE(esp_efuse_check_secure_version(desc->secure_version), ESP_FAIL, TAG, "Incorrect secure version of app"); -#endif - -#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED - esp_flash_encryption_init_checks(); -#endif - -#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT) - // Note: in some configs this may read flash, so placed after flash init - esp_secure_boot_init_checks(); -#endif - -#if SOC_EFUSE_ECDSA_USE_HARDWARE_K - if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY, NULL)) { - // ECDSA key purpose block is present and hence permanently enable - // the hardware TRNG supplied k mode (most secure mode) - ESP_RETURN_ON_ERROR(esp_efuse_write_field_bit(ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K), TAG, "Failed to enable hardware k mode"); - } -#endif - -#if CONFIG_SECURE_DISABLE_ROM_DL_MODE - ESP_RETURN_ON_ERROR(esp_efuse_disable_rom_download_mode(), TAG, "Failed to disable ROM download mode"); -#endif - -#if CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE - ESP_RETURN_ON_ERROR(esp_efuse_enable_rom_secure_download_mode(), TAG, "Failed to enable Secure Download mode"); -#endif - -#if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE - esp_efuse_disable_basic_rom_console(); -#endif - return ESP_OK; -} - -// Set efuse ROM_LOG_MODE on first boot -// -// For CONFIG_BOOT_ROM_LOG_ALWAYS_ON (default) or undefined (ESP32), leave -// ROM_LOG_MODE undefined (no need to call this function during startup) -#if CONFIG_BOOT_ROM_LOG_ALWAYS_OFF -#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ALWAYS_OFF -#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW -#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_LOW -#elif CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH -#define ROM_LOG_MODE ESP_EFUSE_ROM_LOG_ON_GPIO_HIGH -#endif - -#ifdef ROM_LOG_MODE -ESP_SYSTEM_INIT_FN(init_rom_log, CORE, BIT(0), 160) -{ - if (ets_efuse_get_uart_print_control() == ROM_LOG_MODE) { - return ESP_OK; - } - - esp_err_t err = esp_efuse_set_rom_log_scheme(ROM_LOG_MODE); - - if (err == ESP_ERR_NOT_SUPPORTED) { - err = ESP_OK; - } - ESP_RETURN_ON_ERROR(err, TAG, "Failed to set ROM log scheme"); - return ESP_OK; -} -#endif // ROM_LOG_MODE - #if CONFIG_ESP_XT_WDT ESP_SYSTEM_INIT_FN(init_xt_wdt, CORE, BIT(0), 170) { diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 51db470feb84..0a89e1f84487 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -17,9 +17,12 @@ ########### CORE startup stage ########### # [refactor-todo]: move init calls into respective components +CORE: 1: init_efuse_check in components/efuse/src/esp_efuse_startup.c on BIT(0) + # Log some information about the system CORE: 10: init_show_cpu_freq in components/esp_system/startup_funcs.c on BIT(0) CORE: 20: init_show_app_info in components/esp_app_format/esp_app_desc.c on BIT(0) +CORE: 21: init_efuse_show_app_info in components/efuse/src/esp_efuse_startup.c on BIT(0) # Initialize heap allocator. WARNING: This *needs* to happen *after* the app cpu has booted. # If the heap allocator is initialized first, it will put free memory linked list items into @@ -52,9 +55,7 @@ CORE: 115: init_newlib_stdio in components/newlib/newlib_init.c on BIT(0) CORE: 120: init_pthread in components/pthread/pthread.c on BIT(0) CORE: 130: init_flash in components/esp_system/startup_funcs.c on BIT(0) -CORE: 140: init_virtual_efuse in components/esp_system/startup_funcs.c on BIT(0) -CORE: 150: init_secure in components/esp_system/startup_funcs.c on BIT(0) -CORE: 160: init_rom_log in components/esp_system/startup_funcs.c on BIT(0) +CORE: 140: init_efuse in components/efuse/src/esp_efuse_startup.c on BIT(0) CORE: 170: init_xt_wdt in components/esp_system/startup_funcs.c on BIT(0) diff --git a/tools/test_apps/system/g1_components/CMakeLists.txt b/tools/test_apps/system/g1_components/CMakeLists.txt index eec4ebf160ea..d7dd5d24a072 100644 --- a/tools/test_apps/system/g1_components/CMakeLists.txt +++ b/tools/test_apps/system/g1_components/CMakeLists.txt @@ -40,8 +40,10 @@ set(extra_components_which_shouldnt_be_included esp_app_format # esp_bootloader_format is dependency of bootloader_support, app_update esp_bootloader_format - # [refactor-todo]: efuse is a dependency of esp_hw_support, esp_system. - # Figure out if these components can exist without a dependency on efuse. + # [refactor-todo]: + # Figure out if the esp_hw_support component can exist without a dependency on efuse. + # efuse is used by the ADC calibration functions in esp_hw_support/adc_share_hw_ctrl.c, + # it could use the efuse hal (if virtual efuse mode is not used for tests). # If not, see if esp_hw_support can provide minimal efuse component replacement in G1 build. efuse # esp_pm is pulled in by freertos, can be made a weak dependency From 943ebe2ca2918d882493353cd983a9d09b8edf83 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Thu, 29 Feb 2024 18:31:40 +0800 Subject: [PATCH 25/33] docs(temperature_sensor): Add new documents for temperature sensor ETM on ESP32C6/H2 --- .../include/driver/temperature_sensor_etm.h | 12 +++++------ .../esp_driver_tsens/src/temperature_sensor.c | 8 +++---- .../main/test_temperature_etm.c | 10 ++++++--- .../main/test_temperature_sensor.c | 2 +- docs/doxygen/Doxyfile | 2 ++ docs/en/api-reference/peripherals/etm.rst | 2 ++ .../api-reference/peripherals/temp_sensor.rst | 21 +++++++++++++++++++ .../main/temp_sensor_monitor_main.c | 2 +- 8 files changed, 44 insertions(+), 15 deletions(-) diff --git a/components/esp_driver_tsens/include/driver/temperature_sensor_etm.h b/components/esp_driver_tsens/include/driver/temperature_sensor_etm.h index 3e030375d587..34c395a22fa9 100644 --- a/components/esp_driver_tsens/include/driver/temperature_sensor_etm.h +++ b/components/esp_driver_tsens/include/driver/temperature_sensor_etm.h @@ -47,15 +47,15 @@ typedef struct { /** * @brief Get the ETM task for Temperature Sensor * - * @note The created ETM event object can be deleted later by calling `esp_etm_del_event` + * @note The created ETM task object can be deleted later by calling `esp_etm_del_task` * * @param[in] tsens Temperature Sensor, allocated by `temperature_sensor_install()` - * @param[in] config Temperature Sensor ETM event configuration - * @param[out] out_task Returned ETM event handle + * @param[in] config Temperature Sensor ETM task configuration + * @param[out] out_task Returned ETM task handle * @return - * - ESP_OK: Get ETM event successfully - * - ESP_ERR_INVALID_ARG: Get ETM event failed because of invalid argument - * - ESP_FAIL: Get ETM event failed because of other error + * - ESP_OK: Get ETM task successfully + * - ESP_ERR_INVALID_ARG: Get ETM task failed because of invalid argument + * - ESP_FAIL: Get ETM task failed because of other error */ esp_err_t temperature_sensor_new_etm_task(temperature_sensor_handle_t tsens, const temperature_sensor_etm_task_config_t *config, esp_etm_task_handle_t *out_task); diff --git a/components/esp_driver_tsens/src/temperature_sensor.c b/components/esp_driver_tsens/src/temperature_sensor.c index b8067bcc99d1..584f15e36439 100644 --- a/components/esp_driver_tsens/src/temperature_sensor.c +++ b/components/esp_driver_tsens/src/temperature_sensor.c @@ -103,7 +103,7 @@ esp_err_t temperature_sensor_install(const temperature_sensor_config_t *tsens_co ESP_RETURN_ON_FALSE((s_tsens_attribute_copy == NULL), ESP_ERR_INVALID_STATE, TAG, "Already installed"); temperature_sensor_handle_t tsens = NULL; tsens = (temperature_sensor_obj_t *) heap_caps_calloc(1, sizeof(temperature_sensor_obj_t), MALLOC_CAP_DEFAULT); - ESP_GOTO_ON_FALSE(tsens != NULL, ESP_ERR_NO_MEM, err, TAG, "no mem for temp sensor"); + ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_NO_MEM, TAG, "no mem for temp sensor"); tsens->clk_src = tsens_config->clk_src; temperature_sensor_power_acquire(); @@ -260,7 +260,7 @@ esp_err_t temperature_sensor_set_absolute_threshold(temperature_sensor_handle_t { esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed"); - ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in enable state"); + ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state"); ESP_RETURN_ON_FALSE(abs_cfg, ESP_ERR_INVALID_ARG, TAG, "Invalid callback configuration"); temperature_sensor_ll_set_sample_rate(0xffff); @@ -275,7 +275,7 @@ esp_err_t temperature_sensor_set_delta_threshold(temperature_sensor_handle_t tse { esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed"); - ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in enable state"); + ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state"); ESP_RETURN_ON_FALSE(delta_cfg, ESP_ERR_INVALID_ARG, TAG, "Invalid callback configuration"); temperature_sensor_ll_set_sample_rate(0xffff); @@ -290,7 +290,7 @@ esp_err_t temperature_sensor_register_callbacks(temperature_sensor_handle_t tsen { esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE((tsens != NULL), ESP_ERR_INVALID_ARG, TAG, "Temperature sensor has not been installed"); - ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in enable state"); + ESP_RETURN_ON_FALSE(tsens->fsm == TEMP_SENSOR_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "temperature sensor is not in init state"); ESP_RETURN_ON_FALSE(cbs, ESP_ERR_INVALID_ARG, TAG, "callback group pointer is invalid"); #if CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_etm.c b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_etm.c index e9eb171932a7..d036d4ef9c41 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_etm.c +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_etm.c @@ -15,10 +15,14 @@ #include "driver/temperature_sensor.h" #include "soc/soc_etm_struct.h" +// To run this example, you need a facility that can make the temperature change +// on board. Like a heat gun. +// Then after the temperature meet the threshold, you can see the gpio level changes +// from 0 to 1 on logic analyzer or oscilloscope. TEST_CASE("temperature sensor alarm cause gpio pull up", "[etm]") { const uint32_t output_gpio = 5; - // temperature sensor alarm ---> ETM channel A ---> GPIO toggle + // temperature sensor alarm ---> ETM channel A ---> GPIO level to high printf("allocate etm channel\r\n"); esp_etm_channel_config_t etm_config = {}; esp_etm_channel_handle_t etm_channel_a; @@ -27,7 +31,7 @@ TEST_CASE("temperature sensor alarm cause gpio pull up", "[etm]") printf("allocate GPIO etm task\r\n"); esp_etm_task_handle_t gpio_task = NULL; gpio_etm_task_config_t gpio_task_config = { - .action = GPIO_ETM_TASK_ACTION_TOG, + .action = GPIO_ETM_TASK_ACTION_SET, }; TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config, &gpio_task)); // set gpio number for the gpio etm primitives @@ -46,13 +50,13 @@ TEST_CASE("temperature sensor alarm cause gpio pull up", "[etm]") temperature_sensor_config_t temp_sensor = TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50); temperature_sensor_handle_t temp_handle = NULL; TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle)); - TEST_ESP_OK(temperature_sensor_enable(temp_handle)); temperature_sensor_abs_threshold_config_t threshold_cfg = { .high_threshold = 50, .low_threshold = -10, }; TEST_ESP_OK(temperature_sensor_set_absolute_threshold(temp_handle, &threshold_cfg)); + TEST_ESP_OK(temperature_sensor_enable(temp_handle)); printf("Temperature sensor started\n"); temperature_sensor_etm_event_config_t tsens_etm_event = { diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.c b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.c index 37c1b7e81a8a..6bc7fe4e86ea 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.c +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/main/test_temperature_sensor.c @@ -110,7 +110,6 @@ TEST_CASE("Temperature sensor callback test", "[temperature_sensor]") temperature_sensor_config_t temp_sensor = TEMPERATURE_SENSOR_CONFIG_DEFAULT(10, 50); temperature_sensor_handle_t temp_handle = NULL; TEST_ESP_OK(temperature_sensor_install(&temp_sensor, &temp_handle)); - TEST_ESP_OK(temperature_sensor_enable(temp_handle)); temperature_sensor_event_callbacks_t cbs = { .on_threshold = temp_sensor_cbs_test, @@ -125,6 +124,7 @@ TEST_CASE("Temperature sensor callback test", "[temperature_sensor]") TEST_ESP_OK(temperature_sensor_set_absolute_threshold(temp_handle, &threshold_cfg)); temperature_sensor_register_callbacks(temp_handle, &cbs, &temperature_alarm); + TEST_ESP_OK(temperature_sensor_enable(temp_handle)); #if CONFIG_TEMP_SENSOR_ISR_IRAM_SAFE printf("disable flash cache and check if we can still get temperature intr\r\n"); for (int i = 0; i < 100; i++) { diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 747685533862..278eb6180863 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -143,6 +143,7 @@ INPUT = \ $(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_slave_hd.h \ $(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_slave.h \ $(PROJECT_PATH)/components/esp_driver_tsens/include/driver/temperature_sensor.h \ + $(PROJECT_PATH)/components/esp_driver_tsens/include/driver/temperature_sensor_etm.h \ $(PROJECT_PATH)/components/esp_driver_uart/include/driver/uart.h \ $(PROJECT_PATH)/components/esp_driver_uart/include/driver/uart_vfs.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \ @@ -251,6 +252,7 @@ INPUT = \ $(PROJECT_PATH)/components/hal/include/hal/sdm_types.h \ $(PROJECT_PATH)/components/hal/include/hal/spi_flash_types.h \ $(PROJECT_PATH)/components/hal/include/hal/spi_types.h \ + $(PROJECT_PATH)/components/hal/include/hal/temperature_sensor_types.h \ $(PROJECT_PATH)/components/hal/include/hal/timer_types.h \ $(PROJECT_PATH)/components/hal/include/hal/touch_sensor_types.h \ $(PROJECT_PATH)/components/hal/include/hal/twai_types.h \ diff --git a/docs/en/api-reference/peripherals/etm.rst b/docs/en/api-reference/peripherals/etm.rst index bca698df5dfc..8c9d901881d2 100644 --- a/docs/en/api-reference/peripherals/etm.rst +++ b/docs/en/api-reference/peripherals/etm.rst @@ -71,6 +71,7 @@ Other Peripheral Events :SOC_GDMA_SUPPORT_ETM: - Refer to :doc:`/api-reference/system/async_memcpy` for how to get the ETM event handle from async memcpy. :SOC_MCPWM_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/mcpwm` for how to get the ETM event handle from MCPWM. :SOC_ANA_CMPR_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/ana_cmpr` for how to get the ETM event handle from analog comparator. + :SOC_TEMPERATURE_SENSOR_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/temp_sensor` for how to get the ETM event handle from temperature sensor. .. _etm-task: @@ -96,6 +97,7 @@ Other Peripheral Tasks .. list:: :SOC_TIMER_SUPPORT_ETM: - Refer to :doc:`GPTimer ` for how to get the ETM task handle from GPTimer. + :SOC_TEMPERATURE_SENSOR_SUPPORT_ETM: - Refer to :doc:`/api-reference/peripherals/temp_sensor` for how to get the ETM task handle from temperature sensor. .. _etm-channel-control: diff --git a/docs/en/api-reference/peripherals/temp_sensor.rst b/docs/en/api-reference/peripherals/temp_sensor.rst index 13ceb154e330..5a0be3676aa6 100644 --- a/docs/en/api-reference/peripherals/temp_sensor.rst +++ b/docs/en/api-reference/peripherals/temp_sensor.rst @@ -46,6 +46,7 @@ The description of the temperature sensor functionality is divided into the foll - :ref:`temp-power-management` - covers how the temperature sensor is affected when changing power mode (e.g., Light-sleep mode). :SOC_TEMPERATURE_SENSOR_INTR_SUPPORT: - :ref:`temp-iram-safe` - describes tips on how to make the temperature sensor interrupt work better along with a disabled cache. - :ref:`temp-thread-safety` - covers how to make the driver to be thread-safe. + :SOC_TEMPERATURE_SENSOR_SUPPORT_ETM: - :ref:`temperature-sensor-etm-event-and-task` - describes what the events and tasks can be connected to the ETM channel. .. _temp-resource-allocation: @@ -180,6 +181,21 @@ Thread Safety In the temperature sensor driver, we do not add any protection to ensure the thread safety, because typically this driver is only supposed to be used in one task. If you have to use this driver in different tasks, please add extra locks to protect it. +.. only:: SOC_TEMPERATURE_SENSOR_SUPPORT_ETM + + .. _temperature-sensor-etm-event-and-task: + + ETM Event and Task + ^^^^^^^^^^^^^^^^^^ + + Temperature Sensor is able to generate events that can interact with the :doc:`ETM ` module. The supported events are listed in the :cpp:type:`temperature_sensor_etm_event_type_t`. You can call :cpp:func:`temperature_sensor_new_etm_event` to get the corresponding ETM event handle. The supported tasks are listed in the :cpp:type:`temperature_sensor_etm_task_type_t`. You can call :cpp:func:`temperature_sensor_new_etm_task` to get the corresponding ETM event handle. + + .. note:: + + - :cpp:enumerator:`TEMPERATURE_SENSOR_EVENT_OVER_LIMIT` for :cpp:member:`temperature_sensor_etm_event_type_t::event_type` depends on what kind of threshold you set first. If you set the absolute threshold by :cpp:func:`temperature_sensor_set_absolute_threshold`, then the :cpp:enumerator:`TEMPERATURE_SENSOR_EVENT_OVER_LIMIT` refers to absolute threshold. Likewise, if you set the delta threshold by :cpp:func:`temperature_sensor_set_delta_threshold`, then the :cpp:enumerator:`TEMPERATURE_SENSOR_EVENT_OVER_LIMIT` refers to delta threshold. + + For how to connect the event and task to an ETM channel, please refer to the :doc:`ETM ` documentation. + Unexpected Behaviors -------------------- @@ -202,3 +218,8 @@ API Reference ---------------------------------- .. include-build-file:: inc/temperature_sensor.inc +.. include-build-file:: inc/temperature_sensor_types.inc + +.. only:: SOC_TEMPERATURE_SENSOR_SUPPORT_ETM + + .. include-build-file:: inc/temperature_sensor_etm.inc diff --git a/examples/peripherals/temperature_sensor/temp_sensor_monitor/main/temp_sensor_monitor_main.c b/examples/peripherals/temperature_sensor/temp_sensor_monitor/main/temp_sensor_monitor_main.c index 96e4e981c20d..b75cd5960ce6 100644 --- a/examples/peripherals/temperature_sensor/temp_sensor_monitor/main/temp_sensor_monitor_main.c +++ b/examples/peripherals/temperature_sensor/temp_sensor_monitor/main/temp_sensor_monitor_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ From 4e4be31b4aff222537af24bd24c1f82071ef029c Mon Sep 17 00:00:00 2001 From: Shang Zhou Date: Fri, 1 Mar 2024 15:07:19 +0800 Subject: [PATCH 26/33] docs: sync low-power-mode and usb-serial-jtag-console --- docs/en/api-guides/usb-serial-jtag-console.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/en/api-guides/usb-serial-jtag-console.rst b/docs/en/api-guides/usb-serial-jtag-console.rst index cbcfc4b4657f..23d57436a3e9 100644 --- a/docs/en/api-guides/usb-serial-jtag-console.rst +++ b/docs/en/api-guides/usb-serial-jtag-console.rst @@ -98,23 +98,23 @@ Sleep Mode Considerations The USB Serial/JTAG controller and its associated USB PHY are driven by particular clocks (e.g., APB and USB PHY clock) and belong to a particular power domain (e.g., digital power domain). Thus, any change to the clock and power domains associated with the USB Serial/JTAG controller, such as entering different sleep modes, can affect the controller's operation. -Deep Sleep +Deep-sleep ^^^^^^^^^^ -When entering deep sleep, both the USB Serial/JTAG controller and the USB PHY are powered off, leading to the USB PHY's D+ line no longer being pulled up. As a result: +When entering Deep-sleep, both the USB Serial/JTAG controller and the USB PHY are powered off, leading to the USB PHY's D+ line no longer being pulled up. As a result: -- When entering deep sleep, the USB Serial/JTAG device appears disconnected from the host/PC (even if the USB cable is still physically connected). -- When exiting deep sleep, the USB Serial/JTAG device reconnects to the host/PC. +- When entering Deep-sleep, the USB Serial/JTAG device appears disconnected from the host/PC (even if the USB cable is still physically connected). +- When exiting Deep-sleep, the USB Serial/JTAG device reconnects to the host/PC. -Light Sleep +Light-sleep ^^^^^^^^^^^ .. only:: not SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP -When entering light sleep, the APB and USB PHY clock are gated. Thus, the USB Serial/JTAG controller is no longer able to receive or respond to any USB transactions from the connected host (including periodic CDC Data IN transactions). As a result: +When entering Light-sleep, the APB and USB PHY clock are gated. Thus, the USB Serial/JTAG controller is no longer able to receive or respond to any USB transactions from the connected host (including periodic CDC Data IN transactions). As a result: -- when entering light sleep, the USB Serial/JTAG device is unresponsive to the host/PC's USB CDC driver. The host/PC may then report the USB Serial/JTAG device as disconnected or erroneous (even if the USB cable is still physically connected). -- when exiting light sleep, it is possible that the host/PC does not re-enumerate (i.e., reconnect) the USB Serial/JTAG device given that the USB PHY's D+ line remains pulled up state during light sleep. Users may need to physically disconnect and then reconnect the USB cable. +- when entering Light-sleep, the USB Serial/JTAG device is unresponsive to the host/PC's USB CDC driver. The host/PC may then report the USB Serial/JTAG device as disconnected or erroneous (even if the USB cable is still physically connected). +- when exiting Light-sleep, it is possible that the host/PC does not re-enumerate (i.e., reconnect) the USB Serial/JTAG device given that the USB PHY's D+ line remains pulled up state during Light-sleep. Users may need to physically disconnect and then reconnect the USB cable. Automatic and Manual Sleep Entry ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 37adea9a14584664dd4ef167e00fb955533671cc Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Wed, 25 Oct 2023 15:15:42 +0530 Subject: [PATCH 27/33] feat: add example to re-enable jtag using hmac peripheral --- .../jtag-debugging/tips-and-quirks.rst | 4 + docs/en/api-reference/peripherals/hmac.rst | 2 + examples/security/.build-test-rules.yml | 11 + .../security/hmac_soft_jtag/CMakeLists.txt | 8 + examples/security/hmac_soft_jtag/README.md | 113 ++++++++++ .../hmac_soft_jtag/jtag_example_helper.py | 86 ++++++++ .../hmac_soft_jtag/main/CMakeLists.txt | 2 + .../hmac_soft_jtag/main/Kconfig.projbuild | 13 ++ .../hmac_soft_jtag/main/example_main.c | 43 ++++ .../hmac_soft_jtag/main/jtag_commands.c | 204 ++++++++++++++++++ .../hmac_soft_jtag/main/jtag_commands.h | 8 + .../hmac_soft_jtag/pytest_jtag_example.py | 51 +++++ .../security/hmac_soft_jtag/requirements.txt | 1 + .../hmac_soft_jtag/sdkconfig.defaults | 0 .../hmac_soft_jtag/sdkconfig.defaults.esp32c6 | 3 + tools/ci/idf_pytest/constants.py | 1 + 16 files changed, 550 insertions(+) create mode 100644 examples/security/hmac_soft_jtag/CMakeLists.txt create mode 100644 examples/security/hmac_soft_jtag/README.md create mode 100644 examples/security/hmac_soft_jtag/jtag_example_helper.py create mode 100644 examples/security/hmac_soft_jtag/main/CMakeLists.txt create mode 100644 examples/security/hmac_soft_jtag/main/Kconfig.projbuild create mode 100644 examples/security/hmac_soft_jtag/main/example_main.c create mode 100644 examples/security/hmac_soft_jtag/main/jtag_commands.c create mode 100644 examples/security/hmac_soft_jtag/main/jtag_commands.h create mode 100644 examples/security/hmac_soft_jtag/pytest_jtag_example.py create mode 100644 examples/security/hmac_soft_jtag/requirements.txt create mode 100644 examples/security/hmac_soft_jtag/sdkconfig.defaults create mode 100644 examples/security/hmac_soft_jtag/sdkconfig.defaults.esp32c6 diff --git a/docs/en/api-guides/jtag-debugging/tips-and-quirks.rst b/docs/en/api-guides/jtag-debugging/tips-and-quirks.rst index cde6f6fcd43b..63b0c707fa2d 100644 --- a/docs/en/api-guides/jtag-debugging/tips-and-quirks.rst +++ b/docs/en/api-guides/jtag-debugging/tips-and-quirks.rst @@ -232,6 +232,10 @@ JTAG with Flash Encryption or Secure Boot By default, enabling Flash Encryption and/or Secure Boot will disable JTAG debugging. On first boot, the bootloader will burn an eFuse bit to permanently disable JTAG at the same time it enables the other features. +.. only:: SOC_HMAC_SUPPORTED + + Please note that once JTAG is permanently disabled, it cannot be re-enabled for JTAG access. However, we do have the option of disabling JTAG softly. For more details on soft disabling and re-enabling soft-disabled JTAG, please refer to the :ref:`hmac_for_enabling_jtag`. + The project configuration option :ref:`CONFIG_SECURE_BOOT_ALLOW_JTAG` will keep JTAG enabled at this time, removing all physical security but allowing debugging. (Although the name suggests Secure Boot, this option can be applied even when only Flash Encryption is enabled). However, OpenOCD may attempt to automatically read and write the flash in order to set :ref:`software breakpoints `. This has two problems: diff --git a/docs/en/api-reference/peripherals/hmac.rst b/docs/en/api-reference/peripherals/hmac.rst index adb92c38af81..68720e4c21ef 100644 --- a/docs/en/api-reference/peripherals/hmac.rst +++ b/docs/en/api-reference/peripherals/hmac.rst @@ -132,6 +132,8 @@ JTAG enables 2. Pass this key value when calling the :cpp:func:`esp_hmac_jtag_enable` function from the firmware. 3. To re-disable JTAG in the firmware, reset the system or call :cpp:func:`esp_hmac_jtag_disable`. +End-to-end example of soft disable and re-enable JTAG workflow: :example:`security/hmac_soft_jtag` + For more details, see **{IDF_TARGET_NAME} Technical Reference Manual** > **HMAC Accelerator (HMAC)** [`PDF <{IDF_TARGET_TRM_EN_URL}#hmac>`__]. diff --git a/examples/security/.build-test-rules.yml b/examples/security/.build-test-rules.yml index 81f7d70edd4c..9098251ec9c1 100644 --- a/examples/security/.build-test-rules.yml +++ b/examples/security/.build-test-rules.yml @@ -6,6 +6,17 @@ examples/security/flash_encryption: temporary: true reason: lack of runners +examples/security/hmac_soft_jtag: + disable: + - if: SOC_HMAC_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET not in ["esp32c6"] + reason: sufficient to test on one HMAC-capable chip + depends_components: + - esp_hw_support + depends_filepatterns: + - examples/security/hmac_soft_jtag/**/* + examples/security/nvs_encryption_hmac: disable: - if: SOC_HMAC_SUPPORTED != 1 diff --git a/examples/security/hmac_soft_jtag/CMakeLists.txt b/examples/security/hmac_soft_jtag/CMakeLists.txt new file mode 100644 index 000000000000..143eb6ee5406 --- /dev/null +++ b/examples/security/hmac_soft_jtag/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(hmac_soft_jtag) diff --git a/examples/security/hmac_soft_jtag/README.md b/examples/security/hmac_soft_jtag/README.md new file mode 100644 index 000000000000..99d7f559ba1b --- /dev/null +++ b/examples/security/hmac_soft_jtag/README.md @@ -0,0 +1,113 @@ +| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | + +# JTAG Re-enable Example + +This example showcases the use of HMAC peripheral for enabling the soft-disabled JTAG interface. + +## How to use example + +### Hardware Required + +This example can be executed on any development board with a supported Espressif SOC chip - possessing a built-in HMAC peripheral (see `Supported Targets` table above). + +### Configure the device + +To configure the device for JTAG access, follow these steps: + +**Note:** Before running the jtag_example_helper.py script, make sure to install the required dependencies by running the following command: + +```bash +pip install -r requirements.txt +``` + +**Step 1:** Check JTAG status. + +```bash +python jtag_example_helper.py check_jtag_status +``` + +If device is soft disabled, this example can re-enable it using further steps. + +**Step 2:** Generate a 32 bytes HMAC key. + +```bash +python jtag_example_helper.py generate_hmac_key .bin +``` + +This generates a new 32-byte random HMAC key and store it in given file. + +**Step 3:** Run the following command to burn the eFuse with the generated HMAC key with appropriate purpose. You can use purpose either HMAC_DOWN_ALL or HMAC_DOWN_JTAG. Check efuse summary to identify an available empty key block. + +```bash +espefuse.py -p $ESPPORT burn_key .bin HMAC_DOWN_ALL +``` + +**Step 4:** Generate token data from the HMAC key. Keep this token data handy before re-enabling JTAG access. + +```bash +python jtag_example_helper.py generate_token .bin +``` + +### Configure the project + +Before the project configuration and build, be sure to set the correct chip target using `idf.py set-target `. + +Key block to be used for re-enabling JTAG can be configured in the project configuration menu, under ``Example Configuration`` > ``key block to be used``. The default value is -1, indicating that the example will use the first found keys with the purpose either HMAC_DOWN_ALL or HMAC_DOWN_JTAG. + +### Build and Flash + +Build the project and flash it to the board, then run the monitor tool to view the serial output: + +```bash +idf.py -p PORT flash monitor +``` + +It will open console to enter command. Refer [Re-enable & Disable JTAG](#Re-enable-&-Disable-JTAG) to know more about usage of example. + +(To exit the serial monitor, type `Ctrl-]`.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +### Re-enable & Disable JTAG + +#### Re-enable JTAG + +This re-enables JTAG access until the next reboot or until disabled using this example. For disabling JTAG, refer [Disable JTAG](#Disable-JTAG) + +**Note:** Even upon successful return, JTAG will only be enabled with a valid token_data. + +```bash +enable_jtag +``` + +Console logs while re-enabling JTAG: + +```bash +I (314) main_task: Calling app_main() +Type 'help' to get the list of commands. +Use UP/DOWN arrows to navigate through command history. +Press TAB when typing command name to auto-complete. +I (394) main_task: Returned from app_main() +esp32c6> enable_jtag b2a49b1cce1be922bb7e431277413e3e8e6c3e8e6e17625c50ac66a9a857949b +I (10974) jtag_re_enable: Device is ready to re-enable. +I (10974) jtag_re_enable: Using HMAC key at block 8 with purpose HMAC_DOWN_JTAG +I (10984) jtag: JTAG re-enablement workflow performed, please check the JTAG connection manually +esp32c6> +``` + +#### Disable JTAG + +This disables the temporarily enabled JTAG access. + +```bash +disable_jtag +``` + +Console logs while disabling JTAG: + +```bash +esp32c6> disable_jtag +I (25104) jtag_re_enable: JTAG disabled temporarily +esp32c6> +``` diff --git a/examples/security/hmac_soft_jtag/jtag_example_helper.py b/examples/security/hmac_soft_jtag/jtag_example_helper.py new file mode 100644 index 000000000000..d355a9d2db2c --- /dev/null +++ b/examples/security/hmac_soft_jtag/jtag_example_helper.py @@ -0,0 +1,86 @@ +# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import argparse +import binascii +import hashlib +import hmac +import os +import subprocess + + +def generate_token_data(hmac_key_file: str) -> None: + with open(hmac_key_file, 'rb') as file: + key_data = file.read() + data = bytes([0] * 32) + token_data = hmac.HMAC(key_data, data, hashlib.sha256).digest() + token_hex = binascii.hexlify(token_data).decode('utf-8') + print(token_hex) + + +def generate_hmac_key(hmac_key_file: str) -> None: + hmac_key = os.urandom(32) + with open(hmac_key_file, 'wb') as file: + file.write(hmac_key) + + +def check_jtag_status() -> None: + esp_port = os.getenv('ESPPORT') + if not esp_port: + raise RuntimeError('ESPPORT not specified') + + output = subprocess.check_output(['espefuse.py', 'summary']).decode('utf-8') + + # check if JTAG is permenently/hard disabled + if ('DIS_PAD_JTAG' in output and 'JTAG = True' in output) or ('HARD_DIS_JTAG' in output and 'JTAG = True' in output): + print('JTAG functionality is permanently disabled') + else: + print('JTAG functionality is not permanently disabled') + + # check if JTAG is software disabled + soft_dis_value = None + lines = output.split('\n') + for line in lines: + if 'SOFT_DIS_JTAG' in line: + hex_value = line.split('=')[-1].split(' ')[1] # Extract the hexadecimal part + soft_dis_value = int(hex_value, 16) + break + + if soft_dis_value is not None: + # Count the number of 1's in the binary representation of soft_dis_value + ones_count = bin(soft_dis_value).count('1') + if ones_count % 2 != 0: + print('JTAG is software disabled') + else: + print('JTAG is not software disabled') + else: + print('SOFT_DIS_JTAG value not found in the output') + + print('If JTAG is permenently disabled, it cannot be re-enabled.\nThis example re-enables only software disabled JTAG access') + + +def main() -> None: + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(dest='command') + + subparsers.add_parser('check_jtag_status', help='Check JTAG current status') + + hmac_generator_parser = subparsers.add_parser('generate_hmac_key') + hmac_generator_parser.add_argument('hmac_key_file', help='File to store generated HMAC key') + + token_generator_parser = subparsers.add_parser('generate_token') + token_generator_parser.add_argument('hmac_key_file', help='File containing the HMAC key') + + args = parser.parse_args() + + if args.command == 'check_jtag_status': + check_jtag_status() + elif args.command == 'generate_hmac_key': + generate_hmac_key(args.hmac_key_file) + elif args.command == 'generate_token': + generate_token_data(args.hmac_key_file) + else: + parser.print_help() + + +if __name__ == '__main__': + main() diff --git a/examples/security/hmac_soft_jtag/main/CMakeLists.txt b/examples/security/hmac_soft_jtag/main/CMakeLists.txt new file mode 100644 index 000000000000..beb15285a52e --- /dev/null +++ b/examples/security/hmac_soft_jtag/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "example_main.c" "jtag_commands.c" + PRIV_INCLUDE_DIRS ".") diff --git a/examples/security/hmac_soft_jtag/main/Kconfig.projbuild b/examples/security/hmac_soft_jtag/main/Kconfig.projbuild new file mode 100644 index 000000000000..94666cfd70b1 --- /dev/null +++ b/examples/security/hmac_soft_jtag/main/Kconfig.projbuild @@ -0,0 +1,13 @@ +menu "Example Configuration" + + config EXAMPLE_JTAG_SEC_HMAC_EFUSE_KEY_ID + int "eFuse key ID storing the HMAC key" + range -1 5 + default -1 + help + The eFuse block key ID stores the HMAC key necessary for deriving token data to enable JTAG access. + + Note: If set to -1, the system will attempt to use the first found keys with the purpose + either HMAC_DOWN_ALL or HMAC_DOWN_JTAG. + +endmenu diff --git a/examples/security/hmac_soft_jtag/main/example_main.c b/examples/security/hmac_soft_jtag/main/example_main.c new file mode 100644 index 000000000000..946fc2217eb9 --- /dev/null +++ b/examples/security/hmac_soft_jtag/main/example_main.c @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "esp_console.h" +#include "nvs_flash.h" +#include "jtag_commands.h" + +#define PROMPT_STR CONFIG_IDF_TARGET + +void app_main(void) +{ + esp_console_repl_t *repl = NULL; + esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + repl_config.prompt = PROMPT_STR ">"; + repl_config.max_cmdline_length = 256; + + /* Register commands */ + esp_console_register_help_command(); + register_jtag_commands(); + +#if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) || defined(CONFIG_ESP_CONSOLE_UART_CUSTOM) + esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config, &repl_config, &repl)); + +#elif defined(CONFIG_ESP_CONSOLE_USB_CDC) + esp_console_dev_usb_cdc_config_t hw_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&hw_config, &repl_config, &repl)); + +#elif defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) + esp_console_dev_usb_serial_jtag_config_t hw_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&hw_config, &repl_config, &repl)); + +#else +#error Unsupported console type +#endif + + ESP_ERROR_CHECK(esp_console_start_repl(repl)); +} diff --git a/examples/security/hmac_soft_jtag/main/jtag_commands.c b/examples/security/hmac_soft_jtag/main/jtag_commands.c new file mode 100644 index 000000000000..bfbb30fe3cc2 --- /dev/null +++ b/examples/security/hmac_soft_jtag/main/jtag_commands.c @@ -0,0 +1,204 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include +#include +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "esp_log.h" +#include "esp_hmac.h" +#include "mbedtls/md.h" +#include "esp_console.h" +#include "argtable3/argtable3.h" + +#define HMAC_KEY_SIZE 32 +#define TOKEN_DATA_SIZE 32 + +static const char* TAG = "jtag_re_enable"; + +typedef struct { + struct arg_str *token_data; + struct arg_end *end; +} command_args_t; + +static command_args_t command_args; + +static bool is_hexadecimal(const char *str) +{ + if (str == NULL || *str == '\0') { + return false; + } + + while (*str != '\0') { + if (!isxdigit((unsigned char)*str)) { + return false; + } + str++; + } + + return true; +} + +const char *esp_efuse_purpose_str(esp_efuse_purpose_t purpose) +{ + switch (purpose) { + case ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL: + return "HMAC_DOWN_ALL"; + case ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG: + return "HMAC_DOWN_JTAG"; + default: + return "Unknown"; + } +} + +static esp_err_t is_device_ready_to_re_enable(void) +{ + bool flag_jtag_hard_dis; +#if SOC_EFUSE_HARD_DIS_JTAG + flag_jtag_hard_dis = esp_efuse_read_field_bit(ESP_EFUSE_HARD_DIS_JTAG); +#else + flag_jtag_hard_dis = esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG); +#endif + + if (flag_jtag_hard_dis) { + ESP_LOGE(TAG, "JTAG permenently disabled. Can't re-enable."); + return ESP_FAIL; + } + + size_t out_cnt = 0; + if (ESP_OK != esp_efuse_read_field_cnt(ESP_EFUSE_SOFT_DIS_JTAG, &out_cnt)) { + ESP_LOGE(TAG, "Error obtaining value for SOFT_DIS_JTAG"); + return ESP_FAIL; + } + + if (out_cnt == 0) { + ESP_LOGI(TAG, "JTAG soft disable efuse bit is not programmed, hence JTAG is already enabled"); + return ESP_FAIL; + } + + return ESP_OK; +} + +static esp_err_t re_enable_jtag_utility(uint8_t token_data[]) +{ + esp_err_t status; + + // Read the configured key block number from Kconfig + int configured_block_number = CONFIG_EXAMPLE_JTAG_SEC_HMAC_EFUSE_KEY_ID; + + if (configured_block_number != -1) { + // User has configured a specific key block number + ESP_LOGI(TAG, "Using user-configured key block number %d for authentication", configured_block_number); + status = esp_hmac_jtag_enable(configured_block_number, token_data); + } else { + esp_efuse_purpose_t purposes[] = { + ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL, + ESP_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG + }; + + // Check if there is already a key block with the desired purpose + esp_efuse_block_t block; + status = ESP_FAIL; + for (unsigned i = 0; i < sizeof(purposes) / sizeof(esp_efuse_purpose_t); i++) { + if (esp_efuse_find_purpose(purposes[i], &block)) { + // key block with appropriate purpose found + ESP_LOGI(TAG, "Using HMAC key at block %d with purpose %s for authentication", block - (int)EFUSE_BLK4, esp_efuse_purpose_str(purposes[i])); + status = status && esp_hmac_jtag_enable(block - (int)EFUSE_BLK4, token_data); + } + } + + if (EFUSE_BLK_KEY_MAX == block) { + ESP_LOGI(TAG, "HMAC key is not burned with required purpose. Please refer to device configuration in example readme for more details."); + return ESP_FAIL; + } + } + + if (ESP_OK != status) { + ESP_LOGI(TAG, "Error in re-enabling JTAG"); + return ESP_FAIL; + } + + return ESP_OK; +} + +static esp_err_t re_enable_jtag(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &command_args); + if (nerrors != 0) { + arg_print_errors(stderr, command_args.end, argv[0]); + return ESP_FAIL; + } + + if (ESP_OK != is_device_ready_to_re_enable()) { + return ESP_FAIL; + } + ESP_LOGI(TAG, "Device is ready to re-enable."); + + const char* arg_token_data_str = command_args.token_data->sval[0]; + if (strlen(arg_token_data_str) != TOKEN_DATA_SIZE * 2 || !is_hexadecimal(arg_token_data_str)) { + ESP_LOGE(TAG, "Invalid token_data. The token data should be 64 hexadecimal characters."); + return ESP_FAIL; + } + + // Convert the string to uint8_t array + uint8_t token_data[TOKEN_DATA_SIZE]; + for (int i = 0; i < TOKEN_DATA_SIZE; ++i) { + sscanf(arg_token_data_str + 2 * i, "%2hhx", &token_data[i]); + } + + if (ESP_OK != re_enable_jtag_utility(token_data)) { + ESP_LOGI(TAG, "JTAG re-enabling failed"); + return ESP_FAIL; + } + + ESP_LOGI("jtag", "JTAG re-enablement workflow performed, please check the JTAG connection manually"); + return ESP_OK; +} + +static void register_enable_jtag(void) +{ + command_args.token_data = arg_str1(NULL, NULL, "", "token_data"); + command_args.end = arg_end(1); + + const esp_console_cmd_t cmd = { + .command = "enable_jtag", + .help = "Re-enables software JTAG access.\n\t Usage: enable_jtag ", + .hint = NULL, + .func = &re_enable_jtag, + .argtable = &command_args, + }; + + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +static esp_err_t disable_jtag(int argc, char **argv) +{ + if (ESP_OK != esp_hmac_jtag_disable()) { + ESP_LOGE(TAG, "Failed to disable JTAG"); + return ESP_FAIL; + } + + ESP_LOGI(TAG, "JTAG disabled temporarily"); + return ESP_OK; +} + +static void register_disable_jtag(void) +{ + const esp_console_cmd_t cmd = { + .command = "disable_jtag", + .help = "Disables software JTAG access", + .hint = NULL, + .func = &disable_jtag, + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&cmd)); +} + +void register_jtag_commands(void) +{ + register_enable_jtag(); + register_disable_jtag(); +} diff --git a/examples/security/hmac_soft_jtag/main/jtag_commands.h b/examples/security/hmac_soft_jtag/main/jtag_commands.h new file mode 100644 index 000000000000..afc0af17a8e8 --- /dev/null +++ b/examples/security/hmac_soft_jtag/main/jtag_commands.h @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#pragma once + +void register_jtag_commands(void); diff --git a/examples/security/hmac_soft_jtag/pytest_jtag_example.py b/examples/security/hmac_soft_jtag/pytest_jtag_example.py new file mode 100644 index 000000000000..a8e551041087 --- /dev/null +++ b/examples/security/hmac_soft_jtag/pytest_jtag_example.py @@ -0,0 +1,51 @@ +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# # SPDX-License-Identifier: CC0-1.0 +import logging +import os +import re +import signal + +import pexpect +import pytest +from pytest_embedded_idf import IdfDut + + +def run_gdb_test(dut: IdfDut) -> None: + with open(os.path.join(dut.logdir, 'ocd.txt'), 'w') as ocd_log, \ + pexpect.spawn(f'openocd -f board/esp32c6-builtin.cfg', + timeout=60, + logfile=ocd_log, + encoding='utf-8', + codec_errors='ignore') as p: + try: + p.expect(re.compile(r'JTAG tap: esp32c6.cpu tap/device found'), timeout=5) + logging.info('JTAG is enabled.') + + except pexpect.TIMEOUT: + logging.info('JTAG is disabled') + + finally: + p.terminate() + p.kill(signal.SIGKILL) + + +@pytest.mark.esp32c6 +@pytest.mark.jtag_re_enable +def test_jtag_re_enable(dut: IdfDut) -> None: + + dut.expect_exact('esp32c6>', timeout=30) + + logging.info('Initially:') + run_gdb_test(dut) + + logging.info('After calling enable_jtag:') + # The following token data is generated using the HMAC key: + # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32} + dut.write('enable_jtag b2a49b1cce1be922bb7e431277413e3e8e6c3e8e6e17625c50ac66a9a857949b') + dut.expect('JTAG re-enablement workflow performed', timeout=30) + run_gdb_test(dut) + + logging.info('After calling disable_jtag:') + dut.write('disable_jtag') + dut.expect('JTAG disabled temporarily', timeout=30) + run_gdb_test(dut) diff --git a/examples/security/hmac_soft_jtag/requirements.txt b/examples/security/hmac_soft_jtag/requirements.txt new file mode 100644 index 000000000000..3b9ce0507dbf --- /dev/null +++ b/examples/security/hmac_soft_jtag/requirements.txt @@ -0,0 +1 @@ +esptool diff --git a/examples/security/hmac_soft_jtag/sdkconfig.defaults b/examples/security/hmac_soft_jtag/sdkconfig.defaults new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/examples/security/hmac_soft_jtag/sdkconfig.defaults.esp32c6 b/examples/security/hmac_soft_jtag/sdkconfig.defaults.esp32c6 new file mode 100644 index 000000000000..3237463f0a1f --- /dev/null +++ b/examples/security/hmac_soft_jtag/sdkconfig.defaults.esp32c6 @@ -0,0 +1,3 @@ +# Changing channel for console output +# +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/tools/ci/idf_pytest/constants.py b/tools/ci/idf_pytest/constants.py index 8ab64183f04c..51736c28325a 100644 --- a/tools/ci/idf_pytest/constants.py +++ b/tools/ci/idf_pytest/constants.py @@ -103,6 +103,7 @@ 'i2c_oled': 'Runner with ssd1306 I2C oled connected', 'httpbin': 'runner for tests that need to access the httpbin service', 'flash_4mb': 'C2 runners with 4 MB flash', + 'jtag_re_enable': 'Runner to re-enable jtag which is softly disabled by burning bit SOFT_DIS_JTAG on eFuse', # multi-dut markers 'multi_dut_modbus_rs485': 'a pair of runners connected by RS485 bus', 'ieee802154': 'ieee802154 related tests should run on ieee802154 runners.', From 483b87750c6e0dc9772ab3733a26e5f95e3f99a9 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Mon, 4 Mar 2024 16:28:13 +0530 Subject: [PATCH 28/33] docs(wifi_provisioning): Use heap to allocate memory for the response Added a note to specify that the memory for the response of a custom endpoint should be allocated using the heap, as this memory gets freed by the protocomm layer once it has been passed to the transport layer. Closes https://github.com/espressif/esp-idf/issues/13263 --- docs/en/api-reference/provisioning/wifi_provisioning.rst | 2 +- examples/provisioning/wifi_prov_mgr/main/app_main.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/api-reference/provisioning/wifi_provisioning.rst b/docs/en/api-reference/provisioning/wifi_provisioning.rst index 3b7ffc59e11c..e9c436417721 100644 --- a/docs/en/api-reference/provisioning/wifi_provisioning.rst +++ b/docs/en/api-reference/provisioning/wifi_provisioning.rst @@ -264,7 +264,7 @@ The client can also control the provisioning state of the device using ``wifi_ct Additional Endpoints ^^^^^^^^^^^^^^^^^^^^ -In case users want to have some additional protocomm endpoints customized to their requirements, this is done in two steps. First is creation of an endpoint with a specific name, and the second step is the registration of a handler for this endpoint. See :doc:`protocomm` for the function signature of an endpoint handler. A custom endpoint must be created after initialization and before starting the provisioning service. Whereas, the protocomm handler is registered for this endpoint only after starting the provisioning service. +In case users want to have some additional protocomm endpoints customized to their requirements, this is done in two steps. First is creation of an endpoint with a specific name, and the second step is the registration of a handler for this endpoint. See :doc:`protocomm` for the function signature of an endpoint handler. A custom endpoint must be created after initialization and before starting the provisioning service. Whereas, the protocomm handler is registered for this endpoint only after starting the provisioning service. Note that in the custom endpoint handler function, memory for the response of such protocomm endpoints should be allocated using heap as it gets freed by the protocomm layer once it has been sent by the transport layer. .. code-block:: c diff --git a/examples/provisioning/wifi_prov_mgr/main/app_main.c b/examples/provisioning/wifi_prov_mgr/main/app_main.c index f6c02328721a..9c5f2a506485 100644 --- a/examples/provisioning/wifi_prov_mgr/main/app_main.c +++ b/examples/provisioning/wifi_prov_mgr/main/app_main.c @@ -230,6 +230,8 @@ static void get_device_service_name(char *service_name, size_t max) /* Handler for the optional provisioning endpoint registered by the application. * The data format can be chosen by applications. Here, we are using plain ascii text. * Applications can choose to use other formats like protobuf, JSON, XML, etc. + * Note that memory for the response buffer must be allocated using heap as this buffer + * gets freed by the protocomm layer once it has been sent by the transport layer. */ esp_err_t custom_prov_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen, void *priv_data) From dec3786d30540bfae80b2c198a12292cf670abb0 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Fri, 1 Mar 2024 17:46:32 +0800 Subject: [PATCH 29/33] fix(freertos/idf): Fix build error when CONFIG_FREERTOS_USE_TICK_HOOK is enabled Closes https://github.com/espressif/esp-idf/issues/13297 --- components/freertos/FreeRTOS-Kernel/tasks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index 941b0635470b..fd5511828ae0 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -3356,7 +3356,7 @@ BaseType_t xTaskIncrementTick( void ) { /* Guard against the tick hook being called when the pended tick * count is being unwound (when the scheduler is being unlocked). */ - if( xPendedTicksTemp == ( TickType_t ) 0 ) + if( xPendedTicks == ( TickType_t ) 0 ) { xCallTickHook = pdTRUE; } From f9965e309230483e05ecc035df6b1b89956c7151 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Fri, 1 Mar 2024 17:59:52 +0800 Subject: [PATCH 30/33] change(freertos): Test tick and idle hooks in options test Add CONFIG_FREERTOS_USE_TICK_HOOK and CONFIG_FREERTOS_USE_IDLE_HOOK to sdkconfig.ci.freertos_options to ensure those options are tested. --- .../freertos/kernel/tasks/test_freertos_hooks.c | 14 +++++++------- .../freertos/sdkconfig.ci.freertos_options | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_hooks.c b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_hooks.c index 39d7f3c12b46..80fd6d4d655e 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_hooks.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_hooks.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,11 +18,11 @@ a definition for vApplicationTickHook(). Thus this test cannot be run. #include "unity.h" #include "test_utils.h" -#ifndef CONFIG_FREERTOS_SMP +#if !CONFIG_FREERTOS_SMP /* Test FreeRTOS idle hook. Only compiled in if FreeRTOS idle hooks are enabled. */ -#if ( configUSE_IDLE_HOOK == 1 ) +#if CONFIG_FREERTOS_USE_IDLE_HOOK static volatile unsigned idle_count; @@ -38,12 +38,12 @@ TEST_CASE("FreeRTOS idle hook", "[freertos]") TEST_ASSERT_NOT_EQUAL(0, idle_count); // The legacy idle hook should be called at least once } -#endif // configUSE_IDLE_HOOK +#endif // CONFIG_FREERTOS_USE_IDLE_HOOK /* Test the FreeRTOS tick hook. Only compiled in if FreeRTOS tick hooks are enabled. */ -#if ( configUSE_TICK_HOOK == 1 ) +#if CONFIG_FREERTOS_USE_TICK_HOOK static volatile unsigned tick_count; @@ -62,8 +62,8 @@ TEST_CASE("FreeRTOS tick hook", "[freertos]") "The FreeRTOS tick hook should have been called approx 1 time per tick per CPU"); } -#endif // configUSE_TICK_HOOK -#endif // CONFIG_FREERTOS_SMP +#endif // CONFIG_FREERTOS_USE_TICK_HOOK +#endif // !CONFIG_FREERTOS_SMP #if CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK diff --git a/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options b/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options index 747ee35c635d..680d6646fe68 100644 --- a/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options +++ b/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options @@ -19,3 +19,5 @@ CONFIG_FREERTOS_FPU_IN_ISR=y CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2 CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES=y CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1=y +CONFIG_FREERTOS_USE_TICK_HOOK=y +CONFIG_FREERTOS_USE_IDLE_HOOK=y From 6643798227a6d5a603f73e8308d616056c021022 Mon Sep 17 00:00:00 2001 From: Ondrej Kosta Date: Mon, 4 Mar 2024 16:23:40 +0100 Subject: [PATCH 31/33] feat(esp_eth): added configuration of SPI ETH for ESP32P4 ETH examples --- .../basic/components/ethernet_init/Kconfig.projbuild | 7 +++++++ examples/ethernet/enc28j60/main/Kconfig.projbuild | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild b/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild index 230b4dee1e4b..f2b2fadfede0 100644 --- a/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild +++ b/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild @@ -147,6 +147,7 @@ menu "Example Ethernet Configuration" default 12 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6 default 4 if IDF_TARGET_ESP32H2 + default 33 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI SCLK. @@ -157,6 +158,7 @@ menu "Example Ethernet Configuration" default 11 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 7 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6 default 5 if IDF_TARGET_ESP32H2 + default 32 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI MOSI. @@ -167,6 +169,7 @@ menu "Example Ethernet Configuration" default 13 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 2 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6 default 0 if IDF_TARGET_ESP32H2 + default 52 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI MISO. @@ -184,6 +187,7 @@ menu "Example Ethernet Configuration" default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C2 default 3 if IDF_TARGET_ESP32C6 default 1 if IDF_TARGET_ESP32H2 + default 53 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI CS0, i.e. Chip Select associated with the first SPI Eth module). @@ -197,6 +201,7 @@ menu "Example Ethernet Configuration" default 21 if IDF_TARGET_ESP32C6 default 3 if IDF_TARGET_ESP32C2 default 11 if IDF_TARGET_ESP32H2 + default 23 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI CS1, i.e. Chip Select associated with the second SPI Eth module. @@ -206,6 +211,7 @@ menu "Example Ethernet Configuration" default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 default 4 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6 default 10 if IDF_TARGET_ESP32H2 + default 48 if IDF_TARGET_ESP32P4 help Set the GPIO number used by the first SPI Ethernet module interrupt line. Set -1 to use SPI Ethernet module in polling mode. @@ -218,6 +224,7 @@ menu "Example Ethernet Configuration" default 5 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C2 default 5 if IDF_TARGET_ESP32C6 default 9 if IDF_TARGET_ESP32H2 + default 47 if IDF_TARGET_ESP32P4 help Set the GPIO number used by the second SPI Ethernet module interrupt line. Set -1 to use SPI Ethernet module in polling mode. diff --git a/examples/ethernet/enc28j60/main/Kconfig.projbuild b/examples/ethernet/enc28j60/main/Kconfig.projbuild index 3fe17bff57d2..0d48ae673c46 100644 --- a/examples/ethernet/enc28j60/main/Kconfig.projbuild +++ b/examples/ethernet/enc28j60/main/Kconfig.projbuild @@ -16,6 +16,7 @@ menu "Example Configuration" default 12 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6 default 4 if IDF_TARGET_ESP32H2 + default 33 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI SCLK. @@ -26,6 +27,7 @@ menu "Example Configuration" default 11 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 7 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6 default 5 if IDF_TARGET_ESP32H2 + default 32 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI MOSI. @@ -36,6 +38,7 @@ menu "Example Configuration" default 13 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 default 2 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6 default 0 if IDF_TARGET_ESP32H2 + default 52 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI MISO. @@ -46,6 +49,7 @@ menu "Example Configuration" default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C2 default 3 if IDF_TARGET_ESP32C6 default 1 if IDF_TARGET_ESP32H2 + default 53 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SPI CS. @@ -62,6 +66,7 @@ menu "Example Configuration" default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 default 4 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6 default 10 if IDF_TARGET_ESP32H2 + default 48 if IDF_TARGET_ESP32P4 help Set the GPIO number used by ENC28J60 interrupt. From 832a706eb58b6e94adf4cb411c7de8c0c0e4246f Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Tue, 5 Mar 2024 15:07:54 +0800 Subject: [PATCH 32/33] revert(usb_host): Revert temporary disable cdc_acm_vcp test for P4 This reverts commit b1bbca60ee98f01bcc9c5fdb315d8232e35dd103 --- examples/peripherals/.build-test-rules.yml | 23 ------------------- .../usb/host/cdc/cdc_acm_vcp/README.md | 4 ++-- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 09d3cb64f8f5..6bbc715db6ac 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -472,29 +472,6 @@ examples/peripherals/usb/host: - components/soc/esp32*/include/soc/usb_wrap_*.h - examples/peripherals/usb/host/**/* - -# Temporarily override and disable cdc_acm_vcp due to component manager CI issue -examples/peripherals/usb/host/cdc/cdc_acm_vcp: - disable: - - if: SOC_USB_OTG_SUPPORTED != 1 or IDF_TARGET == "esp32p4" - temporary: true - reason: CI failing for P4 # IDFCI-2042 - disable_test: - - if: IDF_TARGET not in ["esp32s3"] - temporary: true - reason: lack of runners with usb_host_flash_disk tag - depends_components: - - usb - depends_filepatterns: - - components/hal/usb*.c - - components/hal/include/hal/usb*.h - - components/hal/esp32*/include/hal/usb*.h - - components/soc/esp32*/usb*.c - - components/soc/include/soc/usb*.h - - components/soc/esp32*/include/soc/usb_dwc_*.h - - components/soc/esp32*/include/soc/usb_wrap_*.h - - examples/peripherals/usb/host/**/* - examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo: disable: - if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1 diff --git a/examples/peripherals/usb/host/cdc/cdc_acm_vcp/README.md b/examples/peripherals/usb/host/cdc/cdc_acm_vcp/README.md index 71fdfb331d93..23193375d118 100644 --- a/examples/peripherals/usb/host/cdc/cdc_acm_vcp/README.md +++ b/examples/peripherals/usb/host/cdc/cdc_acm_vcp/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | +| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | # USB CDC-ACM Virtual COM Port example From f6a7fb13cd7302473a3c59baa3b3ac9f793af1ae Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Wed, 21 Feb 2024 15:43:25 +0530 Subject: [PATCH 33/33] feat: re enables tests on p4 This commit re-enables mbedtls and hal/crypto testapos on p4. --- components/esp_system/port/soc/esp32p4/clk.c | 4 ++++ components/hal/.build-test-rules.yml | 4 ---- components/hal/test_apps/crypto/pytest_crypto.py | 2 -- components/mbedtls/test_apps/.build-test-rules.yml | 4 ---- components/mbedtls/test_apps/pytest_mbedtls_ut.py | 2 -- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/components/esp_system/port/soc/esp32p4/clk.c b/components/esp_system/port/soc/esp32p4/clk.c index 777d1716483f..c7ac1113cf3c 100644 --- a/components/esp_system/port/soc/esp32p4/clk.c +++ b/components/esp_system/port/soc/esp32p4/clk.c @@ -18,6 +18,7 @@ #include "soc/rtc.h" #include "soc/rtc_periph.h" #include "soc/i2s_reg.h" +#include "soc/hp_sys_clkrst_reg.h" #include "esp_cpu.h" #include "hal/wdt_hal.h" #include "esp_private/esp_modem_clock.h" @@ -100,6 +101,9 @@ __attribute__((weak)) void esp_clk_init(void) // Re calculate the ccount to make time calculation correct. esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz); + + // Set crypto clock (`clk_sec`) to use 240M PLL clock + REG_SET_FIELD(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_CRYPTO_CLK_SRC_SEL, 0x2); } static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src) diff --git a/components/hal/.build-test-rules.yml b/components/hal/.build-test-rules.yml index 38b4d9e94b4c..2577a357be26 100644 --- a/components/hal/.build-test-rules.yml +++ b/components/hal/.build-test-rules.yml @@ -1,8 +1,4 @@ components/hal/test_apps/crypto: - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8982 depends_components: - efuse diff --git a/components/hal/test_apps/crypto/pytest_crypto.py b/components/hal/test_apps/crypto/pytest_crypto.py index 447bff843f7f..d988e8eb6d55 100644 --- a/components/hal/test_apps/crypto/pytest_crypto.py +++ b/components/hal/test_apps/crypto/pytest_crypto.py @@ -6,7 +6,6 @@ from pytest_embedded import Dut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8982 @pytest.mark.supported_targets @pytest.mark.generic def test_crypto(dut: Dut) -> None: @@ -17,7 +16,6 @@ def test_crypto(dut: Dut) -> None: dut.expect('Tests finished', timeout=timeout) -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8982 @pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['long_aes_operations'], indirect=True) diff --git a/components/mbedtls/test_apps/.build-test-rules.yml b/components/mbedtls/test_apps/.build-test-rules.yml index 360df7c66b16..f33fabc474c3 100644 --- a/components/mbedtls/test_apps/.build-test-rules.yml +++ b/components/mbedtls/test_apps/.build-test-rules.yml @@ -5,10 +5,6 @@ components/mbedtls/test_apps: - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 - if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1 - if: CONFIG_NAME == "ecdsa_sign" and SOC_ECDSA_SUPPORTED != 1 - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8982 depends_components: - efuse depends_filepatterns: diff --git a/components/mbedtls/test_apps/pytest_mbedtls_ut.py b/components/mbedtls/test_apps/pytest_mbedtls_ut.py index a95752dd579e..e51de7aa41a8 100644 --- a/components/mbedtls/test_apps/pytest_mbedtls_ut.py +++ b/components/mbedtls/test_apps/pytest_mbedtls_ut.py @@ -1,11 +1,9 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8982 @pytest.mark.supported_targets @pytest.mark.generic def test_mbedtls(dut: Dut) -> None: