This discussion has piqued my curiosity regarding time-read reliability and the desire for time to always 'move forward'. I added this check:
| _rtc_get_time( &rtc_time ); |
| if( (rtc_time.SECONDS < rtc_time_last.SECONDS) |
| | || ((rtc_time.SECONDS == rtc_time_last.SECONDS) && (rtc_time.MICROSECONDS < rtc_time_last.MICROSECONDS)) ) |
| { |
| | Os_LogDebug(OS_LOG_DEBUG_ERROR, "Time slip. Old:%X.%X, New:%X.%X\n", |
| | rtc_time_last.SECONDS,rtc_time_last.MICROSECONDS,rtc_time.SECONDS,rtc_time.MICROSECONDS); |
| } |
| rtc_time_last.MICROSECONDS = rtc_time.MICROSECONDS; |
| rtc_time_last.SECONDS = rtc_time.SECONDS; |
in my 'idle' loop [most of the time], so about 175,000 checks per second. WITHOUT the protections of the above _rtc_get_time dual-reads and rollover-check, I got about 5 per second of these timestamped [HH:MM:SS.ms] prints showing TPR reads of 'inconsistent' contents due to increment-ripple-in-progress:
[09:12:33.653] ERR: Time slip. Old:56309181.9F9D2, New:56309181.9F808
[09:12:33.736] ERR: Time slip. Old:56309181.B3D1E, New:56309181.B3C48
Turning back 'on' the dual-reads-check knocked them out, but left a few of these at 'TPR rollover' from 999,969us to zero:
[09:15:24.000] ERR: Time slip. Old:5630922B.F4221, New:5630922B.0
[09:15:26.000] ERR: Time slip. Old:5630922D.F4221, New:5630922D.0
When I re-enabled that rollover protection but at '<50us', I got one in 15minutes:
[09:33:27.000] ERR: Time slip. Old:56309666.F4221, New:56309666.3D
This indicates that one(or more) 'interrupt(s)' between the TSR reads and the TPR reads took LONG ENOUGH to make the <50us check 'fail' to protect from seconds rollover: In this case TPR went from '-31us' to '+61us' AFTER we had already read TSR. At the original '<100us' (as above) for the 'rollover time check' I don't expect I would have ever seen a fault, but THAT depends entirely on one's worst interrupt processing interval! Mine is 70us.
I suggest that the entire _rtc_get_time routine should be run with interrupts disabled! The routine only takes 1 to 1.5us at 100MHz. Adding DisableInterrupts and EnableInterrupts around it, I've gotten NO fault in 6 hours!