Skip to content

[NRF5]: fix rtc overflow-while-set-timestamp issue #4016

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

Merged
merged 2 commits into from
Apr 20, 2017

Conversation

nvlsianpu
Copy link
Contributor

@nvlsianpu nvlsianpu commented Mar 24, 2017

Description

bug:
If rtc overflow occur while setting of timestamp then the compare event ocurr (erroneously) in 512s.
This cause #3857 issue.

changes:

  • move rtc ovf handler at the beginning of rtc handler for mitigate the case (mitigate issue for execution from rtc handler)
  • add repeating of operation of set a timestamp in case that rtc overflow occurred during the operation.

Status

READY

@nvlsianpu nvlsianpu mentioned this pull request Mar 24, 2017
…mpara-event ocurre (erroneusly) in 512s.

- move ovf handler at the begining of rtc handler for mitigate the case (mitigate issue for exexution from rtc handler)
- add repeating of operation of set a timestamp in cas that rtc overflow occured during the operation.
@nvlsianpu nvlsianpu force-pushed the nrf5_rtc_ovf_bugfix branch from 191d0a9 to c6ef2f3 Compare March 24, 2017 14:01
@nvlsianpu
Copy link
Contributor Author

@anangl I need your review. cc: @pan-

@nvlsianpu
Copy link
Contributor Author

For curious images:
general bug behaviour:
Imgur
time window of the bug, one tick of RTC timer last ~30 us:
Imgur

@pan-
Copy link
Member

pan- commented Mar 27, 2017

@nvlsianpu Could you also look at #4026 ?

@bridadan
Copy link
Contributor

/morph test-nightly


// check in case of preemption by RTC OVF event (apply if call was from a low priority level)
if (prev_overflows != m_common_rtc_overflows)
{
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: code style


if (cond) {

} else {

}

while (1) {

}

@0xc0170 0xc0170 requested a review from pan- March 29, 2017 10:15
Copy link
Member

@pan- pan- left a comment

Choose a reason for hiding this comment

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

The changes indicated in #4026 (comment) have to be included in this PR.

// Don't disable this event. It shall occur periodically.

++m_common_rtc_overflows;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd extract the above block to some static function, e.g. check_overflow, since the same code needs to be executed in two places.

{
uint32_t prev_overflows;

while (1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Such a loop should not be placed here, but in common_rtc_32bit_ticks_get(), since this problematic gluing of hardware ticks with software counted overflows can be called from other places as well; currently it is called from us_ticker_read() and lp_ticker_read().
I'd propose to put it like this (not tested):

uint32_t common_rtc_32bit_ticks_get(void)
{
    uint32_t ticks;
    uint32_t prev_overflows;
    do {
        prev_overflows = m_common_rtc_overflows;

        ticks = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
        // The counter used for time measurements is less than 32 bit wide,
        // so its value is complemented with the number of registered overflows
        // of the counter.
        ticks += (m_common_rtc_overflows << RTC_COUNTER_BITS);

        int was_masked = __sd_nvic_irq_disable();
        check_overflow();
        if (!was_masked) {
            __sd_nvic_irq_enable();
        }
    } while (m_common_rtc_overflows != prev_overflows);

    return ticks;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Anyway this won't fix overflow issue for setting a timieout. Overflow might occurs during executing of internal_common_rtc_set_interrupt for instance. But preserve time readout is problem as well, see #4026

@mbed-bot
Copy link

Result: SUCCESS

Your command has finished executing! Here's what you wrote!

/morph test-nightly

Output

mbed Build Number: 1776

All builds and test passed!

@0xc0170
Copy link
Contributor

0xc0170 commented Mar 29, 2017

The changes indicated in #4026 (comment) have to be included in this PR.

@nvlsianpu What do you think?

@nvlsianpu
Copy link
Contributor Author

0xc0170 Sure - good idea.

break;
}
// check in case that OVF occurred during execution of a RTC handler (apply if call was from RTC handler)
} while (rtc_ovf_evet_check() != prev_overflows);
Copy link
Contributor

Choose a reason for hiding this comment

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

This loop is no longer needed, because now common_rtc_32bit_ticks_get() provides the protection.

if (nrf_rtc_event_pending(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) {
nrf_rtc_event_clear(COMMON_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW);
// Don't disable this event. It shall occur periodically.

++m_common_rtc_overflows;
}

return m_common_rtc_overflows;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bit ineffective. This variable is volatile, so it will be re-read every time, and the return value from the first call of this function is not used at all (see line 75). It would be better to not return anything here and read m_common_rtc_overflows when it is really needed (i.e. in line 182).

#else
void COMMON_RTC_IRQ_HANDLER(void)
#endif
__STATIC_INLINE uint32_t rtc_ovf_evet_check(void)
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you mean rtc_ovf_event_check?

- extarct for check rtc overflow
- make common_rtc_32bit_ticks_get safe against preemption.
@nvlsianpu nvlsianpu force-pushed the nrf5_rtc_ovf_bugfix branch from 8de8a60 to 4f99aa5 Compare April 3, 2017 14:10
@nvlsianpu
Copy link
Contributor Author

@pan- PR is updated to fix #4026. I verified that this PR resolves issues once more. @0xc0170 the Travis CI build has trouble with it-self.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 4, 2017

@0xc0170 the Travis CI build has trouble with it-self.

Restarted

cc @Sissors

@Sissors
Copy link
Contributor

Sissors commented Apr 4, 2017

Since the structure of this file is quite different from the NRF51822 one it is hard to say for me if I think it is solved. So @nvlsianpu , did you check with my test program if no errors occur?

@nvlsianpu
Copy link
Contributor Author

nvlsianpu commented Apr 4, 2017

@Sissors

did you check with my test program if no errors occur?

Yes I checked. It pass this as well.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 4, 2017

@pan- review please

@nvlsianpu
Copy link
Contributor Author

@0xc0170 what happened on continuous-integration/jenkins/pr-head?

@pan-
Copy link
Member

pan- commented Apr 5, 2017

@0xc0170 LGTM

@geky
Copy link
Contributor

geky commented Apr 5, 2017

There is an issue with the continuous-integration/jenkins/pr-head that is being progressed here.

In the meantime we can run this guy. The morph test runs all of the unit tests in the code base, so if morph passes it's unlikely that continuous-integration/jenkins/pr-head will fail.
/morph test

@mbed-bot
Copy link

mbed-bot commented Apr 6, 2017

Result: SUCCESS

Your command has finished executing! Here's what you wrote!

/morph test

Output

mbed Build Number: 1842

All builds and test passed!

@adbridge adbridge merged commit 78c4850 into ARMmbed:master Apr 20, 2017
aisair pushed a commit to aisair/mbed that referenced this pull request Apr 30, 2024
Ports for Upcoming Targets


Fixes and Changes

4008: [NUC472/M453] Support Bootloader and FlashIAP ARMmbed/mbed-os#4008
4102: Add SCL and SDA defs for I2C[0-2]; redefine I2C_[SCL,SDA] to I2C2 ARMmbed/mbed-os#4102
4118: STM32F4 Internal ADC channels rework ARMmbed/mbed-os#4118
4126: STM32F4 : remove SERIAL_TX and SERIAL_RX from available pins ARMmbed/mbed-os#4126
4148: Revert "STM32F4 Internal ADC channels rework" ARMmbed/mbed-os#4148
4152: STM32F4 Internal ADC channels rework ARMmbed/mbed-os#4152
4074: [Silicon Labs] Update pinout ARMmbed/mbed-os#4074
4133: U-BLOX_C030: Default XTAL is now 12MHz onboard. Option to use Debug 8MHz ARMmbed/mbed-os#4133
4142: EFM32: Fixed `pwmout_all_inactive` being inversed ARMmbed/mbed-os#4142
4016: [NRF5]: fix rtc overflow-while-set-timestamp issue ARMmbed/mbed-os#4016
4031: STM32 increase IAR heap size for big RAM targets ARMmbed/mbed-os#4031
4137: MCUXpresso: Update ARM linker files to eliminate reserving RAM for stack & heap ARMmbed/mbed-os#4137
4176: STM32L4 Internal ADC channels rework ARMmbed/mbed-os#4176
4154: STM32F7 Internal ADC channels rework ARMmbed/mbed-os#4154
4174: [NRF52840]:  fix rtc overflow-while-set-timestamp issue ARMmbed/mbed-os#4174
4180: [UBLOX_C030] create target hierarchy for the specific versions of the C030 board ARMmbed/mbed-os#4180
4153: STM32F2: Internal ADC channels rework ARMmbed/mbed-os#4153
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants