RIOT-OS / RIOT

RIOT - The friendly OS for IoT
https://riot-os.org
GNU Lesser General Public License v2.1
4.95k stars 1.99k forks source link

Migration of RIOT to ztimer? #13753

Closed jue89 closed 2 years ago

jue89 commented 4 years ago

Description

I'm currently trying to push RIOT forward in terms of power management. Now that ztimer has made it into master, it's a really good basis to achieve a power management that just works. The most important aspect of ztimer is its ability to distinguish between high precision, high frequency timers and long running, moderate frequency timers. Those timers are backed by a fitting hardware peripheral: i.e. high precision, high frequency timers use a high frequency hardware timer and the long running, moderate frequency timers use a RTT peripheral timer.

This comes in handy, since on every MCU that I worked with it is necessary to disable any peripheral that requires a high frequency clock source in order to save energy. So, the high frequency hardware timer must only run if it is required. For that reason I started implementing the interaction of ztimer and pm_layered in #13722.

But that's just half the battle. RIOT and the application must start to use ztimer and also pick the right timer (i.e the moderate frequency timer for long running tasks and the high frequency timer for short running tasks). That's the reason for this issue: Start a discussion how to get to that point.

The current situation

The widely-used and established timer system is xtimer. It is based solely on high frequency hardware timers. It extends those timers to 64-bit allowing for long-running timers.

ztimer features a wrapper for xtimer named xzimer_on_ztimer. This wrapper substitutes the high frequency hardware timer required for xtimer with the high frequency timer offered by ztimer. This allows for coexistence of both timers in the same application but comes with a problem: If this wrapper is used, ztimer never knows if there is an actual user of the high precision timer or if it is just the tick counter running for xtimer. This leads to the situation where the high frequency hardware timer is never disabled and no power management takes place.

ztimer features another alternative wrapper for xtimer named ztimer_xtimer_compat. It maps every API call to ztimer excluding those requiring 64-bit wide timers: There are no suitable replacement functions present in ztimer. But with this wrapper, ztimer now gets the whole picture who requires the high frequency hardware timer to be running and is also able to handle power management.

Beside xtimer, a wrapper named evtimer for long-running tasks has been established to reduce the overhead that comes with all the 64-bit algorithmic. evtimer uses 64-bit xtimer behind the curtains. It has been introduced with the intention to be replaced at some time:

Provides timers for events up to $2^{32}$ milliseconds in the future.

Note Experimental and likely to replaced with unified timer API

RIOT's main timer subsystem is xtimer, but for many applications xtimer's 64-bit absolute time values are wasteful or clumsy to use.

Beside all the technical parts inside of RIOT, a ROIT Developer Memo is written in #12970. It will describe how a high level timer API of RIOT should look like, once its finished and becomes effective.

How to move forward?

I see two different paths (and @kaspar030 added a third one) to get to a timer API that allows for a power management that just work

1. Migrate all RIOT parts requiring long-running timer to evtimer

In #13661 I started working on evtimer_on_ztimer that uses the moderate frequency timer of ztimer as the timer backend. This will automatically move all long-running timers to the moderate frequency hardware timer. But this also creates certain overhead due to the wrapper but doesn't directly bind ztimer into the code of RIOT core components, like GNRC.

13667 lists modules, that must be touched.

2. Migrate all RIOT parts requiring long-running timer to ztimer

This is of course the cleanest solution since no wrapper aren't required at all. But this path also feels a little bit premature to me, because #12970 isn't merged and we don't know if the outcome is congruent with that what ztimer implements.

3. Extend xtimer with methods especially for long-running timers and migrate all RIOT parts to those methods

-> See the comment down below for further details.

I would like to hear some opinions. I think, after revising a lot of code that interacts with xtimer and evtimer, we should go with path 1. Once we have achieved that and the RDM has been merged, moving all evtimer users to ztimer shouldn't be too complicated. After some time thinking over our options, I would opt for option 3.

Useful links

evtimer: https://riot-os.org/api/group__sys__evtimer.html xtimer: https://riot-os.org/api/group__sys__xtimer.html ztimer: https://riot-os.org/api/group__sys__ztimer.html

kaspar030 commented 4 years ago

I would like to hear some opinions. I think, after revising a lot of code that interacts with xtimer and evtimer, we should go with path 1. Once we have achieved that and the RDM has been merged, moving all evtimer users to ztimer shouldn't be too complicated.

I see another option. xtimer's API only allows setting microseconds, but many places use it to set millis or even seconds. There is already xtimer_sleep() sleeping seconds, doing the conversion to 64bit usec underneath. We could introduce xtimer_set_sec(), xtimer_set_millis() etc, that just do xtimer_set_millis(t, millis) { xtimer_set64(t, millis * 1000)}. Then, instead of converting to evtimer, just convert to the fitting API. ztimer_xtimer_compat can easily add these (mapping to the corresponding ztimer clock). And those calls can be easily converted to ztimer using coccinelle (or even regexps).

This would be a move into an easier possible migration towards ztimer, without expanding the use of evtimer, and xtimer's API got more powerful (should we decide not to use ztimer).

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

jue89 commented 3 years ago

Shall we create a Github Project to keep track of PRs related to the migration?

fjmolinas commented 3 years ago

Shall we create a Github Project to keep track of PRs related to the migration?

Yes I think thats a good idea!

fjmolinas commented 2 years ago

I think we can close this one with ztimer being the default xtimer backend.