Skip to content

Commit

Permalink
Provide time implementations in RTC.cpp, add test
Browse files Browse the repository at this point in the history
Checked on esp8266, rp2040, esp32s2, host.
  • Loading branch information
mikee47 committed Jun 4, 2024
1 parent 2cb3a57 commit bba0cfc
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 124 deletions.
4 changes: 4 additions & 0 deletions Sming/Arch/Esp32/Platform/RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
****/

#include <Platform/RTC.h>
#include <sys/time.h>

// #include <ESP_VARIANT/clk.h>
extern "C" uint64_t esp_clk_rtc_time(void);
Expand Down Expand Up @@ -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);
}
23 changes: 22 additions & 1 deletion Sming/Arch/Esp8266/Platform/RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <Platform/RTC.h>
#include <esp_systemapi.h>
#include <sys/time.h>

RtcClass RTC;

Expand Down Expand Up @@ -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;
}
8 changes: 8 additions & 0 deletions Sming/Arch/Rp2040/Platform/RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include <Platform/RTC.h>
#include <DateTime.h>
#include <hardware/rtc.h>
#include <sys/time.h>

extern "C" int settimeofday(const struct timeval*, const struct timezone*);

RtcClass RTC;

Expand Down Expand Up @@ -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 = {
Expand Down
130 changes: 7 additions & 123 deletions Sming/Components/axtls-8266/axtls-8266.patch
Original file line number Diff line number Diff line change
Expand Up @@ -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 <c_types.h>
+#if 0
+
#include <time.h>
-#include <sntp.h>
+#include <lwip/sntp.h>
#include <sntp.h>

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
Expand Down
28 changes: 28 additions & 0 deletions tests/HostTests/modules/DateTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<delay>([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<TestDate>& dates)
Expand Down

0 comments on commit bba0cfc

Please sign in to comment.