sys/walltime: add module for system time#21343
Conversation
| * @brief Common functions to access the wall-clock / real time clock | ||
| * @{ | ||
| * @file | ||
| * |
There was a problem hiding this comment.
Also since there is no documentation for struct tm (I think time.h is part of the standard library?), it might be good to include a link to a reference for it.
This is the link used by drivers/periph/rtc.h: https://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
RIOT/drivers/include/periph/rtc.h
Lines 17 to 20 in 85dc9be
mguetschow
left a comment
There was a problem hiding this comment.
Nice, I like this! Some first thoughts on it below.
| #endif | ||
|
|
||
| static uint32_t _boottime; | ||
| #ifdef BACKUP_RAM |
There was a problem hiding this comment.
Is that macro documented somewhere?
There was a problem hiding this comment.
Does this count?
$ rg BACKUP_RAM -B 5 features.yaml
417-- title: RAM Related Features
418- help: These features indicate presence of special RAM regions or features
419- features:
420- - name: backup_ram
421- help: A special portion of RAM is retained during deep sleep.
422: Variables can be placed there by annotating them with the `BACKUP_RAM`
See https://doc.riot-os.org/feature-list.html#autotoc_md2404 for the output
There was a problem hiding this comment.
Hum, that's indeed something, but probably nothing doxygen would find when using @ref BACKUP_RAM
sys/walltime/walltime.c
Outdated
|
|
||
| void walltime_set(struct tm *time) | ||
| { | ||
| int32_t diff = rtc_mktime(time) - walltime_get_riot(NULL); |
There was a problem hiding this comment.
I think the int32_t could lead to unexpected results. For example the extreme case 0 - 4294967295 becomes 1.
I would expect -4294967295
You could figure out the sign and compute the number as uint32_t higher - lower.
There was a problem hiding this comment.
diff --git a/sys/walltime/walltime.c b/sys/walltime/walltime.c
index 903e856a16..5171cb0770 100644
--- a/sys/walltime/walltime.c
+++ b/sys/walltime/walltime.c
@@ -17,6 +17,8 @@
*
* @}
*/
+#include <stdio.h>
+
#include "auto_init.h"
#include "auto_init_utils.h"
#include "auto_init_priorities.h"
@@ -96,7 +98,10 @@ time_t walltime_get_unix(uint16_t *ms)
void walltime_set(struct tm *time)
{
- int32_t diff = rtc_mktime(time) - walltime_get_riot(NULL);
+ uint32_t t;
+ int32_t w;
+ int32_t diff = (t = rtc_mktime(time)) - (w = walltime_get_riot(NULL));
+ printf("t %"PRIu32" - w %"PRId32" = diff %"PRId32"\n", t, w, diff);
_boottime += diff;
#ifdef BACKUP_RAM
_boottime_bkup += diff;> 2025-05-06 15:29:20,168 # main(): This is RIOT! (Version: 2025.04-devel-522-g90fc5e-walltime)
> walltime set 4000-01-01 00:00:00
2025-05-06 15:29:23,464 # walltime set 4000-01-01 00:00:00
2025-05-06 15:29:23,480 # t 2353209856 - w 3 = diff -1941757443
2025-05-06 15:29:23,481 # time changed by -1941757443 sec, 0 ms
So when going very very very far in the future, the diff becomes negative.
I know that no one actually cares about the year 4000, but consider some user input or malformed network packet ... whatever.
| return now - _boottime; | ||
| } | ||
|
|
||
| static void auto_init_uptime(void) |
There was a problem hiding this comment.
maybe guard with IS_USED(MODULE_AUTO_INIT_WALLTIME/UPTIME)
There was a problem hiding this comment.
We always want to auto-init this module
How would I implement an on-time change callback? |
We can add that to the I wanted to get the core API in first, but might as well already add this here.
Yea applications must not use the
There only is a single wall time/system time. I'm happy to hook up different backends like |
d3999cd to
90fc5e4
Compare
Since there will only be a single active Or a |
|
+1 for the |
It's a shame we don't have that upstream though… |
| __attribute__((weak)) | ||
| int walltime_impl_get(struct tm *time, uint16_t *ms) | ||
| { | ||
| uint32_t now = ztimer_now(ZTIMER_MSEC); |
There was a problem hiding this comment.
The walltime module is good from my perspective. As the xtimer_compat was merged, it would be nice to have it here.
There was a problem hiding this comment.
Hm we don't have a xtimer_now_msec(), but I could add that.
There was a problem hiding this comment.
Ah I thought there is. It's a logic addition to xtimer_now_usec. It should probably favor ZTIMER_MSEC over ZTIMER_USEC.
There was a problem hiding this comment.
but tbh I'm not sure how useful a non-msec based backend would be here.
ZTIMER_USEC wraps after 1h and 11 minutes.
There was a problem hiding this comment.
If there is no implication of using ztimer_msec towards not using ztimer_msec then yes msec is better than usec here.
Then ztimer_msec should be added to the Makefile.dep.
There was a problem hiding this comment.
ahh but only in the fallback case... I dont know ... either you squash or add xtimer_now_msec if you like
|
Would you mind sprinkling some SPDX-license-identifier fairy dust over the new code? |
|
|

Contribution description
Currently applications use the
periph_rtcAPI directly if they want to track wall clock time.This leads to problems when the time is not provided by
periph_rtcbut some external RTC or when we want to perform actions e.g. on setting the time - then this has to be hooked up with everyperiph_rtcimplementation.Instead, provide a wrapper API that applications can use to obtain the current system time without accessing the RTC API directly.
This allows to write applications that are agnostic to the availability of
periph_rtcand still can provide some proper timestamps.Testing procedure
Enable the
walltimemodule.This will provide a
walltimecommand to get / set the time and display the time since last boot.Issues/PRs references
Alternative to #17416, #21366