2017-08-10 11:36 PM
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 #interrupts2017-08-11 02:12 AM
How do you measure it?
JW
2017-08-11 02:21 AM
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.
2017-08-11 04:27 AM
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.
2017-08-11 05:34 AM
Need more details.
JW
2017-08-11 06:15 AM
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.
2017-08-11 08:19 AM
Guess how many cycles elapse between these two reads to
DWT->CYCCNT...:
uint32_t inteval = DWT->CYCCNT - count;
count = DWT->CYCCNT;
:-)
JW
2017-08-15 05:51 AM
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 theSysTick->LOAD. For me it's the 167999 as well.
2017-08-15 08:00 AM
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.
2017-08-15 08:53 AM
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