Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys/xtimer: multiple hardware timer support #9308

Closed
wants to merge 2 commits into from

Conversation

ZetaR60
Copy link
Contributor

@ZetaR60 ZetaR60 commented Jun 7, 2018

Contribution description

This is a very WIP PR to add support for multiple hardware timers to xtimer. A hardware abstraction layer interfaces xtimer to the low-level timers, allowing easy addition and maintenance of low-level timers. Configuration should be reverse-compatible with the old configuration (requiring no alterations to board.h), but multiple timers can be added by creating an xtimer_params.h file, in the style of how the drivers work. I intend to have periph/timer, periph/rtt, and periph/rtc support added. It may also be possible to add support for drivers/ds1307 and similar discrete RTC modules, but I do not have one of these lying around.

One of my primary reasons for adding this is to create better support for sleep modes in xtimer. Consider the following example atmega1284p setup:

  • system clock 8MHz
  • RTC crystal 32kHz
  • timer1 set to count system clock at 1MHz
  • timer3 set to count system clock at 125kHz (prescale by 1/64)
  • timer2 set to count RTC crystal at 32 Hz

If the xtimer_sleep time is very short, then the 1MHz timer is used. If it is medium, then the 125kHz timer is used. If it is long then the 32 Hz timer is used. Here is the current used in different power modes (according to the datasheet at 3.3V):

  • System is active at 8MHz (figure 30-348): 4.5 mA
  • System is idle when using 1MHz timer. Switch to idle mode, reduce system clock to 1MHz, and disable timer prescaling (figure 30-353). 200uA
  • System is idle when using 125kHz timer. Switch to idle mode, reduce system clock to 125kHz, and disable timer prescaling (figure 30-354). 60uA (better if more aggressive prescaling, but there isn't a figure for that)
  • System is idle when using 32 Hz timer. Switch to power-save mode, which turns off the system clock (figure 30-357). <1uA (slightly higher due to periodic wakes to handle overflow events)

Current state

sys/include/xtimer/hal.h is incomplete
sys/xtimer/xtimer_hal.c is messy and does not reflect intended change
sys/xtimer/xtimer.c and sys/xtimer/xtimer_core.c haven't been altered yet
xtimer headers may require some further alterations.
Nothing has been tested yet.

Posted mainly for discussion.

Issues/PRs references

This affects discussion of div / frac requirements in #9280 and #9283

@bergzand bergzand added Area: timers Area: timer subsystems State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR labels Jun 7, 2018
@ZetaR60 ZetaR60 mentioned this pull request Jun 7, 2018
24 tasks
@jnohlgard
Copy link
Member

@ZetaR60 Send me an email, we should coordinate timer subsystem improvements to avoid doing the same work twice.

@Josar
Copy link
Contributor

Josar commented Jun 8, 2018

Just to add my thoughts: using 3 timers is a high usage of resources or not?
As for rtc and xtimer there seems to be the best thing to have two timers.

But maybe it is possible to just change the xtimer divider instead of using 2 timers.

Maybe changing the divider if next target allows it to the biggest divider that is possible. This could allow multiple divider.

Before take timer value converted to fastest tick base, add to xtimer_now counter, set timer to zero, change divider.

In the overflow add one highest counter timer circle, based on actual divider.

When new timer is set ensure divider is se to fastest tick base.
Afterwards check for divider adjustment.

When timer is fired set highest tick base.

Take into Account that timer value is not in fastest tick base when read out.

Something like this could work, IMHO.
It will add some jitter which can be adjusted based on cpu cicle, as the divider change will always take the same amount of cpu ticks.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Jun 8, 2018

@Josar Thanks for the feedback. The reason for having a 3 timer example with different prescaler settings is to show that you can perform that trick with swapping the system clock prescaler and counter prescaler to get significant power gains. It is a use case for having multiple timers with the same API, which would not be possible if RTC support was added to xtimer in a simple way.

As for your other suggestions: this PR will probably change radically or may be canceled depending on how other devs are working on xtimer. I will leave it up for now, and see how things go.

@Josar
Copy link
Contributor

Josar commented Jun 14, 2018

@ZetaR60 I understand that, but what I meant is two timer one rtc for sleep and precision and one xtimer with changeable prescaler.
This would also show the possibility to save power.

It was also no criticism just a idea I was thinking about in the last days.

One nice feature I was thinking about is interconnect the xtimer with the rtc. As the xtimer might slack or be too fast. If it is configured to be too fast it can be slowed down in every overflow cycle by comparing to the rtc and just wait some ticks.

But I will first work on two other xtimer related things. #9211 #8990

@ZetaR60 ZetaR60 closed this Jun 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: timers Area: timer subsystems Discussion: RFC The issue/PR is used as a discussion starting point about the item of the issue/PR State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants