From bba0cfc3bac5e52f35d750122187a5b5a126ca74 Mon Sep 17 00:00:00 2001 From: mikee47 Date: Tue, 4 Jun 2024 10:33:29 +0100 Subject: [PATCH] Provide time implementations in RTC.cpp, add test Checked on esp8266, rp2040, esp32s2, host. --- Sming/Arch/Esp32/Platform/RTC.cpp | 4 + Sming/Arch/Esp8266/Platform/RTC.cpp | 23 +++- Sming/Arch/Rp2040/Platform/RTC.cpp | 8 ++ Sming/Components/axtls-8266/axtls-8266.patch | 130 +------------------ tests/HostTests/modules/DateTime.cpp | 28 ++++ 5 files changed, 69 insertions(+), 124 deletions(-) diff --git a/Sming/Arch/Esp32/Platform/RTC.cpp b/Sming/Arch/Esp32/Platform/RTC.cpp index b5b721f806..8995950084 100644 --- a/Sming/Arch/Esp32/Platform/RTC.cpp +++ b/Sming/Arch/Esp32/Platform/RTC.cpp @@ -9,6 +9,7 @@ ****/ #include +#include // #include extern "C" uint64_t esp_clk_rtc_time(void); @@ -45,5 +46,8 @@ bool RtcClass::setRtcNanoseconds(uint64_t nanoseconds) bool RtcClass::setRtcSeconds(uint32_t seconds) { + struct timeval tv{seconds}; + settimeofday(&tv, nullptr); + return setRtcNanoseconds(uint64_t(seconds) * NS_PER_SECOND); } diff --git a/Sming/Arch/Esp8266/Platform/RTC.cpp b/Sming/Arch/Esp8266/Platform/RTC.cpp index a90f06b9a2..49e5e5b0f2 100644 --- a/Sming/Arch/Esp8266/Platform/RTC.cpp +++ b/Sming/Arch/Esp8266/Platform/RTC.cpp @@ -10,6 +10,7 @@ #include #include +#include RtcClass RTC; @@ -97,9 +98,29 @@ void loadTime(RtcData& data) // Initialise the time struct if(data.magic != RTC_MAGIC) { - debugf("rtc time init..."); + debug_d("rtc time init..."); data.magic = RTC_MAGIC; data.time = 0; data.cycles = 0; } } + +extern "C" int _gettimeofday_r(struct _reent*, struct timeval* tp, void*) +{ + if(tp) { + // ensureBootTimeIsSet(); + uint32_t micros = RTC.getRtcNanoseconds() / 1000LL; + tp->tv_sec = micros / 1000; + tp->tv_usec = micros % 1000; + } + return 0; +} + +extern "C" time_t time(time_t* t) +{ + time_t seconds = RTC.getRtcSeconds(); + if(t) { + *t = seconds; + } + return seconds; +} diff --git a/Sming/Arch/Rp2040/Platform/RTC.cpp b/Sming/Arch/Rp2040/Platform/RTC.cpp index fef78b61d5..67b8e98e56 100644 --- a/Sming/Arch/Rp2040/Platform/RTC.cpp +++ b/Sming/Arch/Rp2040/Platform/RTC.cpp @@ -11,6 +11,9 @@ #include #include #include +#include + +extern "C" int settimeofday(const struct timeval*, const struct timezone*); RtcClass RTC; @@ -52,6 +55,11 @@ bool RtcClass::setRtcNanoseconds(uint64_t nanoseconds) bool RtcClass::setRtcSeconds(uint32_t seconds) { + struct timeval tv { + seconds + }; + settimeofday(&tv, nullptr); + DateTime dt{seconds}; datetime_t t = { diff --git a/Sming/Components/axtls-8266/axtls-8266.patch b/Sming/Components/axtls-8266/axtls-8266.patch index 16eff5af6a..19688134c4 100644 --- a/Sming/Components/axtls-8266/axtls-8266.patch +++ b/Sming/Components/axtls-8266/axtls-8266.patch @@ -220,140 +220,24 @@ index 53509d0..25c568d 100644 #endif diff --git a/replacements/time.c b/replacements/time.c -index 4972119..d39481c 100644 +index 4972119..1447711 100644 --- a/replacements/time.c +++ b/replacements/time.c -@@ -16,29 +16,25 @@ +@@ -16,6 +16,8 @@ * */ -+#define _C_TYPES_H_ -+#include ++#if 0 + #include --#include -+#include + #include - extern uint32_t system_get_time(void); - extern uint64_t system_mktime(uint32_t year, uint32_t mon, uint32_t day, uint32_t hour, uint32_t min, uint32_t sec); - - static int errno_var = 0; - --int* __errno(void) { -+// These functions are implemented in Espressif SDK versions 2 and later (libmain.a) so we weaken them to avoid linker problems -+#define WEAK_ATTR __attribute__((weak)) -+ -+int* WEAK_ATTR __errno(void) { - // DEBUGV("__errno is called last error: %d (not current)\n", errno_var); - return &errno_var; - } - --unsigned long millis(void) --{ -- return system_get_time() / 1000UL; --} -- --unsigned long micros(void) --{ -- return system_get_time(); --} -- - #ifndef _TIMEVAL_DEFINED - #define _TIMEVAL_DEFINED - struct timeval { -@@ -60,12 +56,12 @@ static time_t s_bootTime = 0; - // calculate offset used in gettimeofday - static void ensureBootTimeIsSet() - { -- if (!s_bootTime) -+ if (s_bootTime == 0) - { - time_t now = sntp_get_current_timestamp(); -- if (now) -+ if (now != 0) - { -- s_bootTime = now - millis() / 1000; -+ s_bootTime = now - (system_get_time() / 1000000); - } - } - } -@@ -79,7 +75,7 @@ static void setServer(int id, const char* name_or_ip) - } - } - --void configTime(int timezone, int daylightOffset_sec, const char* server1, const char* server2, const char* server3) -+void WEAK_ATTR configTime(int timezone, int daylightOffset_sec, const char* server1, const char* server2, const char* server3) - { - sntp_stop(); - -@@ -93,22 +89,16 @@ void configTime(int timezone, int daylightOffset_sec, const char* server1, const - sntp_init(); - } - --int clock_gettime(clockid_t unused, struct timespec *tp) -+int WEAK_ATTR clock_gettime(clockid_t unused, struct timespec *tp) - { -- tp->tv_sec = millis() / 1000; -- tp->tv_nsec = micros() * 1000; -+ unsigned long us = system_get_time(); -+ tp->tv_sec = us / 1000000UL; -+ us %= 1000000UL; -+ tp->tv_nsec = us * 1000; - return 0; - } - --// seconds since 1970 --time_t mktime(struct tm *t) --{ -- // system_mktime expects month in range 1..12 -- #define START_MONTH 1 -- return DIFF1900TO1970 + system_mktime(t->tm_year, t->tm_mon + START_MONTH, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); --} -- --time_t time(time_t * t) -+time_t WEAK_ATTR time(time_t * t) - { - time_t seconds = sntp_get_current_timestamp(); - if (t) -@@ -118,30 +108,32 @@ time_t time(time_t * t) - return seconds; - } - --char* asctime(const struct tm *t) -+char* WEAK_ATTR asctime(const struct tm *t) - { - return sntp_asctime(t); - } - --struct tm* localtime(const time_t *clock) -+struct tm* WEAK_ATTR localtime(const time_t *clock) - { - return sntp_localtime(clock); - } - --char* ctime(const time_t *t) -+char* WEAK_ATTR ctime(const time_t *t) - { - struct tm* p_tm = localtime(t); - char* result = asctime(p_tm); - return result; - } - --int gettimeofday(struct timeval *tp, void *tzp) -+int WEAK_ATTR gettimeofday(struct timeval *tp, void *tzp) - { - if (tp) - { - ensureBootTimeIsSet(); -- tp->tv_sec = (s_bootTime + millis()) / 1000; -- tp->tv_usec = micros() * 1000; -+ unsigned long us = system_get_time(); -+ tp->tv_sec = s_bootTime + (us / 1000000UL); -+ us %= 1000000UL; -+ tp->tv_usec = us * 1000UL; +@@ -145,3 +147,5 @@ int gettimeofday(struct timeval *tp, void *tzp) } return 0; } ++ ++#endif diff --git a/ssl/asn1.c b/ssl/asn1.c index a08a618..3c64064 100644 --- a/ssl/asn1.c diff --git a/tests/HostTests/modules/DateTime.cpp b/tests/HostTests/modules/DateTime.cpp index 5f262a8c0d..544789b0c9 100644 --- a/tests/HostTests/modules/DateTime.cpp +++ b/tests/HostTests/modules/DateTime.cpp @@ -90,6 +90,34 @@ class DateTimeTest : public TestGroup << DateTime::getLocaleMonthName(month) << endl; } } + + TEST_CASE("time() sync") + { + auto curTime = SystemClock.now(eTZ_UTC); + DateTime dt; + dt.fromISO8601(F("2024-01-01T13:57Z")); + time_t newTime = dt; + Serial << _F("curTime ") << curTime << _F(", newTime ") << newTime << _F(" ...") << endl; + SystemClock.setTime(newTime, eTZ_UTC); + auto timer = new AutoDeleteTimer; + const auto delay = 2000; + timer->initializeMs([newTime, this]() { + auto sysClockTime = SystemClock.now(eTZ_UTC); + auto ctime = ::time(nullptr); + auto diff = sysClockTime - ctime; + auto timeDelay = sysClockTime - newTime; + Serial << _F("sysClockTime ") << sysClockTime << _F(", delay ") << timeDelay << endl; + Serial << _F("time() ") << ctime << _F(", diff ") << diff << endl; + REQUIRE(abs(1000 * timeDelay - delay) <= 1000); +#ifndef ARCH_HOST + // Can't check time() on host + REQUIRE(abs(diff) < 2); +#endif + complete(); + }); + timer->startOnce(); + pending(); + } } void checkHttpDates(const FSTR::Array& dates)