sys/walltime: add module for system time
Contribution description
Currently applications use the periph_rtc API directly if they want to track wall clock time.
This leads to problems when the time is not provided by periph_rtc but some external RTC or when we want to perform actions e.g. on setting the time - then this has to be hooked up with every periph_rtc implementation.
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_rtc and still can provide some proper timestamps.
Testing procedure
Enable the walltime module.
This will provide a walltime command to get / set the time and display the time since last boot.
Issues/PRs references
Alternative to #17416, #21366
Murdock results
:heavy_check_mark: PASSED
6b9137c1ff73ff128a78ee1f4e6fac8738317697 sys/walltime: add RTC backend
| Success | Failures | Total | Runtime |
|---|---|---|---|
| 10968 | 0 | 10968 | 09m:55s |
Artifacts
This allows to write applications that are independent of the RTC peripheral and allows the implementation of on-time change callbacks.
How would I implement an on-time change callback?
You expect that the backend for walltime implements the RTC API, don't you?
This limits to only only one RTC API. If I want to implement my application rtc_set_time around the RTC rtc_set_time, it does not work. I would have gone with function pointers for walltime_backend->rtc_set_time and walltime_backend->rtc_get_time
How would I implement an on-time change callback?
We can add that to the walltime module as a 2nd step, then we would only need to add it in one place instead of adding it to every RTC implementation.
I wanted to get the core API in first, but might as well already add this here.
If I want to implement my application rtc_set_time around the RTC rtc_set_time, it does not work.
Yea applications must not use the periph_rtc API if the walltime module is used to access the RTC instead - but that should be a simple change.
I would have gone with function pointers for walltime_backend->rtc_set_time and walltime_backend->rtc_get_time
There only is a single wall time/system time. I'm happy to hook up different backends like ds1307 or even dcf77 or gnss. The nice thing about the high level API is that the internals can be as complex as needed, to the user it's still just a simple get time / set time API.
The walltime is calling rtc API.
Consider the case of an external RTC.
There is the option to wrap the driver RTC API in our periph RTC API.
- Then
periph_rtcmust get substituted with the external RTC.
If the walltime would not use the RTC API but use a driver struct with function callbacks, then the walltime could be instanciated with either the periph RTC or the external RTC driver. Then periph RTC features could still be used.
If the walltime would not use the RTC API but use a driver struct with function callbacks, then the walltime could be instanciated with either the periph RTC or the external RTC driver. Then periph RTC features could still be used.
Since there will only be a single active walltime source, we might as well make that a compile-time selection inside the walltime module.
Or a weak default implementation that can be overwritten by other backends?
+1 for the weak default implementation. That would allow us to hook in our I2C RTC into the walltime module quite easily.
That would allow us to hook in our I2C RTC into the walltime module quite easily.
It's a shame we don't have that upstream though…