2017-10-06 84 views
1

我在我的程序中遇到了一个奇怪的行为。在上下文中,我编写了一个STM32F469微控制器。使用的IDE是SW4STM32(带有Eclipse Neon版本(4.6.3))。STM32F4,IRQ处理程序和具有共享变量的函数之间的奇怪行为

直来直去的地步,这里是我有:

void foo(void){ 
    while(1){ 
     if(var.x == 1){ 
      var.x = 0; 
      var.y = 1; 

      // Some irrelevant calculus 

      var.y = 0; 
     } 
    } 

foo()功能没有具体的东西。它适用于其他不相关的东西,全局变量(结构)var

void interruption(void){ 
    if(var.x == 0 && var.y == 0){ 
     // Some irrelevant calculus 
     var.x = 1; 
    } 
} 

正如它的名称的状态,所述interruption()函数是一个ISR(中断服务例程)。与ISR相关的中断大约每16ms提高一次。它使用相同的全局变量(结构)var

最后,这里是我的main

int main(void) 
{ 
    myStruct var; 
    var.x = 0; 
    var.y = 0; 

    // Some initialization (the ISR for example) 

    foo(); 
} 

好了,所以我不明白的是,整个过程只工作,如果有“东西”的while循环和if条件,例如之间:延迟或引脚状态在foo()功能开关:

void foo(void){ 
    **Place something here to make the process work, a 1ms delay for example** 
    while(1){ 
     if(var.x == 1){ 
      var.x = 0; 
      var.y = 1; 

      // Some irrelevant calculus 

      var.y = 0; 
     } 
    } 

只要是具体的:当它不工作,这意味着,无论是我的程序经过了在ISR中的条件或foo()函数中的if条件。当它工作时,程序会通过它们两个(if条件)。

两者的if条件都是假的事实意味着:

  1. 这些值的var.x == 0
  2. 均为真if条件。事情是这样的,那就是在这里出了问题,通常这些值只在foo()函数的if条件中遇到。如果我处于这种状态,则var.y等于0

var目前无处可用。

所以,我的问题是,你有任何关于这种现象的解释吗?

谢谢!

回答

1

您可能正在看到注册表缓存的行动。确保您的全局变量声明为volatile(请参阅https://barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword)。基本上,生成的代码并不认为var.x可以在当前函数之外进行更改。 volatile关键字告诉代码生成器它应该假定该值是由异步操作(ISR,信号处理程序,其他线程等)修改的。

哦,我假设目标语言是C或C++,因为该语言定义了volatile关键字。

+0

我从来没有完全理解如何使用'volatile'关键字,为什么和什么时候应该使用(因为你的文章指出btw)。现在我明白了。它解决了这个问题。谢谢 ! – vionyst

+0

@ D.Shawley在你的情况下它是不够的!它也必须是原子的。 volatile不会影响对象的加载和存储,但不是原子性。他检查值并采取可能同时更改的值的操作(加载/修改/存储之间)。 –