小智 5
如果在正常执行流程中更改(写入)了全局变量,并且仅在该正常流程之外(在中断中)读取。这个变量需要可变吗?
是的,一点没错。
又为什么呢?
确保正确执行中断处理程序(而不是正常流程)。
让我详细说明。
假设您有一个这样的变量:
int x;
Run Code Online (Sandbox Code Playgroud)
您正在程序的正常流程中修改此变量,如下所示:
void modify(int *x){...some code here...}
Run Code Online (Sandbox Code Playgroud)
在中断服务程序中,您正在读取变量。
请记住,中断可以异步发生(任何时候)。还要记住,编译器会首先将您的代码转换为一系列机器指令,看起来像这样:
load val from mem to register
perform modification operations
store value from registers to memory
perform other operations where the variable is used
Run Code Online (Sandbox Code Playgroud)
现在,编译器可以优化该程序,以减少这样的内存读写次数:
load value
perform modifications
use value
...
modify register content
...
use
...
keep using value from the registers without ever storing in the memory.
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果发生中断(请注意,中断上下文通常不同于正常上下文,因此在许多体系结构中具有不同的寄存器集(例如arm ...)),它将尝试读取中断。内存中变量的值。但是由于编译器的优化,内存的内容从未改变过。
因此,ISR可能会读取旧值(更糟糕的是-我们不能肯定地说一个值有多旧),这会导致意外的行为。
因此,应将变量声明为volatile,以防止编译器干预程序。
| 归档时间: |
|
| 查看次数: |
259 次 |
| 最近记录: |