Hi,
Thanks for starting this! It's very much appreciated.
Discussing these things, reaching common ground and documenting
decisions and findings
during this process is IMO one of the most important things to do before
we move on.
I'm really sorry to write this wall of text, but there are so many
things to this timer topic where
we IMO lack a facts driven analysis, decision- and development-process.
This is combined with a lack of documentation of decisions and their
implications.
TL;DR:
let's try to decide what is good for our high level timer based on
measurable facts.
For that we need detailed knowledge on the hardware we target, the
software that will use the high level timer,
and measurements/benchmarks that tell us what are the ups an downs of
different ways of implementation.
Side note: I think we should move the discussion to an RDM PR for the
design document and discuss there to not get lost.
In the much too long version below I comment mostly on the design
document, other quotes as indicated.
RIOT needs an easy to use, efficient and flexible timer system that
allows precise high-frequency (microsecond scale) timings *alongside*
low-power timers.
For example, an application might include a driver requiring
high-frequency (microsecond scale) timings, but at the same time needs
to run on batteries and thus needs to make use of low-power timers
that can wake up the device from deep sleep.
I fully agree that this currently is a problem and it needs to be resolved.
But what this statement essentially points out, is that the xtimer API
either misses
an instance parameter to be used on different low level timers or that it
misses the functionality to internally handle multiple low level timers
to multiplex
timeouts to the (different) available hardware instances to fulfill
low-power and high precision sleep requirements.
The problem statement implies nothing related to the rest of the high
level timer API and design at all.
Thus, it is not a problem statement that shows ztimer is our only option.
*efficient*
-in which dimensions? Do we favor small RAM, ROM, CPU overhead?
-how do we prefer this to scale if more or less timers are used?
-does it make sense to decide for only one of these things at all? (one
implementation may not suit everyone)
-just thinking: would it hurt to have one memory efficient
implementation and one that is "bigger, but faster"?
*flexible*
-in level of manual control it provides?
-in level of automatic functionality and abstraction it provides?
*precision (& accuracy)*
-the bounds are defined by the hardware.
-the question is how do we come as close as possible to the capabilities
the HW provides.
-where do we need trade-offs?
*low-power*
-dependencies are mostly defined by the hardware
-How do we model these dependencies?
-for our power management we try to do things implicit.
-how does this work together with a timer that needs to be called
with explicit instances?
-why should the timer API differ from that principle?
The following general questions pop up:
-What does the hardware provide that is abstracted by this high level timer?
-How much abstraction do we need?
-Where do we need trade-offs?
-How do we balance them?
-Based on what information?
Please don't get me wrong, I'm not in principle for or against xtimer,
ztimer (or even wtimer, the whatever timer;)
Yes, 64 bit time intuitively doesn't sound like a perfect fit for the
IoT, but how does this translate to numbers (also different scenarios)?
Yes, xtimer is broken. Yes, it needs fixing or replacement.
*But: the functional problems related to xtimer are not related to it's
API, it is the implementation!*
General requirements:
- very efficient timers for use in time-critical drivers
This statement touches memory, runtime overhead and precision, but isn't
precise on how to balance between them.
easy-to-use interface (unified interface)
Very much a matter of taste, but also what is the importance of "unified"?
If there are two completely distinct use-cases (requirements) why
enforce unified API for that?
work with varying MCU timer widths (16, 24, 32-bit timers)
Agree, an absolute must! (though I'd rather specify it more as "any width")
- adaptable to varying configurations of timers, RTTs, RTCs
(use RTC if available for super-long-time timers)
- this means that applications and / or system modules need to be able
to set timers on different timer hardware (configurations)
*simultaneously*
To me this feels like it is asking for an API below the high level timer
that fits various kind of hardware (?).
We currently miss such an API. Though, an extended periph_timer could be
used for most (all?) of it.
API (necessary functionality):
- Wait for a time period (e.g. timer_usleep(howlong))
- receive message after given period of time (e.g. timer_msg(howlong))
- receive message periodically
- Await a point in time
- Wait for a (past) time