From 904af10914322afbc2c4957dd8eb769a53db04af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sat, 3 Sep 2022 21:26:07 +0200 Subject: [PATCH] [core] Implement POSIX gettimeofday() and settimeofday() --- arduino/libretuya/core/LibreTuyaConfig.h | 5 +++ arduino/libretuya/core/main.cpp | 6 +++ arduino/libretuya/posix/lt_posix_api.h | 2 + arduino/libretuya/posix/time.c | 50 ++++++++++++++++++++++++ builder/arduino-common.py | 3 ++ docs/reference/config.md | 4 ++ 6 files changed, 70 insertions(+) create mode 100644 arduino/libretuya/posix/time.c diff --git a/arduino/libretuya/core/LibreTuyaConfig.h b/arduino/libretuya/core/LibreTuyaConfig.h index 16be532..448d61e 100644 --- a/arduino/libretuya/core/LibreTuyaConfig.h +++ b/arduino/libretuya/core/LibreTuyaConfig.h @@ -77,6 +77,11 @@ #define LT_UART_DEFAULT_SERIAL LT_UART_DEFAULT_PORT #endif +// Misc options +#ifndef LT_USE_TIME +#define LT_USE_TIME 0 +#endif + // Per-module logging output - applies to all loglevels #ifndef LT_DEBUG_ALL #define LT_DEBUG_ALL 0 diff --git a/arduino/libretuya/core/main.cpp b/arduino/libretuya/core/main.cpp index 86ad423..675911c 100644 --- a/arduino/libretuya/core/main.cpp +++ b/arduino/libretuya/core/main.cpp @@ -41,6 +41,12 @@ void runPeriodicTasks() { periodicTasks[0] = millis(); } #endif +#if LT_USE_TIME + if (millis() - periodicTasks[1] > 10000) { + gettimeofday(NULL, NULL); + periodicTasks[1] = millis(); + } +#endif } int main(void) { diff --git a/arduino/libretuya/posix/lt_posix_api.h b/arduino/libretuya/posix/lt_posix_api.h index b9a5f05..c27d2f4 100644 --- a/arduino/libretuya/posix/lt_posix_api.h +++ b/arduino/libretuya/posix/lt_posix_api.h @@ -1,5 +1,7 @@ /* Copyright (c) Kuba SzczodrzyƄski 2022-05-16. */ +#include + extern char *strdup(const char *); extern int strcasecmp(const char *s1, const char *s2); extern int strncasecmp(const char *s1, const char *s2, size_t n); diff --git a/arduino/libretuya/posix/time.c b/arduino/libretuya/posix/time.c new file mode 100644 index 0000000..991dbbc --- /dev/null +++ b/arduino/libretuya/posix/time.c @@ -0,0 +1,50 @@ +/* Copyright (c) Kuba SzczodrzyƄski 2022-09-03. */ + +#include +#include + +static uint32_t reset_epoch = 0; // epoch corresponding to millis() == 0 +static uint32_t reset_millis = 0; // millis() when epoch reset was performed + +int __wrap_gettimeofday(struct timeval *tv, void *tz) { + if (millis() < reset_millis) { + // the clock overflowed + reset_epoch += UINT32_MAX / 1000; + reset_millis = millis(); + } + if (!tv) { + errno = EINVAL; + return -1; + } + unsigned long m = millis(); + tv->tv_sec = reset_epoch + (m / 1000); + tv->tv_usec = (m % 1000) * 1000; + return 0; +} + +int __wrap_settimeofday(const struct timeval *tv, const struct timezone *tz) { + if (!tv) { + errno = EINVAL; + return -1; + } + unsigned long m = millis(); + reset_epoch = tv->tv_sec - (m / 1000); + reset_millis = m; + return 0; +} + +int gettimeofday(struct timeval *tv, void *tz) { + return __wrap_gettimeofday(tv, tz); +} + +int settimeofday(const struct timeval *tv, const struct timezone *tz) { + return __wrap_settimeofday(tv, tz); +} + +int _gettimeofday(struct timeval *tv, void *tz) { + return __wrap_gettimeofday(tv, tz); +} + +int _settimeofday(const struct timeval *tv, const struct timezone *tz) { + return __wrap_settimeofday(tv, tz); +} diff --git a/builder/arduino-common.py b/builder/arduino-common.py index a6b4367..3cb2879 100644 --- a/builder/arduino-common.py +++ b/builder/arduino-common.py @@ -30,6 +30,9 @@ env.Append( # wrappers from port/printf/ "-Wl,-wrap,putchar", "-Wl,-wrap,puts", + # wrappers from posix/time.c + "-Wl,-wrap,gettimeofday", + "-Wl,-wrap,settimeofday", ], ) # Arduino core uses __libc_init_array diff --git a/docs/reference/config.md b/docs/reference/config.md index 42441b4..d135156 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -107,3 +107,7 @@ The meaning of most flags is as follows: - `LT_ARD_HAS_MD5` - MD5 library implemented, `MD5Impl.h` available - `LT_ARD_HAS_WIFI` - WiFi library implemented, `WiFiData.h` available - `LT_HEAP_FUNC` - function name used to get available heap size (for `LT_HEAP_I()`) + +### Misc options + +- `LT_USE_TIME` - enables implementation of `gettimeofday()` and `settimeofday()`; checks for `millis()` overflows periodically