From c34049a323c2199f8f7e041ee52972ad7389543b Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 7 Apr 2026 20:14:26 +0800 Subject: [PATCH] fix(esp_hal_wdt): reduce IRAM usage of WDT init ROM patch The ROM patch for chips missing clock source configuration in wdt_hal_init was re-implementing the full function in IRAM. Instead, delegate to the ROM version and only append the missing clock configuration afterwards, saving ~550 bytes of IRAM. --- components/esp_hal_wdt/esp32c6/rom.wdt.ld | 9 +-- components/esp_hal_wdt/esp32h2/rom.wdt.ld | 9 +-- components/esp_hal_wdt/esp32h21/rom.wdt.ld | 9 +-- components/esp_hal_wdt/rom_patch.c | 94 +++------------------- 4 files changed, 21 insertions(+), 100 deletions(-) diff --git a/components/esp_hal_wdt/esp32c6/rom.wdt.ld b/components/esp_hal_wdt/esp32c6/rom.wdt.ld index ada8eb7fc8..eceae1144e 100644 --- a/components/esp_hal_wdt/esp32c6/rom.wdt.ld +++ b/components/esp_hal_wdt/esp32c6/rom.wdt.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,10 +9,9 @@ /* Functions */ -/* Patch init function to set clock source -wdt_hal_init = 0x40000394; -wdt_hal_deinit = 0x40000398; -*/ +/* Patch init/deinit to add clock configuration missing from ROM version */ +rom_wdt_hal_init = 0x40000394; +rom_wdt_hal_deinit = 0x40000398; wdt_hal_config_stage = 0x4000039c; wdt_hal_write_protect_disable = 0x400003a0; diff --git a/components/esp_hal_wdt/esp32h2/rom.wdt.ld b/components/esp_hal_wdt/esp32h2/rom.wdt.ld index fd145e4b6f..e1c51192f8 100644 --- a/components/esp_hal_wdt/esp32h2/rom.wdt.ld +++ b/components/esp_hal_wdt/esp32h2/rom.wdt.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,10 +9,9 @@ /* Functions */ -/* Patch init function to set clock source -wdt_hal_init = 0x4000038c; -wdt_hal_deinit = 0x40000390; -*/ +/* Patch init/deinit to add clock configuration missing from ROM version */ +rom_wdt_hal_init = 0x4000038c; +rom_wdt_hal_deinit = 0x40000390; /* Functions */ wdt_hal_config_stage = 0x40000394; diff --git a/components/esp_hal_wdt/esp32h21/rom.wdt.ld b/components/esp_hal_wdt/esp32h21/rom.wdt.ld index 6d139bdd04..8b94a98f1b 100644 --- a/components/esp_hal_wdt/esp32h21/rom.wdt.ld +++ b/components/esp_hal_wdt/esp32h21/rom.wdt.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,10 +10,9 @@ /* Functions */ -/* Patch init function to set clock source -wdt_hal_init = 0x4000038c; -wdt_hal_deinit = 0x40000390; -*/ +/* Patch init/deinit to add clock configuration missing from ROM version */ +rom_wdt_hal_init = 0x4000038c; +rom_wdt_hal_deinit = 0x40000390; /* Functions */ wdt_hal_config_stage = 0x40000394; diff --git a/components/esp_hal_wdt/rom_patch.c b/components/esp_hal_wdt/rom_patch.c index 63c4b14533..c883e1c81a 100644 --- a/components/esp_hal_wdt/rom_patch.c +++ b/components/esp_hal_wdt/rom_patch.c @@ -14,107 +14,31 @@ #include "hal/wdt_hal.h" #if ESP_ROM_WDT_INIT_PATCH +extern void rom_wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr); +extern void rom_wdt_hal_deinit(wdt_hal_context_t *hal); + void wdt_hal_init(wdt_hal_context_t *hal, wdt_inst_t wdt_inst, uint32_t prescaler, bool enable_intr) { - //Initialize HAL context - memset(hal, 0, sizeof(wdt_hal_context_t)); - if (wdt_inst == WDT_MWDT0) { - hal->mwdt_dev = &TIMERG0; - } -#if TIMG_LL_GET(INST_NUM) >= 2 - else if (wdt_inst == WDT_MWDT1) { - hal->mwdt_dev = &TIMERG1; - } -#endif - else { - hal->rwdt_dev = RWDT_DEV_GET(); - } - hal->inst = wdt_inst; + // ROM version omits clock source config for MWDT — delegate to ROM then fix up + rom_wdt_hal_init(hal, wdt_inst, prescaler, enable_intr); - if (hal->inst == WDT_RWDT) { - //Unlock RTC WDT - rwdt_ll_write_protect_disable(hal->rwdt_dev); - //Disable RTC WDT, all stages, and all interrupts. - rwdt_ll_disable(hal->rwdt_dev); - rwdt_ll_disable_stage(hal->rwdt_dev, WDT_STAGE0); - rwdt_ll_disable_stage(hal->rwdt_dev, WDT_STAGE1); - rwdt_ll_disable_stage(hal->rwdt_dev, WDT_STAGE2); - rwdt_ll_disable_stage(hal->rwdt_dev, WDT_STAGE3); -#if SOC_IS(ESP32) - //Enable or disable level interrupt. Edge interrupt is always disabled. - rwdt_ll_set_edge_intr(hal->rwdt_dev, false); - rwdt_ll_set_level_intr(hal->rwdt_dev, enable_intr); -#else - //Enable or disable chip reset on timeout, and length of chip reset signal - rwdt_ll_set_chip_reset_width(hal->rwdt_dev, 0); - rwdt_ll_set_chip_reset_en(hal->rwdt_dev, false); -#endif - rwdt_ll_clear_intr_status(hal->rwdt_dev); - rwdt_ll_set_intr_enable(hal->rwdt_dev, enable_intr); - //Set default values -#if SOC_CPU_CORES_NUM > 1 - rwdt_ll_set_appcpu_reset_en(hal->rwdt_dev, true); -#endif - rwdt_ll_set_procpu_reset_en(hal->rwdt_dev, true); - rwdt_ll_set_pause_in_sleep_en(hal->rwdt_dev, true); - rwdt_ll_set_cpu_reset_length(hal->rwdt_dev, WDT_RESET_SIG_LENGTH_3_2us); - rwdt_ll_set_sys_reset_length(hal->rwdt_dev, WDT_RESET_SIG_LENGTH_3_2us); - //Lock RTC WDT - rwdt_ll_write_protect_enable(hal->rwdt_dev); - } else { - //Unlock WDT + if (hal->inst != WDT_RWDT) { mwdt_ll_write_protect_disable(hal->mwdt_dev); - //Disable WDT and stages. - mwdt_ll_disable(hal->mwdt_dev); - mwdt_ll_disable_stage(hal->mwdt_dev, 0); - mwdt_ll_disable_stage(hal->mwdt_dev, 1); - mwdt_ll_disable_stage(hal->mwdt_dev, 2); - mwdt_ll_disable_stage(hal->mwdt_dev, 3); -#if SOC_IS(ESP32) || SOC_IS(ESP32S2) || SOC_IS(ESP32S3) - //Enable or disable level interrupt. Edge interrupt is always disabled. - mwdt_ll_set_edge_intr(hal->mwdt_dev, false); - mwdt_ll_set_level_intr(hal->mwdt_dev, enable_intr); -#endif - mwdt_ll_clear_intr_status(hal->mwdt_dev); - mwdt_ll_set_intr_enable(hal->mwdt_dev, enable_intr); - //Set default values - mwdt_ll_set_cpu_reset_length(hal->mwdt_dev, WDT_RESET_SIG_LENGTH_3_2us); - mwdt_ll_set_sys_reset_length(hal->mwdt_dev, WDT_RESET_SIG_LENGTH_3_2us); mwdt_ll_set_clock_source(hal->mwdt_dev, MWDT_CLK_SRC_DEFAULT); mwdt_ll_enable_clock(hal->mwdt_dev, true); - //Set tick period - mwdt_ll_set_prescaler(hal->mwdt_dev, prescaler); - //Lock WDT mwdt_ll_write_protect_enable(hal->mwdt_dev); } } void wdt_hal_deinit(wdt_hal_context_t *hal) { - if (hal->inst == WDT_RWDT) { - //Unlock WDT - rwdt_ll_write_protect_disable(hal->rwdt_dev); - //Disable WDT and clear any interrupts - rwdt_ll_feed(hal->rwdt_dev); - rwdt_ll_disable(hal->rwdt_dev); - rwdt_ll_clear_intr_status(hal->rwdt_dev); - rwdt_ll_set_intr_enable(hal->rwdt_dev, false); - //Lock WDT - rwdt_ll_write_protect_enable(hal->rwdt_dev); - } else { - //Unlock WDT + // ROM version omits mwdt_ll_enable_clock(false) — delegate to ROM then fix up + if (hal->inst != WDT_RWDT) { mwdt_ll_write_protect_disable(hal->mwdt_dev); - //Disable WDT and clear/disable any interrupts - mwdt_ll_feed(hal->mwdt_dev); - mwdt_ll_disable(hal->mwdt_dev); - mwdt_ll_clear_intr_status(hal->mwdt_dev); - mwdt_ll_set_intr_enable(hal->mwdt_dev, false); mwdt_ll_enable_clock(hal->mwdt_dev, false); - //Lock WDT mwdt_ll_write_protect_enable(hal->mwdt_dev); } - //Deinit HAL context - hal->mwdt_dev = NULL; + rom_wdt_hal_deinit(hal); } #if SOC_IS(ESP32P4) && (HAL_CONFIG(CHIP_SUPPORT_MIN_REV) <= 301)