首页 文章

易失性使用,变量未读取主要内容

提问于
浏览
-1

我知道这里有很多关于volatile的问题,但是我没有找到任何特定于这种情况的东西 . 我正在使用微控制器 . 我知道当我在ISR中修改一个全局变量并在我的main函数中读取它时,我必须使用volatile限定符 . 我也觉得非常适合记忆障碍,比赛条件等 .

但是如果我只在主函数中写入一个全局变量(中断被禁用以强制执行原子写入)并且我正在我的ISR中读取和写入它 .

为了给出一个明确的例子假设这个代码:

int state = 0;
ISR()
{
    switch(state)
    {
        case 0:
            //do something
            state=nextState; //go to another state
            break;
        case 1:
            //do something
            state=nextState; //go to another state
            break;
        case 2:
            //do something
            state=nextState; //go to another state
            break;
        //...some more states
        default:
            state=0;
            break;
    }
}

main(void)
{
     while(true)
     {
          //do lots of stuff
          if(someCondition)
          {
               EnterCriticalSection(); //Disable IRQs and memorybarrier
               //write to global shared variable state here!!!
               state=0;
               ExitCriticalSection(); //Enable IRQs again
          }
     }
}

所以必须在这里挥发吗?

什么时候,为什么? (我从来没有真正使用main中的值)编译器可以优化写入状态或其他东西 . 或者编译器是否可以在ISR的多个调用中保持某些寄存器中缓存的状态值?现在我保持像状态不稳定的变量,但我很好奇这是否真的有必要 .

编辑:嗯,是的,我现在明白了答案 . 我道歉,我应该多考虑几分钟 . 当我想到它时,它与(只写)硬件寄存器非常相似 . 当然我需要volatile来确保main方法中的写操作 .

2 回答

  • 5

    这种情况与您“知道”您需要易变的情况并没有区别 .

    它不是关于ISR和 main() 以及哪些读取和写入,而是关于不同的执行线程上下文 . 这些线程上下文是什么并不重要 - 语言不是线程感知的,因此不会考虑用于优化目的 - 您必须通过 volatile 告诉它,无论何时数据直接在上下文之间共享 .

    看一下:Embedded.com上的Introduction to the volatile keyword,还有When to use – and not use – the volatile keyword,它整理了很多关于这个主题的文章,包括第一篇 .

  • 0

    事实上你从未在 main 中使用 state 的值实际上使它更有可能被优化掉 .

    由于 statemain 中仅设置为零,因此编译器可以通过将其设置为零一次进行优化,而不再对其进行写入 .

    如果要确保每次 someCondition 为真时 state 归零,则需要使用 volatile .

相关问题