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

Add LPTICKER tests #8129

Closed
wants to merge 1 commit into from
Closed

Conversation

c1728p9
Copy link
Contributor

@c1728p9 c1728p9 commented Sep 14, 2018

Description

When both tickless and LPTICKER_DELAY_TICKS are enabled some ST devices randomly get stuck sleeping forever. This is because the wake up time passed to the rtc is ignored if the previous match is about to occur. This causes the device to get stuck in sleep.

This patch #8242 prevents matches from getting dropped by the rtc by deactivating the rtc wake up timer before setting a new value.

This patch also makes a related fix for the lp ticker to prevent a spurious interrupt. Note - the lp ticker implementation does correctly set the second match interrupt so it did not have problems with LowPowerTickerWrappper/LPTICKER_DELAY_TICKS.

Events leading up to this failure for the RTC:

  • 1st call to lp_ticker_set_interrupt
  • delay until ticker interrupt is about to fire
  • 2nd call to lp_ticker_set_interrupt
  • interrupt for 1st call fires and match time for 2nd call is dropped
    -LowPowerTickerWrapper gets ticker interrupt but treats it as a
    spurious interrupt and drops it since it comes in too early
  • device enters sleep without a wakeup source and locks up

This PR also adds tests to catch this regression in the future.

Pull request type

[x] Fix
[ ] Refactor
[ ] Target update
[ ] Functionality change
[ ] Breaking change

@@ -389,6 +389,7 @@ void rtc_set_wake_up_timer(timestamp_t timestamp)
}

RtcHandle.Instance = RTC;
HAL_RTCEx_DeactivateWakeUpTimer(&RtcHandle);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this really needed as rtc_deactivate_wake_up_timer function was already called in lp_ticker_set_interrupt before calling rtc_set_wake_up_timer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, rtc_deactivate_wake_up_timer by itself is not sufficient. If HAL_RTCEx_DeactivateWakeUpTimer is removed then this test will fail.

@@ -203,6 +203,10 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
__HAL_LPTIM_CLEAR_FLAG(&LptimHandle, LPTIM_FLAG_CMPM);
__HAL_LPTIM_COMPARE_SET(&LptimHandle, timestamp);

while (__HAL_LPTIM_GET_FLAG(&LptimHandle, LPTIM_FLAG_CMPOK) == RESET) {
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain what is being done here ? Isn't there a risk to spend "a lot" of time in this while loop ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this would cause blocking behavior in a critical section which is problematic. Without this delay the call to lp_ticker_clear_interrupt doesn't actually stop a spurious ticker interrupt from firing. Is it possible to prevent a spurious interrupt here without blocking? If so could you share the sequence so I could incorporate it into this PR?

Alternatively, if a fix cannot be found, I could modify the test to ignore spurious interrupts when LPTICKER_DELAY_TICKS > 0. The LowPowerTickerWrapper layer filters out spurious interrupts so when enabled these will not propagate to higher layers. What are you thoughts on this @LMESTM?

Copy link
Contributor

@mprse mprse left a comment

Choose a reason for hiding this comment

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

Test header and HAL lp ticker header (defined behavior, test functions) should be updated and additional test cases should be documented.


const uint32_t mask = (1 << lp_ticker_get_info()->bits) - 1;

for (uint32_t i = 0; i < 100-0; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe that 100-0 should be 100.

Update the low power ticker test to verify that the low power ticker
does not fire too early. Also add a test to verify that the low power
ticker can be safely rescheduled right before or after a match
occurs.
@c1728p9
Copy link
Contributor Author

c1728p9 commented Sep 17, 2018

Hi @mprse I updated the PR to address your comment and add test function declarations.

The defined behavior that was being violated is already specified:

* * The ticker interrupt fires only when the ticker times increments to or past the value set by ticker_set_interrupt.
* Verified by ::ticker_interrupt_test and ::ticker_past_test

Both ST implementations of the low power ticker violate this (At least on the STM32L432):

  • RTC implementation (lpticker_lptim=0) - sometimes firing early and causing a lockup
  • lpticker implementation (lpticker_lptim=1) - always fires an interrupt at the time specified, but sometimes also fires a spurious interrupt early. This does not cause a lockup.

Copy link
Contributor

@mprse mprse left a comment

Choose a reason for hiding this comment

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

@c1728p9 Thanks for updating test header file and potential bugs section.

Tests looks good only one minor issue mentioned earlier (100-0) is to be fixed.

@0xc0170
Copy link
Contributor

0xc0170 commented Sep 18, 2018

@LMESTM @jeromecoutant Please review

Copy link
Contributor

@mprse mprse left a comment

Choose a reason for hiding this comment

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

Tests looks good!

@c1728p9
Copy link
Contributor Author

c1728p9 commented Sep 19, 2018

Marking this as "do not merge" until the blocking of the LP ticker is addressed.

@jeromecoutant
Copy link
Collaborator

Hi Russ

I propose:

@c1728p9 c1728p9 changed the title Fix tickless and LPTICKER_DELAY_TICKS on ST devices Add LPTICKER tests Sep 25, 2018
@c1728p9
Copy link
Contributor Author

c1728p9 commented Sep 25, 2018

Hi @jeromecoutant I descoped this PR to just the tests as you suggested.

@jeromecoutant
Copy link
Collaborator

@0xc0170 #8242 is merged, you can start CI for this one
Thx

@0xc0170
Copy link
Contributor

0xc0170 commented Oct 8, 2018

@0xc0170 #8242 is merged, you can start CI for this one

Thanks, I'll review shortly

@cmonr
Copy link
Contributor

cmonr commented Oct 10, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Oct 10, 2018

Build : SUCCESS

Build number : 3310
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/8129/

Triggering tests

/morph test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented Oct 10, 2018

@mbed-ci
Copy link

mbed-ci commented Oct 10, 2018

@0xc0170
Copy link
Contributor

0xc0170 commented Oct 10, 2018

Failures related to the new test case, please review

@0xc0170
Copy link
Contributor

0xc0170 commented Oct 23, 2018

Please review the test failures or this can be closed until it's updated

@cmonr
Copy link
Contributor

cmonr commented Oct 29, 2018

Closing this since progress appears to have idled.

Feel free to repoen once updates are availaible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants