mirror of https://github.com/ARMmbed/mbed-os.git
Correct SysTimer absolute time calculations
`SysTimer::set_wake_time` incorrectly assumed that the `SysTimer`s tick count and the underlying HAL timer had the same zero base. This normally holds, at least approximately, in RTOS builds where the HAL timer starts from zero at the same time the SysTimer is initialised. But in bare metal builds, the HAL timer could be started some time before the SysTimer, giving a significant discrepancy. Beyond that, there's no requirement for HAL timers to start from zero in the spec. Record the HAL timer start time to get the conversion right.pull/12326/head
parent
ee1d998d43
commit
de915a034b
|
@ -52,7 +52,8 @@ SysTimer<US_IN_TICK, IRQ>::SysTimer() :
|
||||||
#else
|
#else
|
||||||
TimerEvent(get_us_ticker_data()),
|
TimerEvent(get_us_ticker_data()),
|
||||||
#endif
|
#endif
|
||||||
_time_us(ticker_read_us(_ticker_data)),
|
_epoch(ticker_read_us(_ticker_data)),
|
||||||
|
_time_us(_epoch),
|
||||||
_tick(0),
|
_tick(0),
|
||||||
_unacknowledged_ticks(0),
|
_unacknowledged_ticks(0),
|
||||||
_wake_time_set(false),
|
_wake_time_set(false),
|
||||||
|
@ -66,7 +67,8 @@ SysTimer<US_IN_TICK, IRQ>::SysTimer() :
|
||||||
template<uint32_t US_IN_TICK, bool IRQ>
|
template<uint32_t US_IN_TICK, bool IRQ>
|
||||||
SysTimer<US_IN_TICK, IRQ>::SysTimer(const ticker_data_t *data) :
|
SysTimer<US_IN_TICK, IRQ>::SysTimer(const ticker_data_t *data) :
|
||||||
TimerEvent(data),
|
TimerEvent(data),
|
||||||
_time_us(ticker_read_us(_ticker_data)),
|
_epoch(ticker_read_us(_ticker_data)),
|
||||||
|
_time_us(_epoch),
|
||||||
_tick(0),
|
_tick(0),
|
||||||
_unacknowledged_ticks(0),
|
_unacknowledged_ticks(0),
|
||||||
_wake_time_set(false),
|
_wake_time_set(false),
|
||||||
|
@ -104,7 +106,7 @@ void SysTimer<US_IN_TICK, IRQ>::set_wake_time(uint64_t at)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ticks_to_sleep = at - _tick;
|
uint64_t ticks_to_sleep = at - _tick;
|
||||||
uint64_t wake_time = at * US_IN_TICK;
|
uint64_t wake_time = _epoch + at * US_IN_TICK;
|
||||||
|
|
||||||
/* Set this first, before attaching the interrupt that can unset it */
|
/* Set this first, before attaching the interrupt that can unset it */
|
||||||
_wake_time_set = true;
|
_wake_time_set = true;
|
||||||
|
|
|
@ -225,6 +225,7 @@ protected:
|
||||||
uint64_t _elapsed_ticks() const;
|
uint64_t _elapsed_ticks() const;
|
||||||
static void _set_irq_pending();
|
static void _set_irq_pending();
|
||||||
static void _clear_irq_pending();
|
static void _clear_irq_pending();
|
||||||
|
const us_timestamp_t _epoch;
|
||||||
us_timestamp_t _time_us;
|
us_timestamp_t _time_us;
|
||||||
uint64_t _tick;
|
uint64_t _tick;
|
||||||
uint8_t _unacknowledged_ticks;
|
uint8_t _unacknowledged_ticks;
|
||||||
|
|
Loading…
Reference in New Issue