How reliably and safely detect hardware timer overflow causing logic error

5 hours ago 4
ARTICLE AD BOX

I'm trying to find a best-practice method to handle an edge case when a hardware clock timer wraps around and the overflown value generates a false positive logic match.

For example, on a 16 MHz chip, a 32-bit hardware timer overflows every ~72 minutes.

Eg, consider this code. The event type is immaterial, but for example let's just say it's set by some hardware interrupt in an Interrupt Service Routine (ISR) elsewhere.

volatile unsigned long eventTime; // 32-bit unsigned int microseconds void someISR(){ eventTime = micros(); } void loop(){ auto now = micros(); // 32-bit unsigned int microseconds // has event occurred in the last 1s? if (now - eventTime < 1000000){ // run some code that should only run when we are less than 1s after some event } }

Most of the time this logic test is correct. But consider the case when the event has not occurred for 72 minutes and now has wrapped fully around and just passes the event + 72min time. The code therefore generates a false logic match every 1s/71min = 0.02%.

How can we distinguish this case?

Possible solutions:

Promote the 32-bit timestamps to 64-bit. Practically this solves the problem but introduces slower 64-bit operations and technically doesn't solve the logic bug.

Set some overflow counter. Again, while it practically solves the issue it introduces complexity and technically doesn't solve the bug because the overflow counter will eventually overflow.

Handle the logic in the ISR. This causes other issues because other interrupts are deferred inside an ISR. In particular the interrupts that control micros() are deferred so that function will provide incorrect values during a long ISR.

Read Entire Article