微控制器中的Volatile关键字
Volatile keyword in microcontrollers
volatile
关键字告诉编译器不要优化带有前缀的变量。该变量可能在运行期间被未知源(编译器不知道)更改,可能是由外部中断等。
volatile
还有其他优势吗?volatile
是否适用于读取文件?
volatile
关键字告诉编译器不要优化前缀的变量,变量可能在运行时被未知源(编译器不知道)改变,可能是由外部中断等
。volatile
关键字不告诉编译器禁用或不优化变量;volatile
关键字告诉编译器该变量(或者该变量所代表的内存)可以在程序的外部被修改。
这会导致编译器不再能够进行必要的分析来确定各种优化是否安全(这在功能上是等同的),因此编译器不会执行这些优化。这是一个必要的副作用,但不是关键字存在的主要目的。
使用volatile
作为一种或多或少可移植的方法,类似于pragma
来禁用编译器的优化,这是一种相当常见的模式。在嵌入式编程之外,这可能是应用程序程序员最常遇到的用法。
编译器知道该控制器的所有中断。那么在这种情况下,
volatile
关键字有什么帮助呢?
volatile
关键字意味着内存内容可以在程序控制之外修改,可以在另一个进程、线程中修改,也可以通过外部信号(如硬件中断)修改。
编译器不"知道"中断,可能有一些系统头文件和编译器一起为中断定义了符号名,但这并不意味着编译器理解它们。
volatile
还有其他优势吗?
除了这里所描述的,我想不起来。
[Does]
volatile
appl[y] to read from files?
除非用作进程间通信(IPC)的一种形式或作为信号量,否则文件的内容通常由单个进程控制,因此没有必要使用volatile
。
volatile
实际上告诉编译器变量的值可以在其控制流之外被更改。最流行的是中断或中断处理程序或硬件寄存器。对于后者,编译器实际上不知道它的值何时改变。对于中断也是如此,因为它只在运行时发生。
注意C语言假设一个单线程程序流;编译器对并发进程没有任何概念。它对底层硬件的假设更少。
对于所有其他变量,编译器可能(例如gcc实际上将)假设它完全了解系统状态。
对volatile
变量的访问也不能相对于其他变量重新排序。当UART要求首先读取状态寄存器,然后将新字符存储到传输数据寄存器时,这一点很重要。对于大多数mcu,只有这个序列才能正确清除标志。非常重要:非易变变量可以按照编译器的意愿对重新排序(当然,只要不改变程序逻辑)。
volatile
不能保证多核系统上的原子性和正确行为,也不能防止硬件(内存控制器等)对访问的重新排序(好吧,AVR在所有这些方面都有点特权不足;-)。这就是使用锁的原因之一,也是为什么硬件对内存映射中的硬件区域进行特殊处理(有序的、非共享的)。
编辑:下面详细说明了gcc如何处理volatile对象。众所周知,GCC严格遵守优化标准。任何未被禁止的内容都可能被用于优化。像IAR这样的经典嵌入式编译器通常要保守得多。
volatile的C/c++标准意味着对volatile变量的读和写将是对内存中该位置的读或写,并且对volatile变量的操作顺序将保持不变。由于对易失性变量的读取实际上是对内存中变量的读取,因此如果变量被外部源(如另一个线程、进程或硬件)更新,则read值将反映读取之前发生的任何写操作。它意味着用于内存映射的硬件接口,如I/O内存映射端口。它不能防止对其他变量的无序操作。我假设对多个易失性变量的操作顺序是保持的,因为这是硬件/软件握手所需要的。
Microsoft编译器选择性地扩展了volatile的含义,因此对volatile变量的读/写操作可以作为内存屏障有效地完成,并且可以用于线程之间的通信。正如您所提到的,MSDN volatile .
volatile
保证编译器不会对该变量执行任何优化。如果一个变量的值在编译器确定的范围内没有改变,它可以将该值缓存到寄存器中,并引用缓存的值以提高效率,这样就不会浪费从主存中获取实际值的周期。
我可以想象,在一个寄存器数量如此有限的微控制器中,您不会想要不断缓存变量。
- Visual Studio 2015:Extern "C" 和 "export" 关键字
- C++中的"inline"关键字
- 如何确保C++函数在定义之前声明(如override关键字)
- 在一个读写器队列中,我可以用volatile替换原子吗
- 谷歌模拟和覆盖关键字
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- 为什么"delete"关键字不删除节点?
- 在 c++ 中正确定义"this"关键字?
- 这个额外的关键字在这个 c++ 类声明中是什么意思?
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- 了解C++中的'volatile'关键字
- C++11是否允许(不要求)volatile关键字的发布/获取语义
- C#和C++中的volatile关键字
- Volatile关键字允许访问UnitTest++中的常量结构
- 如果我在互斥锁之间声明一个变量并返回它,我需要使用volatile关键字吗?
- 在VS2012中使用'volatile'关键字的最佳实践
- 从语法的角度来看,"volatile"关键字在C++函数中有多少用法?
- 微控制器中的Volatile关键字