fix(esp_hw_support): add timer wakeup sleep duration check

Closes https://github.com/espressif/esp-idf/issues/15255
This commit is contained in:
wuzhenghui
2025-02-07 14:30:40 +08:00
parent 346d2367ef
commit 989e958256
20 changed files with 105 additions and 30 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -168,9 +168,13 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void);
/** /**
* @brief Enable wakeup by timer * @brief Enable wakeup by timer
* @param time_in_us time before wakeup, in microseconds * @param time_in_us time before wakeup, in microseconds
* @note The valid `time_in_us` value depends on the bit width of the lp_timer/rtc_timer counter and the
* current slow clock source selection (Refer RTC clock source configuration in menuconfig).
* Valid values should be positive values less than RTC slow clock period * (2 ^ RTC timer bitwidth).
*
* @return * @return
* - ESP_OK on success * - ESP_OK on success
* - ESP_ERR_INVALID_ARG if value is out of range (TBD) * - ESP_ERR_INVALID_ARG if value is out of range.
*/ */
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us); esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us);

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -143,9 +143,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{ {
assert(period); assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
* TODO: fix overflow. return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
*/ }
return (time_in_us << RTC_CLK_CAL_FRACT) / period; return (time_in_us << RTC_CLK_CAL_FRACT) / period;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -157,9 +157,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{ {
assert(period); assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
* TODO: fix overflow. return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
*/ }
return (time_in_us << RTC_CLK_CAL_FRACT) / period; return (time_in_us << RTC_CLK_CAL_FRACT) / period;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -160,9 +160,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{ {
assert(period); assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
* TODO: fix overflow. return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
*/ }
return (time_in_us << RTC_CLK_CAL_FRACT) / period; return (time_in_us << RTC_CLK_CAL_FRACT) / period;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -235,9 +235,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{ {
assert(period); assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
* TODO: fix overflow. return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
*/ }
return (time_in_us << RTC_CLK_CAL_FRACT) / period; return (time_in_us << RTC_CLK_CAL_FRACT) / period;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -235,9 +235,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{ {
assert(period); assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
* TODO: fix overflow. return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
*/ }
return (time_in_us << RTC_CLK_CAL_FRACT) / period; return (time_in_us << RTC_CLK_CAL_FRACT) / period;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -225,9 +225,9 @@ uint32_t rtc_clk_cal_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{ {
assert(period); assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
* TODO: fix overflow. return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
*/ }
return (time_in_us << RTC_CLK_CAL_FRACT) / period; return (time_in_us << RTC_CLK_CAL_FRACT) / period;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -159,9 +159,9 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{ {
assert(period); assert(period);
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
* TODO: fix overflow. return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
*/ }
return (time_in_us << RTC_CLK_CAL_FRACT) / period; return (time_in_us << RTC_CLK_CAL_FRACT) / period;
} }

View File

@@ -12,6 +12,7 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_memory_utils.h" #include "esp_memory_utils.h"
#include "esp_sleep.h" #include "esp_sleep.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_private/esp_sleep_internal.h" #include "esp_private/esp_sleep_internal.h"
#include "esp_private/esp_timer_private.h" #include "esp_private/esp_timer_private.h"
#include "esp_private/sleep_event.h" #include "esp_private/sleep_event.h"
@@ -1464,6 +1465,10 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void)
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us) esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
{ {
if (time_in_us > ((BIT64(SOC_LP_TIMER_BIT_WIDTH_LO + SOC_LP_TIMER_BIT_WIDTH_HI) - 1) / esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX)) * MHZ ) {
return ESP_ERR_INVALID_ARG;
}
s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN; s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
s_config.sleep_duration = time_in_us; s_config.sleep_duration = time_in_us;
return ESP_OK; return ESP_OK;

View File

@@ -22,10 +22,12 @@
#include "esp_newlib.h" #include "esp_newlib.h"
#include "test_utils.h" #include "test_utils.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_clk_tree.h"
#include "esp_rom_uart.h" #include "esp_rom_uart.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "esp_timer.h" #include "esp_timer.h"
#include "esp_private/esp_clk.h" #include "esp_private/esp_clk.h"
#include "esp_private/esp_clk_tree_common.h"
#include "esp_random.h" #include "esp_random.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "nvs.h" #include "nvs.h"
@@ -55,6 +57,10 @@ static void deep_sleep_task(void *arg)
static void do_deep_sleep_from_app_cpu(void) static void do_deep_sleep_from_app_cpu(void)
{ {
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_sleep_enable_timer_wakeup(UINT64_MAX));
uint64_t lp_timer_max_allowed_time_in_us = ((BIT64(SOC_LP_TIMER_BIT_WIDTH_LO + SOC_LP_TIMER_BIT_WIDTH_HI) - 1) / esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX)) * MHZ;
TEST_ASSERT_EQUAL(ESP_OK, esp_sleep_enable_timer_wakeup(lp_timer_max_allowed_time_in_us));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_sleep_enable_timer_wakeup(lp_timer_max_allowed_time_in_us + 1));
esp_sleep_enable_timer_wakeup(2000000); esp_sleep_enable_timer_wakeup(2000000);
xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1); xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1);

View File

@@ -623,6 +623,14 @@ config SOC_TIMER_GROUP_SUPPORT_APB
bool bool
default y default y
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_TOUCH_VERSION_1 config SOC_TOUCH_VERSION_1
bool bool
default y default y

View File

@@ -300,6 +300,10 @@
#define SOC_TIMER_GROUP_TOTAL_TIMERS (4) #define SOC_TIMER_GROUP_TOTAL_TIMERS (4)
#define SOC_TIMER_GROUP_SUPPORT_APB (1) #define SOC_TIMER_GROUP_SUPPORT_APB (1)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/ /*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
#define SOC_TOUCH_VERSION_1 (1) /*!<Hardware version of touch sensor */ #define SOC_TOUCH_VERSION_1 (1) /*!<Hardware version of touch sensor */
#define SOC_TOUCH_SENSOR_NUM (10) #define SOC_TOUCH_SENSOR_NUM (10)

View File

@@ -519,6 +519,14 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int int
default 1 default 1
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_MWDT_SUPPORT_XTAL config SOC_MWDT_SUPPORT_XTAL
bool bool
default y default y

View File

@@ -250,6 +250,10 @@
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1) #define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (1U) #define SOC_TIMER_GROUP_TOTAL_TIMERS (1U)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/ /*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1) #define SOC_MWDT_SUPPORT_XTAL (1)

View File

@@ -747,6 +747,14 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int int
default 2 default 2
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_MWDT_SUPPORT_XTAL config SOC_MWDT_SUPPORT_XTAL
bool bool
default y default y

View File

@@ -334,6 +334,10 @@
#define SOC_TIMER_GROUP_SUPPORT_APB (1) #define SOC_TIMER_GROUP_SUPPORT_APB (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2) #define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/ /*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1) #define SOC_MWDT_SUPPORT_XTAL (1)

View File

@@ -715,6 +715,14 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int int
default 4 default 4
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_TOUCH_VERSION_2 config SOC_TOUCH_VERSION_2
bool bool
default y default y

View File

@@ -310,6 +310,10 @@
#define SOC_TIMER_GROUP_SUPPORT_APB (1) #define SOC_TIMER_GROUP_SUPPORT_APB (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (4) #define SOC_TIMER_GROUP_TOTAL_TIMERS (4)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/ /*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
#define SOC_TOUCH_VERSION_2 (1) /*!<Hardware version of touch sensor */ #define SOC_TOUCH_VERSION_2 (1) /*!<Hardware version of touch sensor */
#define SOC_TOUCH_SENSOR_NUM (15) /*!<15 Touch channels */ #define SOC_TOUCH_SENSOR_NUM (15) /*!<15 Touch channels */

View File

@@ -843,6 +843,14 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int int
default 4 default 4
config SOC_LP_TIMER_BIT_WIDTH_LO
int
default 32
config SOC_LP_TIMER_BIT_WIDTH_HI
int
default 16
config SOC_TOUCH_VERSION_2 config SOC_TOUCH_VERSION_2
bool bool
default y default y

View File

@@ -339,6 +339,10 @@
#define SOC_TIMER_GROUP_SUPPORT_APB (1) #define SOC_TIMER_GROUP_SUPPORT_APB (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (4) #define SOC_TIMER_GROUP_TOTAL_TIMERS (4)
/*-------------------------- LP_TIMER CAPS ----------------------------------*/
#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part
#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/ /*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
#define SOC_TOUCH_VERSION_2 (1) // Hardware version of touch sensor #define SOC_TOUCH_VERSION_2 (1) // Hardware version of touch sensor
#define SOC_TOUCH_SENSOR_NUM (15) /*! 15 Touch channels */ #define SOC_TOUCH_SENSOR_NUM (15) /*! 15 Touch channels */