Ver código fonte

Merge branch 'refactor/systimer_reset_alternative_v4.3' into 'release/v4.3'

Systimer reset alternative on S2 (and others) (v4.3)

See merge request espressif/esp-idf!15652
Zim Kalinowski 4 anos atrás
pai
commit
534ca101e4

+ 2 - 2
components/esp_common/include/esp_private/system_internal.h

@@ -61,11 +61,11 @@ void esp_reset_reason_set_hint(esp_reset_reason_t hint);
  */
 esp_reset_reason_t esp_reset_reason_get_hint(void);
 
-
 /**
  * @brief Get the time in microseconds since startup
  *
- * @returns time since startup in microseconds
+ * @returns time since g_startup_time; definition should be fixed by system time provider
+ * no matter the underlying timer used.
  */
 int64_t esp_system_get_time(void);
 

+ 4 - 4
components/esp_hw_support/test/test_rtc_clk.c

@@ -327,7 +327,7 @@ TEST_CASE("Test rtc clk calibration compensation", "[rtc_clk]")
     // so that t2 > t1 remains true
     int64_t t2 = esp_rtc_get_time_us();
 
-    TEST_ASSERT(t2 > t1);
+    TEST_ASSERT_GREATER_THAN(t1, t2);
 
     // Restore calibration value
     esp_clk_slowclk_cal_set(esp_clk_slowclk_cal_get() * 2);
@@ -337,7 +337,7 @@ TEST_CASE("Test rtc clk calibration compensation", "[rtc_clk]")
 
     t2 = esp_rtc_get_time_us();
 
-    TEST_ASSERT(t2 > t1);
+    TEST_ASSERT_GREATER_THAN(t1, t2);
 }
 
 static void trigger_deepsleep(void)
@@ -364,7 +364,7 @@ static void check_time_deepsleep_1(void)
     RESET_REASON reason = rtc_get_reset_reason(0);
     TEST_ASSERT(reason == DEEPSLEEP_RESET);
     int64_t end = esp_rtc_get_time_us();
-    TEST_ASSERT(end > start);
+    TEST_ASSERT_GREATER_THAN(start, end);
 
     esp_clk_slowclk_cal_set(esp_clk_slowclk_cal_get() * 2);
 
@@ -384,7 +384,7 @@ static void check_time_deepsleep_2(void)
     RESET_REASON reason = rtc_get_reset_reason(0);
     TEST_ASSERT(reason == DEEPSLEEP_RESET);
     int64_t end = esp_rtc_get_time_us();
-    TEST_ASSERT(end > start);
+    TEST_ASSERT_GREATER_THAN(start, end);
 }
 
 TEST_CASE_MULTIPLE_STAGES("Test rtc clk calibration compensation across deep sleep", "[rtc_clk][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", trigger_deepsleep, check_time_deepsleep_1, check_time_deepsleep_2);

+ 29 - 0
components/esp_system/README.md

@@ -0,0 +1,29 @@
+## System Notes
+
+### Timekeeping
+
+The following are the timekeeping mechanisms available and their differences:
+
+1. System time (`esp_system_get_time`)
+
+Time with the origin at `g_startup_time`. The implementation is not handled by `esp_system`,
+but it does provide a default implementation using RTC timer. Currently, `esp_timer`
+provides system time, since the hardware timers are under the control of that
+component. However, no matter the underlying timer, the system time provider
+should maintain the definition of having the origin point at `g_startup_time`.
+
+2. `esp_timer` time (`esp_timer_get_time`)
+
+This is the time read from an underlying hardware timer, controlled through config. Origin 
+is at the point where the underlying timer starts counting.
+
+3. `newlib` time (`gettimeofday`)
+
+Timekeeping function in standard library. Can be set (`settimeofday`) or moved forward/backward (`adjtime`);
+with the possibility of the changes being made persistent through config.
+Currently implemented in terms of system time, as the point of origin is fixed.
+If persistence is enabled, RTC time is also used in conjuction with system time.
+
+4. RTC time (`esp_rtc_get_time_us`)
+
+Time read from RTC timer.

+ 0 - 1
components/esp_system/port/soc/esp32s2/clk.c

@@ -315,7 +315,6 @@ __attribute__((weak)) void esp_perip_clk_init(void)
     DPORT_CLEAR_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_8M);
     DPORT_SET_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_RTC_SLOW);
 
-    periph_ll_reset(PERIPH_SYSTIMER_MODULE);
 
     /* Enable RNG clock. */
     periph_module_enable(PERIPH_RNG_MODULE);

+ 36 - 0
components/esp_system/test/test_system_time.c

@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include "unity.h"
+
+#include "esp_private/system_internal.h"
+
+#if CONFIG_IDF_TARGET_ESP32
+#include "esp32/clk.h"
+#elif CONFIG_IDF_TARGET_ESP32S2
+#include "esp32s2/clk.h"
+#elif CONFIG_IDF_TARGET_ESP32S3
+#include "esp32s3/clk.h"
+#elif CONFIG_IDF_TARGET_ESP32C3
+#include "esp32c3/clk.h"
+#endif
+
+TEST_CASE("Test effect of rtc clk calibration compensation on system time", "[esp_system]")
+{
+    uint32_t prev_cal = esp_clk_slowclk_cal_get();
+    int64_t t1 = esp_system_get_time();
+
+    // Modify calibration value
+    esp_clk_slowclk_cal_set(prev_cal/2);
+
+    // Internally, the origin point of rtc clk has been adjusted
+    // so that t2 > t1 remains true
+    int64_t t2 = esp_system_get_time();
+
+    TEST_ASSERT_GREATER_THAN(t1, t2);
+
+    // Restore calibration value
+    esp_clk_slowclk_cal_set(prev_cal);
+
+    t2 = esp_system_get_time();
+
+    TEST_ASSERT_GREATER_THAN(t1, t2);
+}

+ 2 - 1
components/esp_timer/CMakeLists.txt

@@ -1,7 +1,8 @@
 idf_build_get_property(target IDF_TARGET)
 
 set(srcs "src/esp_timer.c"
-         "src/ets_timer_legacy.c")
+         "src/ets_timer_legacy.c"
+         "src/system_time.c")
 
 if(CONFIG_ESP_TIMER_IMPL_FRC2)
     list(APPEND srcs "src/esp_timer_impl_frc_legacy.c")

+ 1 - 2
components/esp_timer/include/esp_timer.h

@@ -186,8 +186,7 @@ esp_err_t esp_timer_delete(esp_timer_handle_t timer);
 
 /**
  * @brief Get time in microseconds since boot
- * @return number of microseconds since esp_timer_init was called (this normally
- *          happens early during application startup).
+ * @return number of microseconds since underlying timer has been started
  */
 int64_t esp_timer_get_time(void);
 

+ 7 - 0
components/esp_timer/private_include/esp_timer_impl.h

@@ -117,3 +117,10 @@ uint64_t esp_timer_impl_get_counter_reg(void);
  * @return the value of the alarm register
  */
 uint64_t esp_timer_impl_get_alarm_reg(void);
+
+#if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
+/**
+ * @brief Initialize esp_timer as system time provider.
+ */
+void esp_timer_impl_init_system_time(void);
+#endif

+ 1 - 17
components/esp_timer/src/esp_timer.c

@@ -384,9 +384,7 @@ esp_err_t esp_timer_init(void)
     }
 
 #if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
-    // [refactor-todo] this logic, "esp_rtc_get_time_us() - g_startup_time", is also
-    // the weak definition of esp_system_get_time; find a way to remove this duplication.
-    esp_timer_private_advance(esp_rtc_get_time_us() - g_startup_time);
+    esp_timer_impl_init_system_time();
 #endif
 
     return ESP_OK;
@@ -517,20 +515,6 @@ int64_t IRAM_ATTR esp_timer_get_next_alarm(void)
     return next_alarm;
 }
 
-// Provides strong definition for system time functions relied upon
-// by core components.
-#if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
-int64_t IRAM_ATTR esp_system_get_time(void)
-{
-    return esp_timer_get_time();
-}
-
-uint32_t IRAM_ATTR esp_system_get_time_resolution(void)
-{
-    return 1000;
-}
-#endif
-
 bool esp_timer_is_active(esp_timer_handle_t timer)
 {
     return timer_armed(timer);

+ 53 - 0
components/esp_timer/src/system_time.c

@@ -0,0 +1,53 @@
+// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Provides strong definition for system time functions relied upon
+// by core components.
+#include "sdkconfig.h"
+
+#if CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER
+#include "esp_timer.h"
+#include "esp_timer_impl.h"
+
+#include "esp_private/startup_internal.h"
+
+#if CONFIG_IDF_TARGET_ESP32
+#include "esp32/rtc.h"
+#elif CONFIG_IDF_TARGET_ESP32S2
+#include "esp32s2/rtc.h"
+#elif CONFIG_IDF_TARGET_ESP32S3
+#include "esp32s3/rtc.h"
+#elif CONFIG_IDF_TARGET_ESP32C3
+#include "esp32c3/rtc.h"
+#endif
+
+// Correction for underlying timer to keep definition
+// of system time consistent.
+static int64_t s_correction_us = 0;
+
+void esp_timer_impl_init_system_time(void)
+{
+    s_correction_us = esp_rtc_get_time_us() - g_startup_time - esp_timer_impl_get_time();
+}
+
+int64_t IRAM_ATTR esp_system_get_time(void)
+{
+    return esp_timer_get_time() + s_correction_us;
+}
+
+uint32_t IRAM_ATTR esp_system_get_time_resolution(void)
+{
+    return 1000;
+}
+#endif

+ 1 - 1
components/newlib/port/esp_time_impl.c

@@ -51,7 +51,7 @@
 // Offset between FRC 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)
-uint64_t s_microseconds_offset = 0;
+int64_t s_microseconds_offset = 0;
 #endif
 
 #ifndef CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER

+ 3 - 1
components/newlib/test/test_time.c

@@ -17,6 +17,8 @@
 #include "esp_system.h"
 #include "esp_timer.h"
 
+#include "esp_private/system_internal.h"
+
 #if CONFIG_IDF_TARGET_ESP32
 #include "esp32/clk.h"
 #define TARGET_DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ
@@ -403,7 +405,7 @@ void test_posix_timers_clock (void)
     TEST_ASSERT_EQUAL_INT(1000, ts.tv_nsec);
 
     TEST_ASSERT(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
-    delta_monotonic_us = esp_timer_get_time() - (ts.tv_sec * 1000000L + ts.tv_nsec / 1000L);
+    delta_monotonic_us = esp_system_get_time() - (ts.tv_sec * 1000000L + ts.tv_nsec / 1000L);
     TEST_ASSERT(delta_monotonic_us > 0 || delta_monotonic_us == 0);
     TEST_ASSERT_INT_WITHIN(5000L, 0, delta_monotonic_us);
 

+ 1 - 1
tools/ci/config/target-test.yml

@@ -580,7 +580,7 @@ UT_047:
 
 UT_C3:
   extends: .unit_test_c3_template
-  parallel: 29
+  parallel: 30
   tags:
     - ESP32C3_IDF
     - UT_T1_1