Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are global variables refreshed between function calls?

Im writing embedded firmware, and find it sometimes hard to decide when I need volatile or not.

When I have a function that waits for some boolean flag to be changed by an interrupt, it's obvious that the flag needs to be volatile, because else the function would wait forever, since the compiler doesn't realise the value can be changed by the interrupt.

But when I have a short function that just checks a flag in the first line, I would expect the flag doesnt need to be volatile, because its value will be read every time I enter the function? So when an interrupt modifies its value between the first time I call the function, and the second time, I will get the fresh value. Or is it not guaranteed that every time I enter the function all caching registers are cleared?

like image 725
Maestro Avatar asked Feb 01 '13 01:02

Maestro


2 Answers

You would still need to mark your variable volatile: since the optimizer is free to inline your functions, especially the short ones, calling your function in a loop without a volatile mark for accessing hardware-modified memory would place you in danger of not reading the memory after the initial iteration.

like image 95
Sergey Kalinichenko Avatar answered Sep 22 '22 14:09

Sergey Kalinichenko


...because its value will be read every time I enter the function?

No, there is no guarantee for this. The problem with the "lack of volatile bug" is that the compiler's optimizer, unaware of that a certain variable can get changed from an external source, changes the whole meaning of the code.

So if you have this:

static int x=0;

int func (void)
{
  if(x == 0)
  {
    return 1;
  }
  else
  {
    return 0;
  }
}

interrupt void isr (void)
{
  x = SOMETHING;
}

Then the compiler will ponder: "Hmm, x is never modified anywhere, since "isr" is never called from the program. So x is always 0, I'll optimize the code to this:"

int func (void)
{
  return 1;
}

And then, perhaps, it will inline the whole function. Whether that happens or not is of no consequence, since the meaning of the code is already destroyed in the previous optimization step.

Any variable shared with an interrupt (or a thread, or DMA, or a hardware register, or a callback function) must be declared as volatile, always.

like image 34
Lundin Avatar answered Sep 21 '22 14:09

Lundin