mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'refactor/systimer_reset_alternative' into 'master'
Systimer reset alternative on S2 (and others) See merge request espressif/esp-idf!12694
This commit is contained in:
commit
a2740be080
@ -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
components/esp_system/README.md
Normal file
29
components/esp_system/README.md
Normal file
@ -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.
|
@ -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);
|
||||
|
||||
|
@ -316,7 +316,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
components/esp_system/test/test_system_time.c
Normal file
36
components/esp_system/test/test_system_time.c
Normal file
@ -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);
|
||||
}
|
@ -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")
|
||||
|
@ -184,8 +184,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);
|
||||
|
||||
|
@ -132,3 +132,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
|
||||
|
@ -446,9 +446,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;
|
||||
@ -600,17 +598,3 @@ 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
|
||||
|
53
components/esp_timer/src/system_time.c
Normal file
53
components/esp_timer/src/system_time.c
Normal file
@ -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
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user