在通用的c语言里,加volatile是为了c编译器的优化器对数据流进行分析,尽可能避免访问存储器,如果在程序中与访问存储器有关的代码和用c语言书写的代码完全相同,必须使用volatile来标明这些访问,编译器不能优化任何对volatile变量的引用,而const则是对常量的定义。 const定义视分散加载文件情况而定。 如果分散加载文件将代码都放到RAM里执行,即使你声明的是const类型,也被放到了RAM。如果分散加载文件将代码都放到ROM里执行,则当被声明的变量为const类型时,编译器将其放到ROM中,如果被声明的变量为非const类型,则编译器将其放到RAM里。 ARM是冯若依漫结构,ROM和RAM统一编址,统一寻址,code/xdata/data/pdata/idata是针对哈佛结构的存储类型,是C51规定的存储类型!在ARM的编译器中使用会提示出错了! volatile是ANSI C语言关键字之一。其作用可以用一句话来概括:用volatile修饰的变量可以防止被编译器优化。定义一个普通变量时,有可能被编译器优化成寄存器变量。如果加上volatile,那它一定是存储器变量。编译器可能会认为某些语句是多余的,从而自动优化掉。例如“{int x; x=57; x=24; ...}”,其中“x=57;”是多余的。如果加上volatile,则不会被优化掉。某些全局变量,在中断服务函数中可能会被隐含地改变。这样的全局变量应当要用volatile修饰。主程序每次访问该变量时,都可以确保是最新的值。存储器映射的I/O变量,也可能会自动地改变。因此也要加上volatile属性。 比如: static int i=0; int main(void) { ... while (1) { if (i) dosomething(); } } void ISR_2(void) { i=1; } 程序的本意是希望ISR_2中断产生时,在main当中调用dosomething函数,但是,由于编译器判断在main函数里面没有修改过 i,因此可能只执行一次对从 i 到某寄存器的读操作,然后每次 if 判断都只使用这个寄存器里面的“i副本”,导致dosomething永远也不会被调用。如果将将变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中 i 也应该如此说明。 一般说来,volatile用在如下的几个地方: 1、中断服务程序中修改的供其它程序检测的变量需要加volatile; 2、多任务环境下各任务间共享的标志应该加volatile; 3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义; 另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。、
有关volatile变量和const常量
最新推荐文章于 2024-05-02 15:33:55 发布