Skip to content

Conversation

benpicco
Copy link
Contributor

Contribution description

SysTick is a 24 bit down-counting timer that is implemented on every Cortex-M processor.
It runs at the same frequency as the CPU and can generate an interrupt when it reaches 0.

It allows to free up hardware timers for other uses and accelerates bring-up of new Cortex-M platforms since SysTick is implemented the same everywhere.

To comply with the RIOT timer interface (xtimer & ztimer) that expect an up-counting, monotonic timer,
SysTick is augmented by software to fulfill these requirements.

This also adds a software prescaler to simulate arbitrary frequencies and introduces a virtual, 32 bit counter.
That allows for longer intervals than would be possible with the SysTick hardware peripheral alone and makes it possible to use it as a backed for xtimer.

I initially hoped to see some power savings by not running a timer peripheral, but on examples/timer_periodic_wakeup power draw went up from 2.35 mA with the periph timer to 2.37 mA with the SysTick timer as source for the xtimer clock.

Testing procedure

A basic test is included with tests/periph_systick.
But it is possible to run any test or application that uses xtimer off SysTick by adding

USEMODULE += xtimer_on_systick

to the application Makefile.

This should work on any Cortex-M processor.

Issues/PRs references

@benpicco benpicco added Type: new feature The issue requests / The PR implemements a new feature for RIOT Area: cpu Area: CPU/MCU ports labels Jul 18, 2020
@benpicco benpicco force-pushed the cpu/cortexm_common-SysTick branch 3 times, most recently from 3670475 to 8df5548 Compare July 18, 2020 19:11
@bergzand
Copy link
Member

Last time I tried something with the systick timer, I found out that the timer is stopped during CPU standby. Probably because the CPU clock is stopped during those standby times. Is that the reason why power consumption increased when using the systick timer?

Copy link
Member

@maribu maribu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See inline comments

@benpicco
Copy link
Contributor Author

Last time I tried something with the systick timer, I found out that the timer is stopped during CPU standby.

But that's true for most periph timers too, usually only RTT will keep running during standby.
In the WFI state, SysTick should still be running.

But we are getting more interrupts as SysTick will overflow after 350ms at 48 MHz.

@maribu
Copy link
Member

maribu commented Jul 20, 2020

Last time I tried something with the systick timer, I found out that the timer is stopped during CPU standby.

But that's true for most periph timers too, usually only RTT will keep running during standby.
In the WFI state, SysTick should still be running.

But we are getting more interrupts as SysTick will overflow after 350ms at 48 MHz.

IMO, power saving is just broken with xtimer anyway. So I don't think we need to worry about this. Having a widely available timer backend for xtimer is IMO a nice addition when porting new CortexM based MCUs, as it allows testing and merging those boards without timer support.

With ztimer we can use an RTT for long timeouts and power saving. Having in addition a high resolution timer can complement the setup in some cases, when short but high resolution timeouts are needed e.g. in device drivers. With #13722 being merged now, the power consumption would only be higher while the high resolution timer is actually used (e.g. during an interaction sequence of a driver with the hardware).

@maribu
Copy link
Member

maribu commented Aug 5, 2020

Needs a rebase. Feel free to squash, btw.

@maribu
Copy link
Member

maribu commented Aug 5, 2020

I still think that frequency conversion is better left to the upper layer. At least ztimer should work with this. And if not, I'd say this is a bug worth fixing :-)

@benpicco benpicco force-pushed the cpu/cortexm_common-SysTick branch from d97eed8 to 2e77327 Compare August 5, 2020 20:07
@benpicco
Copy link
Contributor Author

benpicco commented Aug 5, 2020

I've moved the use of the prescaler to the systick_prescaler pseudo-module.
This way we don't have to layer xtimer on ztimer on systick if we use xtimer and can let ztimer do the prescaling once it's hooked up.

Copy link
Member

@maribu maribu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the compiler won't be able to detect that now_offset is only needed when module systick_prescaler is used. So maybe the suggested changes would result in slimmer code in that case?

*
* To comply with the RIOT timer interface that expects an up-counting, monotonic
* timer, SysTick is augmented by software to fulfill these requirements.
* This also adds a software prescaler to simulate arbitrary frequencies and introduces
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary and / or desirable?

We already have two higher level timer implementations that do exactly that, and more.

There are quite some challenges to overcome to get this right.

As is, I'd probably cut out the guts and re-implement as ztimer backend.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue was that xtimer cannot handle arbitrary frequencies: #14553 (comment)

I'm personally fine with having this a ztimer only. IMO, xtimer is on the way out anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it useful to just being able to use xtimer_on_systick to free up the periph timer and not having to configure ztimer as well.
I don't think the conditional overflow handling adds much to the code, and it's pretty minimal when enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ztimer still expects the timer to be up-counting, right?

@talih0
Copy link

talih0 commented Aug 18, 2020

In cpu/cortexm_common/vectors_cortexm.c:476, there is a comment saying that SysTick interrupt is unused. You want to remove or update it.

@benpicco
Copy link
Contributor Author

Thank you, updated.

@benpicco benpicco force-pushed the cpu/cortexm_common-SysTick branch from b007a80 to 42bfeb6 Compare August 25, 2020 07:16
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Aug 25, 2020
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Sep 9, 2020
This introduces the `xtimer_on_systick` pseudo-module that can be used
to source the xtimer clock from SysTick, available on every Cortex-M CPU.
@benpicco benpicco force-pushed the cpu/cortexm_common-SysTick branch from 333143f to 9b16b84 Compare December 3, 2020 21:41
benpicco and others added 2 commits December 8, 2020 10:50
Co-authored-by: Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
@benpicco benpicco added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Dec 9, 2020
@hugueslarrive
Copy link
Contributor

Why not handle the hardware prescaler by 8 (CLKSOURCE=0) ?

It seems confusing to me to see an option as xtimer_on_systick or filenames as systick.c or systick.h in a tickless operating system so why not use another name as "core_timer" for exemple ?

@stale
Copy link

stale bot commented Mar 2, 2022

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.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Mar 2, 2022
@stale stale bot closed this Apr 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR State: stale State: The issue / PR has no activity for >185 days Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants