cancel
Showing results for 
Search instead for 
Did you mean: 

Why is the SysTick timer off by a few clock cycles?

Jurrien de Klerk
Associate II
Posted on August 11, 2017 at 08:36

Hello all,

Sometime ago I was looking into configuring the SysTick timer for an stm32f407 mcu. As the CMSIS lib provides a function for this, this is kind of straight forward. To verify the configuration I measured the clock cycle count.  When I was looking whether I configured the timer correctly, I discovered something I don't understand; the count between SysTick interrupts was slightly less then expected. I configured the SysTick to hit every 1 ms with a system clock of a 168 MHz, so I would expect that the interrupt would hit every 168000 clock ticks. However, I measure 167996.

Does anyone has an idea why this is?

Best regards,

Jurrien

#systick-config #interrupts
16 REPLIES 16
Posted on August 11, 2017 at 11:12

How do you measure it?

JW

Jurrien de Klerk
Associate II
Posted on August 11, 2017 at 11:21

Thanks for the reply waclawek.jan. First I measured it using a trace tool in my IDE (TrueSTUDIO), but during my experiment I started to suspect that the deviation measured might be in the tool. Therefore, I changed to the clock cycle count register in the debug peripheral (DWT->CYCCNT), this gave me the same result.

Jurrien de Klerk
Associate II
Posted on August 11, 2017 at 13:27

The systick handler is as follow:

extern 'C' void SysTick_Handler(void)
{
 static uint32_t count = DWT->CYCCNT;
 uint32_t interval = DWT->CYCCNT - count;
 count = DWT->CYCCNT;
 if(interval) {
 // useless, but should prevent the compiler from optimizing interval away
 }
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

and the SysTick_Config call looks like:

// SystemCoreClock equals 168000000
if(SysTick_Config(SystemCoreClock / 1000)) {
 // Error ...
 return;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

And finally the main loop is just a while(1) {} loop. I just rechecked the values of the experiment, and now they oscillate around

167980, but they are always below the 168000. I compiled this with the lowest optimization level (-O0), it should not matter expect that some values might be optimized out. To see the values I have a breakpoint on line 6 of the first code fragment.

Please let me know if I forgot an important detail.

Posted on August 11, 2017 at 12:34

Need more details.

JW

Brian TIDAL
ST Employee
Posted on August 11, 2017 at 15:15

Hi,

can you check the SysTick Reload value (SysTick->LOAD) and SystemCoreClock value? The reload value is derived from SystemCoreClock value: reload = ((SystemCoreClock / 1000) -1)

On my side, on STM32F429I-DISC1 discovery board with HCLK=168MHz (*), SystemCoreClock=168000000 and SysTick->LOAD=167999.

(*) Clock config: HSE=8MHz, PLL source=HSE, PLL_M=4 N=168 P=2.

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Posted on August 11, 2017 at 15:19

Guess how many cycles elapse between these two reads to

DWT->CYCCNT...:
uint32_t inteval = DWT->CYCCNT - count;
 count = DWT->CYCCNT;

:-) JW
Jurrien de Klerk
Associate II
Posted on August 15, 2017 at 14:51

Thanks for your response, its much appreciated :-).

Waclawek.Jan

‌ . Unfortunately my life isn't so easy. I performed the test with several different clock frequency settings and different SysTick timer intervals, all resulted in different deviations. Also, the deviation depends on whether the mcu is active or not.

TISSERAND.Bruno

‌ I checked the

SysTick->LOAD. For me it's the 167999 as well.

Jurrien de Klerk
Associate II
Posted on August 15, 2017 at 17:00

Jan,

I have to admit, I did not look up the actual clock count for the load- and subtract instruction, but let assume (for a worst case calculation) the instructions take 3 cycles. (I suspect that the subtract will only be on cycle and the load instruction 2, but this would only make it worst). We have 1 instruction for reading count, 1 for DWT->CYCCNT and one for subtracting. So we execute 3 instruction, times 3 cycles is smaller then 20 cycles (168000 -

167980 = 20)

. But maybe more importantly, the amount of cycles should be constant right? And it isn't.

I realize now that giving the code snippet was a bad idea. I encountered the problem some weeks ago. Back then, I had a program doing nothing expect for executing the SysTick irq. I measured the cycle count using an build in tool of Atollic's TrueSTUDIO, the SWV Exception Trace Log. I was surprised by the result so I tried several different configuration by changing the clock frequency and SysTick interval. Still using the SWV Exception Trace Log I measured different deviation depending on the configuration.

At first, I thought that this issue might be related to the measurement tool, so I had a discussion with the support for TrueSTUDIO. After a while we figured that, using the DWT->CYCCNT, we could show that this problem is not in the measurement tool. And so I ended on this forum.

Posted on August 15, 2017 at 15:53

Jurrien,

don't forget that

DWT->CYCCNT

is ticking continuously, all the time the program is executing. Imagine it's a real clock.

In the above snippet, you first read

DWT->CYCCNT

to calculate the time difference. Say, it's 16:

The you read it again to start measuring the time between two interrupts. But it took time to calculate the time difference, so say you read in 16:

Then the next interrupt chimes in and you read

DWT->CYCCNT

to calculate the time difference. Say, it's 17:

What is the span between two interrupts in this example?

JW