您的位置 首页 数字

对Volatile的了解

Volatile字面的意思时易变的,不稳定的。编译器在优化代码时,可能会把经常用到的代码存在Cache里面,然后下一次调用就直接读取Cache而不

Volatile 字面的意思时易变的,不安稳的。

编译器优化代码时,或许会把常常用到的代码存在Cache里边,然后下一次调用就直接读取Cache而不是内存,这样就大大提高了功率。可是问题也随之而来了。

在多线程程序中,假如把一个变量放入Cache后,又有其他线程改动了变量的值,那么本线程是无法知道这个改动的。它或许会直接读Cache里的数据。可是很不幸,Cache里的数据现已过期了,读出来的是不达时宜的脏数据。这时就会呈现bug。也就是说假如它是一个寄存器变量或许表明一个端口数据就简单犯错,所以说volatile能够确保对特别地址的安稳拜访。

用Volatile声明变量能够处理这个问题。用Volatile声明的变量就相当于告知编译器,我不要把这个变量写Cache,因为这个变量是或许发生改动的。

假如一个变量的值或许会被程序操作之外的其它操作所改动,那么你必需用volatile 声明。在嵌入式体系中其它操作是:中止服务程序的操作、硬件动作的操作等,下面列举了需求加volatile 声明的状况。

1、中止服务程序中修正的供其它程序检测的变量需求加volatile;

2、多使命环境下各使命间同享的标志应该加volatile;

3、存储器映射的硬件寄存器一般也要加volatile阐明,因为每次对它的读写都或许由不同含义;

用volatile声明的变量是不会被编译器优化掉的

例如:

#definePortA( * ( volatile unsignedint * )0x0000 )

这样 PortA 成为一个地址在0x0000的unsigned int类型变量。这个界说看起来很杂乱,其实它也能够分解成几个很简单的部分来看。 ( volatile unsignedint * )是C语言中的强制类型转化,它的作用是把0x0000这个朴实的十六进制数转化成为一个(地址)指针,其间volatile并不是必要的,它仅仅告知编译器,这个值与外界环境有关,不要对它优化。接下来在外面又加了一个*号,就表明0x0000内存单元中的内容了。通过这个宏界说之后,PortA就被能够做为一个一般的变量来操作,一切呈现PortA的当地编译的时分都被替换成( * ( volatile unsignedint * )0x0000 ),外面一层括号是为了确保里边的操作不会因为运算符优先级或许其它不行猜测的原因被改动而无法得到预期的成果。

PORTA做为一个输入端口,其值是由外部设备决议的,因为外部设备的改动是随机的,因而第一次读取的值和第2次读取的值很或许不同,所以咱们把它声明为volatile变量。

a = PORTA;

a = PORTA;

因为PORTA是用volatile声明的变量,编译器不会把它优化成一句,而假如不是volatile声明的编译器就会将第二句优化掉,然后程序将会疏忽输入端口的改动。

一般把嵌入式设备的一切外围器材寄存器都声明为volatile的。

这种界说办法合适一切的C编译器,可移植性好,但PortA并不是一个真实的变量,仅仅一个宏名,当你调试一个程序的时分,无法在调试窗口调查它的值。别的连接器也失去了灵活性,它得避免其它变量跟此变量抵触。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/shuzi/258765.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部