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
Add handling for synchronized low power tickers #6536
Conversation
Shouldn't |
hal/mbed_lp_ticker_api.cpp
Outdated
#include "mbed_critical.h" | ||
static void set_interrupt_wrapper(timestamp_t timestamp); | ||
#else | ||
#define set_interrupt_wrapper lp_ticker_set_interrupt |
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.
Referencing here a proposal for the change this macro : #6473 (comment) . would it be more readable?
31dfd7d
to
f2844db
Compare
Updated this PR by making the following changes:
|
I made this enabled by a macro so this code won't be present for devices which don't need it. As an alternative it could be a part of ticker info but in that case when you use the low power ticker, the microsecond ticker will also be included in your binary even for devices which don't need it.
There is already the fire now ticker API which can be used to trigger interrupts immediately, so I'm not sure if there would be much value to this behavior. With the current implementation the code guarantees that the ticker irq will fire at or after the tick specified. Firing early would break this guarantee and make it harder to ensure correct handling in the common ticker layer.
The primary purpose of this change is to prevent blocking when set_interrupt is called back-to-back, regardless of the value being set. Calling set interrupt to fire 1 second in the future and then calling it again immediately to fire 2 seconds in the future causes blocking without this change. Minar like requirements is also added as a side effect - In addition to the code to prevent blocking, this patch also ensure that lp_ticker_set_interrupt isn't called with an alarm time sooner than LOWPOWERTIMER_DELAY_TICKS. This is done because the value LOWPOWERTIMER_DELAY_TICKS implies that it takes that amount of time for the value to take effect - If you set it to a value less than this it may cause the event to trigger on the next rollover rather than in a few clock cycles. If these values aren't intrinsically coupled (which they may be), it may be best to separate out these two concepts so they aren't conflated:
What do you think @0xc0170, @kjbracey-arm, @LMESTM, @jeromecoutant, @pan-? |
/morph build |
Build : SUCCESSBuild number : 1669 Triggering tests/morph test |
Test : FAILUREBuild number : 1463 |
Exporter Build : SUCCESSBuild number : 1302 |
LGTM, so delay low power ticks stays as it is in this PR |
/morph test |
Test : SUCCESSBuild number : 1472 |
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.
LGTM, just a few clarification questions.
hal/mbed_lp_ticker_wrapper.cpp
Outdated
*/ | ||
#include "hal/lp_ticker_api.h" | ||
|
||
#if DEVICE_LOWPOWERTIMER && defined(LOWPOWERTIMER_DELAY_TICKS) && (LOWPOWERTIMER_DELAY_TICKS > 0) |
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.
Is there a reason why DEVICE_LOWPOWERTIMER
isn't wrapped with a defined
?
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 not hurt but by default values not set defaults to 0.
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.
Conversely there's no need for the defined(LOWPOWERTIME_DELAY_TICKS)
- if it's not defined, the #if
will treat it as 0.
hal/mbed_lp_ticker_wrapper.cpp
Outdated
next = timestamp; | ||
last_request = current; | ||
if (!timeout_pending) { | ||
timeout->attach_us(set_interrupt_later, reschedule_us); |
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 take it that this doesn't need to be unattached once the timeout elapses?
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.
Not needed. Detach only if you want to remove it early
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.
Holding off on merge until a second person OK's the PR.
I did not get full details for the issue in #6522. But to me it seems related (please review). Realtek has a ticker (in this case high freq) also that takes some time to set interrupt. cc @M-ichae-l |
Some low power tickers take multiple cycles of the low power clock to set a compare value. Because of this if the compare value is set twice back-to-back these implementations will block until that time has passed. This can cause system stability issues since interrupts are disabling for this time. To gracefully support this kind of hardware this patch adds code to prevent back-to-back writes to the hardware. It does this by recording the low power clock cycle of the initial write. If any writes come in too soon after this initial write the microsecond ticker is used to schedule the new write in the future when the hardware is ready to accept a new value. To enable this feature on a target the macro LOWPOWERTIMER_DELAY_TICKS must be set to the number of low power clock cycles that must elapse between writes to the low power timer.
933fd07
to
17892cb
Compare
I pulled the fix 436f1d1 into this PR. |
/morph build |
Build : SUCCESSBuild number : 1767 Triggering tests/morph test |
Exporter Build : FAILUREBuild number : 1404 |
@studavekar Please review the java exception, the job took too long? /morph export-build |
Waiting for the @kjbracey-arm @bulislaw review |
Test : SUCCESSBuild number : 1576 |
Exporter Build : SUCCESSBuild number : 1412 |
@bulislaw Any comments? |
Some low power tickers take multiple cycles of the low power clock to set a compare value. Because of this if the compare value is set twice back-to-back these implementations will block until that time has passed. This can cause system stability issues since interrupts are disabling for this time.
To gracefully support this kind of hardware this patch adds code to prevent back-to-back writes to the hardware. It does this by recording the low power clock cycle of the initial write. If any writes come in too soon after this initial write the microsecond ticker is used to schedule the new write in the future when the hardware is ready to accept a new value.
To enable this feature on a target the macro
LOWPOWERTIMER_DELAY_TICKS
must be set to the number of low power clock cycles that must elapse between writes to the low power timer.[X] Feature