-
Notifications
You must be signed in to change notification settings - Fork 3k
[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
Conversation
…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.
191d0a9
to
c6ef2f3
Compare
@nvlsianpu Could you also look at #4026 ? |
/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) | ||
{ |
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.
nit: code style
if (cond) {
} else {
}
while (1) {
}
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 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; | ||
} |
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'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) |
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.
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;
}
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.
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
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
@nvlsianpu What do you think? |
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); |
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.
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; |
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.
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) |
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.
Did you mean rtc_ovf_event_check?
- extarct for check rtc overflow - make common_rtc_32bit_ticks_get safe against preemption.
8de8a60
to
4f99aa5
Compare
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? |
Yes I checked. It pass this as well. |
@pan- review please |
@0xc0170 what happened on continuous-integration/jenkins/pr-head? |
@0xc0170 LGTM |
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. |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
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
Description
bug:
If rtc overflow occur while setting of timestamp then the compare event ocurr (erroneously) in 512s.
This cause #3857 issue.
changes:
Status
READY