STM32F4,IRQ处理程序和具有共享变量的函数之间的奇怪行为

STM32F4,IRQ处理程序和具有共享变量的函数之间的奇怪行为,stm32,stm32f4,irq,isr,Stm32,Stm32f4,Irq,Isr,在我的程序中,我面临着一种奇怪的行为。在上下文中,我正在编程一个STM32F469微控制器。使用的IDE是SW4STM32(带有Eclipse Neon版本(4.6.3)) 直截了当地说,以下是我的观点: void foo(void){ while(1){ if(var.x == 1){ var.x = 0; var.y = 1; // Some irrelevant calculus

在我的程序中,我面临着一种奇怪的行为。在上下文中,我正在编程一个STM32F469微控制器。使用的IDE是SW4STM32(带有Eclipse Neon版本(4.6.3))

直截了当地说,以下是我的观点:

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

            // Some irrelevant calculus

            var.y = 0;
        }
    }
foo()
函数没有任何特定的内容。除了其他不相关的事情之外,它还可以使用全局变量(struct)
var

void interruption(void){
    if(var.x == 0 && var.y == 0){
        // Some irrelevant calculus
        var.x = 1;
    }
}
正如其名称所述,
interruption()
函数是一个ISR(中断服务例程)。与此ISR相关的中断大约每16毫秒触发一次。它使用相同的全局变量(struct)
var

void interruption(void){
    if(var.x == 0 && var.y == 0){
        // Some irrelevant calculus
        var.x = 1;
    }
}
最后,这里是我的
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中的
if
条件,也不会通过
foo()
函数中的
if
条件。当它工作时,程序将同时执行这两个条件(
if
condition)

两个
if
条件均为false表示:

  • var.x==0
  • var.y==1
  • 这两个值在
    if
    条件外均为真。问题是,这就是这里出错的地方,通常只有在
    foo()
    函数的
    if
    条件下才会遇到这些值。如果我处于这种状态,
    var.y
    在这个条件结束时等于
    0
  • var
    目前在其他任何地方都没有使用

    所以,我的问题是,你对这个现象有什么解释吗


    谢谢

    您可能看到寄存器缓存正在运行。确保您的全局变量声明为
    volatile
    (请参阅)。基本上,生成的代码不认为
    var.x
    可以在当前函数之外更改。
    volatile
    关键字告诉代码生成器,它应该假设值是由异步操作(ISR、信号处理程序、其他线程等)修改的


    哦,我假设目标语言是C或C++,因为语言定义了<代码> Value关键字。

    我从来没有完全理解如何、为什么以及何时使用代码> Value关键字(如你的文章所说的BTW)。现在我知道了。它解决了这个问题。谢谢@D.Shawley这在你的情况下是不够的!!!它也必须是原子的。volatile不做任何其他事情,它只确保对象的加载和存储,而不保证原子性。他检查该值并对可能同时更改的值(在加载/修改/存储之间)执行操作。