当仅在中断期间读取变量时需要挥发 [英] Is volatile needed when variable is only read during interrupt

查看:85
本文介绍了当仅在中断期间读取变量时需要挥发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C标准规定,如果变量的值可能在程序的正常执行流程之外发生变化,则应在变量的定义中使用volatile关键字。



如果在常规执行流程中更改(写入)全局变量,并且仅在该常规流程之外(在中断中)读取。此变量是否需要可变?以及为什么?

解决方案


如果在常规执行流程中仅更改(写入)了全局变量,并且仅在正常流程之外读取(在中断中)。


是的。


为什么?


以确保正确执行中断处理程序(而不是正常流程)。 p>




让我详细说明。



想象一下您有一个像这样的变量:

  int x; 

您正在程序的正常流程中修改此变量,如下所示:

  void Modify(int * x){...此处有一些代码...} 

在中断服务程序中,您正在读取变量。



请记住,中断可以异步发生(随时)。还要记住,编译器会首先将您的代码转换为一系列机器指令,看起来像这样:

  load val from寄存器
的内存执行修改操作
从寄存器到内存的存储值
执行使用变量的其他操作

现在,编译器可以优化该程序,以减少内存的读写次数,例如:

 加载值
执行修改
使用值
...
修改寄存器内容
...
使用
。 ..
会继续使用寄存器中的值,而无需存储在内存中。

在这种情况下,如果发生中断,(请注意,中断上下文通常与通常情况下,因此在许多体系结构(例如arm ...)中具有不同的寄存器集,它将尝试从内存中读取变量的值。但是由于编译器的优化,内存的内容从未改变过。



因此,ISR可以读取旧值(更糟糕的是,我们不能肯定地说出如何



因此,应将变量声明为volatile,以防止编译器干预程序。


The C standard states that the volatile keyword should be used in the definition of a variable when there's a chance that the variable's value could change outside the normal flow of execution of the program.

If a global variable is changed (written) during normal execution flow and only read outside this normal flow (in an interrupt). Does this variable need to be volatile ? And why ?

解决方案

If a global variable is changed (written) during normal execution flow and only read outside this normal flow (in an interrupt). Does this variable need to be volatile?

Yes absolutely.

And why?

To ensure proper execution of the interrupt handler (rather than the normal flow).


Let me elaborate.

Imagine you have a variable like this:

int x;

You are modifying this variable in the normal flow of the program as this:

void modify(int *x){...some code here...}

And in the interrupt service routine, you are reading the variable.

Remember that an interrupt can occur asynchronously(at any time). Also remember that the compiler will first convert your code into a series of machine instructions which could look something like this:

load val from mem to register
perform modification operations
store value from registers to memory
perform other operations where the variable is used

Now, the compiler may optimise this program to reduce the number of memory read-writes as such:

load value
perform modifications
use value
...
modify register content
...
use
...
keep using value from the registers without ever storing in the memory.

In such a case, if an interrupt occurs, (note that the interrupt context is usually different from the normal context and thus has different set of registers in a lot of architectures (say arm...)), it will attempt to read the value of the variable from the memory. But the contents of the memory have never been changed because of compiler optimisation.

So, the ISR could read an old value (worse still-we can't definitely say how old a value) which would result in unintended behaviour.

So, the variable should be declared as volatile to prevent the compiler from meddling with the program.

这篇关于当仅在中断期间读取变量时需要挥发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆