函数调用之间是否刷新了全局变量?

Mui*_*uis 9 c embedded gcc volatile c99

我正在编写嵌入式固件,并发现有时很难确定何时需要使用volatile.

当我有一个等待某个布尔标志被中断改变的函数时,很明显该标志需要是易失性的,因为该函数会永远等待,因为编译器没有意识到该值可以由打断.

但是当我有一个只检查第一行中的标志的短函数时,我希望标志不需要是volatile,因为每次进入函数时它的值都会被读取?所以当一个中断在我第一次调用函数和第二次调用函数之间修改它的值时,我将得到新值.或者是否无法保证每次进入该功能时都会清除所有缓存寄存器?

das*_*ght 8

您仍然需要标记您的变量volatile:由于优化器可以自由地内联您的函数,尤其是短函数,因此在没有volatile用于访问硬件修改内存的标记的循环中调用函数会使您在以后无法读取内存的危险最初的迭代.


Lun*_*din 5

...因为每次进入函数时都会读取它的值?

不,不能保证这一点."缺乏易失性错误"的问题在于编译器的优化器,不知道某个变量可以从外部源改变,改变了代码的整个含义.

所以,如果你有这个:

static int x=0;

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

interrupt void isr (void)
{
  x = SOMETHING;
}
Run Code Online (Sandbox Code Playgroud)

然后编译器会思考:"嗯,x永远不会被修改,因为"isr"永远不会从程序中调用.所以x总是0,我会优化代码:

int func (void)
{
  return 1;
}
Run Code Online (Sandbox Code Playgroud)

然后,也许,它将内联整个功能.这种情况是否发生无关紧要,因为代码的含义在之前的优化步骤中已被破坏.

与中断(或线程,或DMA,或硬件寄存器或回调函数)共享的任何变量必须始终声明为volatile.