[riot-devel] Timers

Gaëtan Harter gaetan.harter at fu-berlin.de
Mon Feb 26 12:06:07 CET 2018


Hi,

I think that giving more precise APIs and removing the low level 
implementation detail from it is a good thing.
It means that the library can adapt to the current hardware and PM 
constraints.


I have questions regarding the transition to new timers.
As several modules have dependencies to xtimer both in headers or source 
files, they would need to be adapted to the new api.

Do you think that the new API could be implemented on top of the current 
xtimer with some glue code as a temporary solution ?
This would allow switching modules to the new API even if some boards 
still implement it with xtimer.


And just for precision regarding "removing 64bit time functions".
You want to remove all the 64bit arguments in timer API ?
This would mean that, when you want to say sleep "6hours" or "1 week", 
the developer should say he wants to use a 1second timer, and not the μs 
one.
Then, if there is only a μs timer, it would internally still be 
implemented as storing a 64b value somehow but at least its removed from 
the API.

I think its a good idea to put this in the API, because it gives more 
information to the timer library on what the developer wants to do.
In case where I have timers like "sleep(30 * USECS_PER_SEC)" in reality 
the timer does not need to even be precise at all.


The constraints I see with something like this, is give some precision 
control functionalities.

I would maybe want to control the trigger time offset if I repeat this 
sleep.
Its not a problem if it has a 0.5 seconds offset, but I would not like 
to have this offset adding over time.
So be sure that I can easily do, "trigger every N seconds, but do not 
drift over time".

Also, there may be cases where I would like to say "wake me up before 
XXX" instead of "wake me up after".
This could allow adapting for the last seconds with a higher precision 
timer if I need a more precise trigger time than the timer gives me.


Gaëtan

On 24.01.2018 23:37, Kaspar Schleiser wrote:
> Hi all,
>
> I guess it is time to coordinate improving RIOT's timers - again.
>
> IMO xtimer is a dead end. It was designed with good intentions, but
> unfortunately with not much real-world experience. It has also
> (d)evolved into a complex and inflexible #ifdef-mess...
>
> Here's what I think is bad about it:
>
> - it allows only one type of base timer. On most platforms it tries to
> use one 1MHz periph/timer. there are PR's and hacks to make it use e.g.,
> 32KHz RTTs or low power timers, but they didn't make it to master. The
> API basically enforces 1us ticks, and mapping unchanged code bases to
> very different timers is just too error prone. Also, the API would
> require choosing at compile time, which is just too inflexible.
>
> - xtimer still doesn't support pm
>
> - by forcing 1us time, xtimer also requires 64bit time functions in
> order to support > 2**32us (~71min) timeouts
>
> - xtimer is not ISR safe (xtimer_now() with <16bit base timers can break)
>
> - xtimer_t is quite large (20b on 32bit platforms)
>
> - xtimer's code has become very complex due to us/tick conversion and
> the many #ifdefs that grew into it
>
> Here's what I propose:
>
> - re-write from scratch
>
> - in the API, allow "instances", e.g.:
>
> timer_now(instance);
> timer_set(instance, timer_object);
>
> where an "instance" provides state and function pointers.
>
> - implement backends for periph/timer, rtt, rtc, lptim, systick, whatever
>
> - provide global instance aliases that every board provides, e.g.,
> "TIMER_USEC", "TIMER_MSEC", "TIMER_SEC". Map those to available timer
> backends. Make it possible to enable / disable them as needed.
>
> - allow application specific timers to use the same API (e.g., allow
> setting up a very high speed timer, which can be used alongside
> "default" timers)
>
> - provide stackable "converters"
>    e.g., if there's no MSEC resolution low power timer that can be mapped
> to "TIMER_MSEC", use "TIMER_USEC", but transparently convert all values
>    or if periph/timer doesn't support 32bit, create a "timer instance"
> that transparently handles the extension.
>    Maybe stack those (e.g., if the rtt backend only supports 1024hz and
> 16bit, stack a 1024 to 1000 converter on that, stack a 16bit to 32bit on
> that and map the result to "TIMER_MSEC".
>   this would lead to re-usable components that can also be individually
> tested (think unittests using a software-controlled fake timer).
>
> - provide either clear convention (e.g., TIMER_USEC stops when sleeping,
> unless a timer using it is set, TIMER_MSEC keeps running in low power
> mode) or controlling API (e.g., "timer_block_sleep(TIMER_USEC)" for
> behaviour in sleep modes
>
> - try to slim down the timer struct (if possible)
>
> - drop the 64bit API (usec resolution over 64bit range is unrealistic on
> real hardware. if, for larger ranges, TIMER_MSEC or TIMER_SEC can be
> used, the range that 64bit provides is not needed anymore. thus all the
> expensive 64bit arithmetic can be dropped)
>
> - consider new insights like the clock domain issue fixed by [1]
>
> - obviously, avoid long-standing xtimer bugs like the ISR unsafeness
>
> The main point I would like to push is the introduction of "timer
> instances", which would basically make the timer interface object
> oriented. This would allow having multiple implementations with
> different tradeoffs without changing actual application code.
>
> What do you think?
>
> Kaspar
>
> [1] https://github.com/RIOT-OS/RIOT/pull/7053
> _______________________________________________
> devel mailing list
> devel at riot-os.org
> https://lists.riot-os.org/mailman/listinfo/devel



More information about the devel mailing list