I want to implement a timestamp functionality for my msp430-based platform.
My aim is to use a hardware timer, and count the number of times it overflows, to generate a long timestamp value (typically an uint32 for overflow counter, combined with the uint16 value of the hardware timer).
This is what I have:
- The overflow counter is incremented on interrupt,
- its value is checked every time a timestamp is requested (this is protected by interrupt locks).
- the overflow counter value is combined with the current hardware timer value to a large timestamp.
I run into problems when I take into consideration the timing of interrupts.
The first naive implementation I had:
uint16_t timer_value = timer_value_get();
__istate_t istate = interrupt_disable();
uint64_t overflow_count_local = overflow_count; // the volatile incremented on interrupt
interrupt_restore(istate);
return (overflow_count_local << 16u) + timer_value;
This is going to fail when an overflow occurs after getting the timer value, but before the interrupts are disabled. overflow_count_local
would then be 1 greater than what it was upon assigning timer_value
.
I have tried to add other checks to detect this possible interrupt
uint16_t timer_value = timer_value_get();
__istate_t istate = interrupt_disable();
uint16_t second_timer_value = timer_value_get();
uint64_t overflow_count_local = overflow_count; // the volatile incremented on interrupt
interrupt_restore(istate);
if (second_timer_value < timer_value) {
// A HW timer overflow occured just before disabling interrupts.
overflow_count_local--;
}
return (overflow_count_local << 16u) + timer_value;
This is not either going to work, this time because the timer might have overflown after disabling the interrupts, but before assigning second_timer_value
. This would then make overflow_count_local
one too little.
However I try to turn this around, there seems to always be a case which is not covered. Is there a known way to make this work?
Some limitations:
- The timer is used for other functionality as well (with capture/compare) and may not be stopped.
- The msp430's RTC module may not be used to that effect, because it is used to keep the actual time of the day.
- No 32 bit timer is available.