mirror of https://github.com/ARMmbed/mbed-os.git
shortened the comment in us_ticker_set_interrupt().
parent
be71348f20
commit
ea4537df7d
|
@ -202,42 +202,30 @@ void us_ticker_set_interrupt(timestamp_t timestamp)
|
|||
}
|
||||
|
||||
/*
|
||||
* Alert: Get yourself a beverage.
|
||||
*
|
||||
* In comes a harmless, merry-looking 32-bit timestamp in units of micro-
|
||||
* seconds from the generic us_ticker_api. On most platforms with 32-bit
|
||||
* hardware timers running at micro-second precision this poses no serious
|
||||
* challenge. But on the nRF51, we use an RTC timer running at 32kHz to
|
||||
* implement a low-power us-ticker. This brings with a problem that's rooted
|
||||
* in the fact that 1000000 is not a multiple of 32768.
|
||||
* The argument to this function is a 32-bit microsecond timestamp for when
|
||||
* a callback should be invoked. On the nRF51, we use an RTC timer running
|
||||
* at 32kHz to implement a low-power us-ticker. This brings with a problem
|
||||
* that's rooted in the fact that 1000000 is not a multiple of 32768.
|
||||
*
|
||||
* Going from a micro-second based timestamp to a 32kHz based RTC-time is a
|
||||
* linear mapping; but then when the 32-bit micro-second timestamp wraps
|
||||
* around, unfortunately the underlying RTC counter doesn't. The result is
|
||||
* that timestamp expiry checks on micro-second timestamps don't yield the
|
||||
* same result when applied on the corresponding RTC timestamp values.
|
||||
* You'll really need to whip up some numbers to see the problem.
|
||||
* linear mapping; but this mapping doesn't preserve wraparounds--i.e. when
|
||||
* the 32-bit micro-second timestamp wraps around unfortunately the
|
||||
* underlying RTC counter doesn't. The result is that timestamp expiry
|
||||
* checks on micro-second timestamps don't yield the same result when
|
||||
* applied on the corresponding RTC timestamp values.
|
||||
*
|
||||
* As far as I understand--and this could just be me turning old and rusty,
|
||||
* --there is no clean solution for this problem at the wrap-around
|
||||
* boundary. I'd be interested to be shown how. My solution is to translate
|
||||
* the incoming 32-bit timestamp into a virtual 64-bit timestamp based on
|
||||
* the knowledge of system-uptime, and then use this 64-bit value to do a
|
||||
* linear mapping to RTC time. 64-bit timestamp values shouldn't wrap around
|
||||
* in a few thousand years. This may be pulling down the theoretical upper
|
||||
* boundary for the shelf life of nRF products when used with mbed; please
|
||||
* accept my two to the power 56 apologies for that. But then life often
|
||||
* forces one to live within constraints. What's the meaning of all this
|
||||
* anyway?
|
||||
*
|
||||
* System uptime on an nRF is maintained using RTC's counter. We track the
|
||||
* overflow count to extend the 24-bit hardware counter by an additional 32
|
||||
* bits. This then forms the basis for system time.
|
||||
* One solution is to translate the incoming 32-bit timestamp into a virtual
|
||||
* 64-bit timestamp based on the knowledge of system-uptime, and then use
|
||||
* this wraparound-free 64-bit value to do a linear mapping to RTC time.
|
||||
* System uptime on an nRF is maintained using the 24-bit RTC counter. We
|
||||
* track the overflow count to extend the 24-bit hardware counter by an
|
||||
* additional 32 bits. This then forms the basis for system time.
|
||||
* RTC_UNITS_TO_MICROSECONDS() converts this into microsecond units (in
|
||||
* 64-bits). We then shave off the lower 32-bits of it and add in the
|
||||
* incoming timestamp to get a mapping into a virtual 64-bit timestamp.
|
||||
* There's one additional check to handle the case of wraparound for the
|
||||
* 32-bit timestamp.
|
||||
* There's one additional check to handle the case where the 32-bit callback
|
||||
* timestamp is wrapped around--i.e. where the current time is near
|
||||
* 0xFFFFFFFF, but incoming timestamp is near 0x00000000.
|
||||
*/
|
||||
uint64_t timestamp64 = (RTC_UNITS_TO_MICROSECONDS(rtc1_getCounter()) & ~(uint64_t)0xFFFFFFFF) + timestamp;
|
||||
if ((us_ticker_read() > 0xF0000000) && (timestamp < 0x10000000)) {
|
||||
|
|
Loading…
Reference in New Issue