Cortex-M4 SysTick initialization code: Why so? [Solved] - Page 1
Forum section: electronics / general

author: igendel
author_rank: Frequent Contributor
timestamp: June 11, 2017, 11:06:15 pm
content: Hi all, need your help in figuring out a little piece of code.I'm studying "The Definitive Guide to ARM Cortex-M3 and Cortex-M4 processors" (3rd Ed.) by Joseph Yiu - at this point merely reading, not actually programming... anyway, on page 317 there's a sample code for using SysTick to measure the run time of a function. First comment on each line is from the original text, second one is mine:Code:SysTick->CTRL = 0; // Disable SysTickSysTick->LOAD = 0xFFFFFFFF; // Set reload value to maximum // Although SysTick's 24-bit...SysTick->VAL = 0; // Clear current value to 0SysTick->CTRL = 0x5; // Enable SysTick, use processor clockwhile (SysTick->VAL != 0); // Wait until SysTick reloaded // ???start_time = SysTick->VAL; // Get start timefunction(); // Execute function to be measuredstop_time = SysTick->VAL; // Get stop timecycle_count = start_time - stop_time;Hope I got that right. My question is, shouldn't the while loop be like this?Code:while (SysTick->VAL == 0); // Wait until SysTick reloadedThat would make more sense vis-a-vis the comment, and the fact that we just cleared VAL, and the fact that we're measuring a delta so why wait for a zero...Thanks!P.S. I checked the online errata, nothing about this there.https://community.arm.com/processors/b/blog/posts/errors-in-the-definitive-guide-for-arm-cortex-m-book-series

author: ataradov
author_rank: Super Contributor
timestamp: June 12, 2017, 02:50:34 am
content: It looks like you are correct.Although I really don't see the point of waiting for a single shot measurement. You can just set VAL to 0xffffff before enabling the timer.Actually you can't since write of any values will just clear the counter, so you do need to wait until counter reloads.Although a better way is to have systick running all the time (as it would in a real application), and just do some math on values read at any point.

author: cv007
author_rank: Frequent Contributor
timestamp: June 12, 2017, 07:05:27 am
content: QuoteThis doesn't look like a great idea- who says the timing will be right so that a 0 will ever be read? The systick timer is running at processor speed when enabled in this example, and how many cycles does 'while (SysTick->VAL != 0);' take? What optimization setting is being used? Can it be possible that a 0 will never be read? I don't know, but I'm pretty sure waiting for a specific value on a running timer is not a great idea.I'm not sure why its necessary to wait for the rollover here- the timer register is cleared, so its at 0, enabling the timer will cause the rollover at the next cpu cycle (or next + 1- that's what debuggers are for), the function call obviously will take more than one clock cycle (or at least one if inlined function) so no need to wait for the rollover. There is also no need to read the timer for the start time- its already known. I would also check the countflag if this was a real piece of code in use.Anyway, books are only meant to point you in the right direction.

author: Kjelt
author_rank: Super Contributor
timestamp: June 12, 2017, 07:43:34 am
content: I think this is to compensate the delay to start the systick and load the reload value into the timer.If the old SysTick->LOAD value is too low you could otherwise get strange results. So the proper way is to start after the reload of the timer and you are sure the correct new value is loaded.

author: ataradov
author_rank: Super Contributor
timestamp: June 12, 2017, 07:46:37 am
content: Quote from: Kjelt on June 12, 2017, 07:43:34 amHow is it going to be low, if we specified what it should be?Quote from: Kjelt on June 12, 2017, 07:43:34 amThe proper way is to have timer always running. There is no real need to to all that resetting and waiting.If you get stop value lower than start value, then you know that there was an overflow, and can correct for that. This obviously assumes that measured code is slower than the systick period.

author: Kjelt
author_rank: Super Contributor
timestamp: June 12, 2017, 07:59:27 am
content: QuoteWhat I don't get is why the author sets the timer value to 0x00 while that has 0 effectSysTick->VAL = 0; // Clear current value to 0because in the next statement he enables the systick in the control register:SysTick->CTRL = 0x5; // Enable SysTick, use processor clockWhich has the following action:QuoteSo indeed the while and the value set instructions seem to be useless but there is always a reason for something, just experiment with the code and see what results you get.

author: igendel
author_rank: Frequent Contributor
timestamp: June 12, 2017, 09:30:42 am
content: Thank you all for confirming my suspicionI do think, though, that the timing will beeasiestwhen the initial VAL isnotzero, and as close as possible to RELOAD. This is because SysTick values are 24-bit, so you can't simply subtract any two measurements as if they were regular uint32_t .And, as ataradov mentioned, if function() takes more time than one SysTick period, that's a different story altogether.

author: dgtl
author_rank: Regular Contributor
timestamp: June 12, 2017, 09:55:14 am
content: Quote from: igendel on June 12, 2017, 09:30:42 amJust shift the value left by 8 bits when you read it out. The result is a 32-bit counter, that steps at 256 increments. Now do your substraction as usual.Typically the systick is used just for getting interrupts at regular intervals (thats why it is called like that) and then the counter etc are done in sw. This makes debugging simpler as the counting will freeze on breakpoint and you get a freeze in time, that you can continue later.

author: newbrain
author_rank: Super Contributor
timestamp: June 12, 2017, 10:34:32 am
content: Quote from: igendel on June 12, 2017, 09:30:42 amEither do as dgtl suggests, or simply bitwise and (&) the subtraction result with 0x00FFFFFF.As an aside, if that snippet was taken verbatim from the book and is representative of the coding style, I don't like it that much: no use of meaningful names (what's 0x5?), writing 32 bits in a 24 bit register (should not matter, but e.g. ST programmer's manual says: "Bits 31:24 Reserved, must be kept cleared.") and the pointless looping.I know that book is highly regarded, but still...

author: igendel
author_rank: Frequent Contributor
timestamp: June 12, 2017, 12:25:09 pm
content: Quote from: newbrain on June 12, 2017, 10:34:32 amTo be fair, this book isn't about coding or coding practices. There are only a few snippets, not much longer than this one, and they are usually there just to illustrate some point.[Edit: Yes, it's verbatim]

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: June 12, 2017, 04:40:36 pm
content: Quote from: igendel on June 12, 2017, 12:25:09 pmThe book has errors too. Be sure to check the following list if something appears not to be right:https://community.arm.com/processors/b/blog/posts/errors-in-the-definitive-guide-for-arm-cortex-m-book-series

author: igendel
author_rank: Frequent Contributor
timestamp: June 12, 2017, 04:48:45 pm
content: Quote from: Sal Ammoniac on June 12, 2017, 04:40:36 pmYup, that's the first place I looked (see P.S. in my original post)