cancel
Showing results for 
Search instead for 
Did you mean: 

Hello everyone. Why the function HAL_GetTick() does not disable interrupts before accessing uwTick? What happens if SysTick interrupt occurs while reading uwTick?

Nikolay A. Neudobnoff
Associate II
 
1 ACCEPTED SOLUTION

Accepted Solutions

The 32-bit read should be atomic, the read/write multiples typically aren't, I don't know with 100% certainty the action of LDRD/STRD, this could however be guarded with a double read.

Seems not if you reuse the register you're using as an address...

http://www.keil.com/support/docs/3442.htm

Although I kind of think it restarts completely (do over), so if the Systick preempts everything and is the only thing writing the incremented pair, it would be very hard (tends to impossible) for a foreground task to get a miss-matched pair.

I wouldn't use LDRD/STRD on a hardware FIFO, looks to be a definite hazard there.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

7 REPLIES 7

What if it does increment? The granularity here is 1ms, next time you read the value it will have incremented. Not sure I understand where you think the harm/damage would occur.

You only need protection if you have two functions reading-and-writing the value in two different threads of execution. The SysTick interrupt can't reenter itself based on priority/preemption, only tail-chain (run a second time, back-to-back)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Danish1
Lead II

Maybe Nickolay is carrying over experience from 8-bit microcontrollers, and doesn't realise that a read of a 32-bit value on an arm platform happens all at once. There's no possibility of the value being incremented part-way through a read.

Nikolay A. Neudobnoff
Associate II

User 6.xx and Danish, thank you very much for your replies. Yes, I think exactly about possible corruption of the variable to which uwTick is reading. I am very new in ARM (all my previous experience is about PIC and MSP430). So, I got some further questions: Is reading of uwTick a real atomic operation which cannot be interrupted? What is happens if I due to some reasons change uwTick from uint32_t to uint64_t? Must I do interrupts disabling in this case?

>What is happens if I due to some reasons change uwTick from uint32_t to uint64_t? 

Then, get an AARCH64 chip.

-- pa

Or use multiple reads of the 64-bit value to detect and avoid the rollover. Pseudo code like this:

uint64_t HAL_GetTick64( void )
{
  uint64_t first = uwTick; // Presumes uwTick is now 64 bits
  uint64_t second = uwTick;
 
  if ( upper32bits_of_second != upper32bits_of_first ) {
    // Got rollover from lower 32 bits to upper 32 bits.
    // Read again to get guaranteed valid 64 bit value.
    // At 1ms tick rate, cannot get another 32-bit rollover for 49 days
    first = uwTick;
  }
 
  return( first );
}

The 32-bit read should be atomic, the read/write multiples typically aren't, I don't know with 100% certainty the action of LDRD/STRD, this could however be guarded with a double read.

Seems not if you reuse the register you're using as an address...

http://www.keil.com/support/docs/3442.htm

Although I kind of think it restarts completely (do over), so if the Systick preempts everything and is the only thing writing the incremented pair, it would be very hard (tends to impossible) for a foreground task to get a miss-matched pair.

I wouldn't use LDRD/STRD on a hardware FIFO, looks to be a definite hazard there.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Nikolay A. Neudobnoff
Associate II

Thanks to all for very polite and detailed explanations. Will use double read.