-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
timer: cortex-m systick: add idle timer #63187
timer: cortex-m systick: add idle timer #63187
Conversation
914db9d
to
d787fe5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for submitting this. I have a quite similar need for a different use case:
In other STM32 series which have a low power timer which helps counting tick in lp modes (stop
modes in STM32 nomenclature), we would need the same functionality to enter deeper sleep states (standby
mode) where even LP timer would lose its clock and only RTC could be used (common point with your use case).
My understanding is that to implement my use case, one option would be to reproduce the nearly* same piece of code in drivers/timer/stm32_lptim_timer.c
. Then maybe others would need the same implementation in their own timer driver.
So here is my (not blocking) suggestion:
Since this piece of code is destined to be duplicated in multiple timer drivers, I wonder if it could be implemented as a "generic timer back up service", rather than a specific cortex_m_systick one.
*Note: in my case, I would not need an extra logic:
Using lptimer, I would be able to enter some of the sleep states and only the deepest one would need to trigger use of counter/RTC wakeup. So the idle
parameter will not be sufficient and I would need way to distinguish next state: stop or standby.
I guess this extra functionality can be added later on in a "generic timer back up service".
Thanks for the comment. Very interesting case. However, I've tried to extract common code of the "back up service" for all timers and my conclusion is that it is not a good idea. 2 main points: the code uses a local variable, and it is important to read values of the two timers as soon as possible (no calculation between). The one thing would make sense, I think I can change the config and chosen string to Please let me know what you think. |
Do you know who would be able to review this PR? |
What about setting variable scope to global? |
and .. @teburd :) ! |
I've been thinking about your case. IMO, there is a simply way to handle that. You can compare the measurement of IDLE and system timers. If a difference is bigger than ~10%/1-2 IDLE timer ticks, it means the system timer was stopped and needs correction. Does it make sense? |
Actually my point is that the timer to use depends on the sleep duration (defined by low power state residency). Since standby mode (and use of RTC counter) would require longer time to exit (and potentially also enter), I would go in standby mode only if time allows and, for shorter timeout periods, I would use STOP Mode / LPTIM. This knowledge is available in |
Make sense |
d787fe5
to
bb0c2db
Compare
Friendly ping :-) Please review if you can, this change is very important for my work. |
This is a pretty significant change to the cortex-m timer, and that's a widely used critical piece of software in Zephyr. I get the idea here, though I'm unsure about this idea of the timer depending on the counter API and driver. @npitre is honestly probably the best person to review this |
Thanks for your response. |
What does the `idle_lock` protect against?
|
When we enter the
have to happen one after another, without any interruption. EDIT: I can see now, that |
Still, my question remains. Unless you fear concurrent reentrancy into |
Some chips, that use Cortex-M SysTick as the system timer, disable a clock in a low power mode, that is the input for the SysTick e.g. STM32Fx family. It blocks enabling power management for these chips. The wake-up function doesn't work and the time measurement is lost. Add an additional IDLE timer that handles these functionality when the system is about to enter IDLE. It has to wake up the chip and update the cycle counter by time not measured by the SysTick. The IDLE timer has to support counter API (setting alarm and reading current value). Signed-off-by: Dawid Niedzwiecki <[email protected]>
bb0c2db
to
7bae342
Compare
Thanks for the responses. Disabling interrupts was what I needed, but after making sure the Anyway, the existing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully understand it all and I don't have access to affected platforms, but those changes are all confined inside CONFIG_CORTEX_M_SYSTICK_IDLE_TIMER so that is safe to those who don't need it.
Thanks :-) Is there anything I should explain more in details? |
Hello :-) do you know anyone else who could review the PR and approve it? Or I should do something more. |
This needs maintainer approval (@andyross) |
@andyross can I somehow speed up review? :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Came here on a ping. This all seems reasonable to me, a few notes, but the logic seems fine.
static uint32_t idle_timer_pre_idle; | ||
|
||
/* Idle timer used for timer while entering the idle state */ | ||
static const struct device *idle_timer = DEVICE_DT_GET(DT_CHOSEN(zephyr_cortex_m_idle_timer)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that you're predicating this on a DTS counter device already, you could do this entirely with devicetree and avoid the extra kconfig.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, but I would like to keep the kconfig with the help for additional documentation. If you want, I can change the config to non user-configurable one as a follow-up PR. Does it make sense?
There are chips e.g. STMFX family that use SysTick as a system timer, | ||
but SysTick is not clocked in low power mode. These chips usually have | ||
another timer that is not stopped, but it has lower frequency e.g. | ||
RTC, thus it can't be used as a main system timer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to document the required interface for this somewhere. "The idle timer must be a counter device chosen in device tree via...", etc...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirement is mentioned later in the help message
The chosen IDLE timer node has to support setting alarm from the counter API.
Some chips, that use Cortex-M SysTick as the system timer, disable a clock in a low power mode, that is the input for the SysTick e.g. STM32Fx family.
It blocks enabling power management for these chips. The wake-up function doesn't work and the time measurement is lost.
Add an additional IDLE timer that handles these functionality when the system is about to enter IDLE. It has to wake up the chip and update the cycle counter by time not measured by the SysTick. The IDLE timer has to support counter API (setting alarm and reading current value).
Related:
#61631
#60558
#19755