嵌入式开发中的Volatile~~
内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存Cache,加速对内存的访问。
编译器优化常用的方法有:将内存变量缓存到寄存器;
由于访问寄存器的速度快于访内存,所以编译器一般
都会作优化以减少访内存。如果变量加上volatile修饰,则编译器就不会对此变量
的读写操作进行优化,即不通过寄存器缓冲而直接访内存。
C语言关键字volatile表明某个变量的值可能在外部被改变,因此对这些变量的存取不能缓存到寄存器,每次使用时需要重新存取。
该关键字在多线程环境下经常使用,因为在编写多线程的程序时,同一个变量可能被多个线程修改,而程序通过该变量同步各个线程,
对于C编译器来说,它并不知道这个值会被其他线程修改。自然就把它cache在寄存器里面。记住,C 编译器是没有线程概念的
volatile 的本意是指:这个值可能会在当前线程外部被改变。
下面有个例子:
--------------------------------------------------------------------------------
volatile是“易变的” 意思
由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。比如:
bit bFlag=0;
int main(void)
{
…
while (1)
{
if (bFlag) dosomething();
}
}
/* 中断程序*/
void ISR(void)
{
bFlag=1;
}
程序的本意是希望ISR中断产生时,在main当中调用dosomething函数,但是,由于编译器判
断在main函数里面没有修改过bFlag,因此
可能只执行一次对从bFlag到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面
的“bFlag副本”,导致dosomething永远也不会被调用。如果将将变量加上volatile修饰,
则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中bFlag也应该如此说
明。
--------------------------------------------------------------------------------
一般说来,volatile用在如下的几个地方:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。
补充阅读
嵌入式C 中的volatile和const
文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppsl/2008618/126437.html)
C语言关键字volatile表明某个变量的值可能在外部被改变,因此对这些变量的存取不能缓存到寄存器,每次使用时需要重新存取。
该关键字在多线程环境下经常使用,因为在编写多线程的程序时,同一个变量可能被多个线程修改,而程序通过该变量同步各个线程。对于C编译器来说,它并不知道这个值会被修改,自然就把它cache在寄存器里面。
C编译器是没有线程概念的,这时候就需要用到volatile。
volatile的本意是指这个值可能会在当前线程外部被改变,也就是说,我们要在threadFunc中的intSignal前面加上volatile关键字,这时候,编译器知道该变量的值会在外部改变,因此每次访问改变量时会重新读取。
const可定义一个常量。如:int const a;
那么,既然a的值不能被修改,如何让a拥有一个值呢?两种方法:
第一,在定义时对它初始化,如:int const a=10;
第二,在函数声明为const的形参在函数被调用时会得到实参的值。
需要强调的是牵涉到指针变量的情况。如下所示:
int const *a;
int *const a;
当const写在关键字之后时,查看const究竟指定了何种数据类型为常量要看const之前的数据类型。在第一条语句中,const指定常量的对象是整形数据,即指针a所指向的内存单元的整型内容,因此,该整型数据是不可被改变的,而a这个指针本身的值(地址)是可以被改变的。
在第二个语句中,const指定常量的对象是指向整形数据的指针,则该指针本身(地址)的值是不可被改变的,而该指针所指向的内存单元的内容则是可以改变的。
文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppsl/2008618/126437.html)