-2

I made simple delay func:

void Delay(__IO uint32_t nCount)
{
  while(nCount--) {}
}

And I want to predict time duration of single execution with some value. I know it's bad idea but I don't need accurate time and it will be not interrupted.

I'm using STM32F405 @ 168 MHz with 8 MHz external crystal.

So far I've noticed that calling it with 0x80 0000 gives me about half second delay.

Jacob
  • 109
  • 2
  • 11
  • 4
    If you want a timer, why not use a timer? – Carl Norum Aug 17 '13 at 15:18
  • 1
    I don't need a timer. – Jacob Aug 17 '13 at 15:19
  • 4
    ... but you're trying to time something. I don't really understand your question, maybe. – Carl Norum Aug 17 '13 at 15:21
  • You really need to look at the generated code, and calculate the time used for the instructions to be able to get any kind of accuracy. And that will only work if you run on the bare metal, with no kind of pre-emption (including interrupts). – Some programmer dude Aug 17 '13 at 15:23
  • 2
    Can you do a test with your half-a-second findings, but this time with your compiler set to produce *optimized* code? – Jongware Aug 17 '13 at 15:23
  • Jongware sorry but not right now.I just wanna know how much is one decrementation for (in my case) Keil's compiler but I'm sure it will work the same for other compilers. But true - code optimization could change something here! – Jacob Aug 17 '13 at 15:37
  • 4
    Optimization *will* change the timing. That's one reason why those Cortex-M4 chips come with a bunch of hardware timers. – Turbo J Aug 17 '13 at 19:59

2 Answers2

4

So instead of having an empty while loop, you should put __no_operation(); in there (2 underscores, not 1). This takes ~29ns per instruction cycle at 168MHz on my board, and it's inserting intrinsic assembly NOP's directly into the code stream, so it will stand-up against any optimizations.

One last note: your loop-counter is __IO, meaning that it's volatile. This means the loop-counter will not be put in a CPU register. You can change that once you put the __no_operation(); line in your loop, because it will protect it from being eliminated by the compiler.

You typically should use a timer, but sometimes we all just need a hack-up :)

-Jesse

bunkerdive
  • 2,031
  • 1
  • 25
  • 28
  • 1
    exactly!... Sometime we just need a quick hack. In embedded system delay with a for loop is very common. and also we are very use to it. So whenever we came to a new platform where we just started learning. It is better to use for loop delay instead of bothering with timers. – Abdul Rehman Dec 30 '19 at 17:52
2

The amount of time it takes to execute that function can vary widely depending on your compiler and settings. Since your function does nothing an optimizer would turn this function into a simple bx lr, which takes very little time. If you are able to measure the time then you are not optimizing (and your overall execution of this and other parts of your code will vary even more).

Assuming you solve that problem in a deterministic and repeatable manner, you can get a rough idea of how long it takes to execute by executing it and timing it using a reference clock. the timers in the cortex-m4 are an excellent choice.

Any time you change the way you use this code, turn on a cache, or change the processor clock, change the timing settings on the flash, etc, you will need to re-tune your delay function.

It is far easier to just use one of the timers directly to perform a delay, and the accuracy is improved by quite a bit. Prevents having to continue to maintain the counter loop code and/or calls to it.

old_timer
  • 69,149
  • 8
  • 89
  • 168