Browse Source

Merge branch 'bugfix/light_sleep_when_rtc_is_used_for_gettimeofday' into 'master'

esp_hw_support: Fix time spent in light sleep when RTC is used for gettimeofday

See merge request espressif/esp-idf!17740
Konstantin Kondrashov 3 năm trước cách đây
mục cha
commit
04bcc17dcc

+ 4 - 4
components/esp_hw_support/sleep_modes.c

@@ -620,7 +620,7 @@ esp_err_t esp_light_sleep_start(void)
 
     s_config.rtc_ticks_at_sleep_start = rtc_time_get();
     uint32_t ccount_at_sleep_start = cpu_ll_get_cycle_count();
-    uint64_t high_res_time_at_start = esp_system_get_time();
+    uint64_t high_res_time_at_start = esp_timer_get_time();
     uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL);
 
     esp_ipc_isr_stall_other_cpu();
@@ -723,14 +723,14 @@ esp_err_t esp_light_sleep_start(void)
     // System timer has been clock gated for the duration of the sleep, correct for that.
 #ifdef CONFIG_IDF_TARGET_ESP32C3
     /**
-     * On esp32c3, rtc_time_get() is non-blocking, esp_system_get_time() is
+     * On esp32c3, rtc_time_get() is non-blocking, esp_timer_get_time() is
      * blocking, and the measurement data shows that this order is better.
      */
-    uint64_t high_res_time_at_end = esp_system_get_time();
+    uint64_t high_res_time_at_end = esp_timer_get_time();
     uint64_t rtc_ticks_at_end = rtc_time_get();
 #else
     uint64_t rtc_ticks_at_end = rtc_time_get();
-    uint64_t high_res_time_at_end = esp_system_get_time();
+    uint64_t high_res_time_at_end = esp_timer_get_time();
 #endif
 
     uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period);

+ 6 - 4
examples/system/esp_timer/main/esp_timer_example_main.c

@@ -61,14 +61,16 @@ void app_main(void)
     /* Timekeeping continues in light sleep, and timers are scheduled
      * correctly after light sleep.
      */
-    ESP_LOGI(TAG, "Entering light sleep for 0.5s, time since boot: %lld us",
-            esp_timer_get_time());
+    int64_t t1 = esp_timer_get_time();
+    ESP_LOGI(TAG, "Entering light sleep for 0.5s, time since boot: %lld us", t1);
 
     ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(500000));
     esp_light_sleep_start();
 
-    ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us",
-                esp_timer_get_time());
+    int64_t t2 = esp_timer_get_time();
+    ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us", t2);
+
+    assert(abs((t2 - t1) - 500000) < 1000);
 
     /* Let the timer run for a little bit more */
     usleep(2000000);

+ 7 - 0
examples/system/esp_timer/pytest_esp_timer.py

@@ -30,6 +30,13 @@ ONE_SHOT_TIMER_PERIOD = 5000000
 
 @pytest.mark.supported_targets
 @pytest.mark.generic
+@pytest.mark.parametrize(
+    'config',
+    [
+        'rtc',
+    ],
+    indirect=True
+)
 def test_esp_timer(dut: Dut) -> None:
 
     match = dut.expect(STARTING_TIMERS_REGEX)

+ 10 - 0
examples/system/esp_timer/sdkconfig.ci.rtc

@@ -0,0 +1,10 @@
+# For ESP32-S3 and ESP32-C3, keep secondary console disabled
+# This is to avoid any timing impact on test behavior
+CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
+
+CONFIG_ESP32_TIME_SYSCALL_USE_RTC=y
+CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC=y
+CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC=y
+CONFIG_ESP32C2_TIME_SYSCALL_USE_RTC=y
+CONFIG_ESP32C3_TIME_SYSCALL_USE_RTC=y
+CONFIG_ESP32H2_TIME_SYSCALL_USE_RTC=y