Merge pull request #13867 from marcemmers/fix-systimer-overflow

SysTimer: Prevent unacknowledged tick overflow when halted for a while
pull/13904/head
Martin Kojtal 2020-11-11 08:55:24 +00:00 committed by GitHub
commit 3555ada459
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 6 deletions

View File

@ -191,7 +191,7 @@ public:
*/ */
std::chrono::duration<int, period> unacknowledged_ticks() const std::chrono::duration<int, period> unacknowledged_ticks() const
{ {
return std::chrono::duration<int, period>(core_util_atomic_load_u8(&_unacknowledged_ticks)); return std::chrono::duration<int, period>(core_util_atomic_load_u32(&_unacknowledged_ticks));
} }
/** Get the current tick count /** Get the current tick count
@ -248,7 +248,7 @@ protected:
const highres_time_point _epoch; const highres_time_point _epoch;
highres_time_point _time; highres_time_point _time;
uint64_t _tick; uint64_t _tick;
uint8_t _unacknowledged_ticks; uint32_t _unacknowledged_ticks;
bool _wake_time_set; bool _wake_time_set;
bool _wake_time_passed; bool _wake_time_passed;
bool _wake_early; bool _wake_early;

View File

@ -191,10 +191,15 @@ void SysTimer<Period, IRQ>::acknowledge_tick()
{ {
// Try to avoid missed ticks if OS's IRQ level is not keeping // Try to avoid missed ticks if OS's IRQ level is not keeping
// up with our handler. // up with our handler.
// 8-bit counter to save space, and also make sure it we don't // This value should not get large during normal operation.
// try TOO hard to resync if something goes really awry - // However, when interrupts are not handled for a while
// resync will reset if the count hits 256. // (e.g. by debug halt or large critical sections) this
if (core_util_atomic_decr_u8(&_unacknowledged_ticks, 1) > 0) { // number will get large very quickly. All these un-
// acknowledged ticks need to be processed because otherwise
// the OS timing will be off. Processing may take a while.
// For more info see: https://github.com/ARMmbed/mbed-os/issues/13801
if (core_util_atomic_decr_u32(&_unacknowledged_ticks, 1) > 0) {
_set_irq_pending(); _set_irq_pending();
} }
} }