ImageVerifierCode 换一换
格式:DOCX , 页数:11 ,大小:22.75KB ,
资源ID:5073816      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5073816.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(volatile用法.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

volatile用法.docx

1、volatile用法volatile用法的相关文章由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。比如: static int i=0; int main(void) . while (1) if (i) dosomething(); /* Interrupt service routine. */ void ISR_2(void) i=1; 程序的本意是希望ISR_2中断产生时,在main当中调用dosomething函数,但是,由于编译器判断在main函数里面没有修改过i,因此可能只执行一次对从i到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面的“

2、i副本”,导致dosomething永远也不会被调用。 如果将将变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中i也应该如此说明。 一般说来,volatile用在如下的几个地方: 1、中断服务程序中修改的供其它程序检测的变量需要加volatile; 2、多任务环境下各任务间共享的标志应该加volatile; 3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能有不同意义; 另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只

3、能依*硬件的良好设计了。 1. 因为volatile抑制了优化,因而应尽量减少对它的引用操作,最好只对它进行简单的读写赋值,如: volatile char *pcWr_g; . while (.) *pcWr_g+=UDR; . 考虑改写成: char *pcTemp; . pcTemp=pcWr_g; while (.) *pcTemp+=UDR; pcWr_g=pcTemp; . (其实即便pcWr_g是普通的全局变量,一般而言也是改写后的效率高些,可以在循环中只针对寄存器操作) 2. 优化还会清除死代码、执行代码合并等,因而某些C语句可能找不到直接对应的汇编代码,这应该只会给调试设置断

4、点有影响,不影响运行结果。 3. 类似 for (i=0; i10000; i+) j=0; 之类的延时,如果不把j或者i说明成volatile,编译器都会当成无用代码把优化掉文章二:volatile的本意是一般有两种说法-1.“暂态的”;2.“易变的”。 这两种说法都有可行。但是究竟volatile是什么意思,现举例说明(以Keil-c与a51为例 例子来自Keil FQA),看完例子后你应该明白volatile的意思了,如果还不明白,那只好 再看一遍了。 例1. void main (void) volatile int i; int j; i = 1;/1不被优化 i=1 i = 2;/

5、2不被优化 i=1 i = 3;/3不被优化 i=1 j = 1;/4被优化 j = 2;/5被优化 j = 3;/6j = 3 -例2. 函数: void func (void) unsigned char xdata xdata_junk; unsigned char xdata *p = &xdata_junk; unsigned char t1, t2; t1 = *p; t2 = *p; 编译的汇编为: 0000 7E00R MOV R6,#HIGH xdata_junk 0002 7F00R MOV R7,#LOW xdata_junk ;- Variable p assigned

6、 to Register R6/R7 - 0004 8F82MOV DPL,R7 0006 8E83MOV DPH,R6 ;! 注意 0008 E0MOVXA,DPTR 0009 F500R MOV t1,A 000B F500R MOV t2,A ;! 000D 22RET将函数变为: void func (void) volatile unsigned char xdata xdata_junk; volatile unsigned char xdata *p = &xdata_junk; unsigned char t1, t2; t1 = *p; t2 = *p; 编译的汇编为: 00

7、00 7E00R MOV R6,#HIGH xdata_junk 0002 7F00R MOV R7,#LOW xdata_junk ;- Variable p assigned to Register R6/R7 - 0004 8F82MOV DPL,R7 0006 8E83MOV DPH,R6 ;! 0008 E0MOVXA,DPTR 0009 F500R MOV t1,A;a处 000B E0MOVXA,DPTR 000C F500R MOV t2,A ;! 000E 22RET比较结果可以看出来,未用volatile关键字时,只从*p所指的地址读一次 如在a处*p的内容有变化,则t2得

8、到的则不是真正*p的内容。 -例3 volatile unsigned char bdata var;/ use volatile keyword here sbit var_0 = var0; sbit var_1 = var1; unsigned char xdata values10; void main (void) unsigned char i; for (i = 0; i sizeof (values); i+) var = valuesi; if (var_0) var_1 = 1; /a处 valuesi = var;/ without the volatile keywor

9、d, the compiler / assumes that var is unmodified and does not / reload the variable content. 在此例中,如在a处到下一句运行前,var如有变化则不会,如var=0xff; 则在 valuesi = var;得到的还是valuesi = 1; -应用举例: 例1. #define DBYTE (unsigned char volatile data*) 0) 说明:此处不用volatile关键字,可能得不到真正的内容。 -例2. #define TEST_VOLATILE_C/* / verwendete

10、 Include Dateien /* #if _C51_ 600 #error: ! Keil 版本不正确 #endif /* / 函数 void v_IntOccured(void) /* extern void v_IntOccured(void); /* / 变量定义 /* char xdata cValue1;/全局xdata char volatile xdata cValue2; /全局xdata /* / 函数: v_ExtInt0() / 版本: / 参数: / 用途:cValue1+,cValue2+ /* void v_ExtInt0(void) interrupt 0

11、cValue1+; cValue2+;/* / 函数: main() / 版本: / 参数: / 用途:测试volatile /* void main() char cErg; /1. 使cErg=cValue1; cErg = cValue1; /2. 在此处仿真时手动产生中断INT0,使cValue1+; cValue2+ if (cValue1 != cErg) v_IntOccured(); /3. 使cErg=cValue2; cErg = cValue2; /4. 在此处仿真时手动产生中断INT0,使cValue1+; cValue2+ if (cValue2 != cErg) v

12、_IntOccured(); /5. 完成 while (1); /* / 函数: v_IntOccured() / 版本: / 参数: / 用途: 死循环 /* void v_IntOccured() while(1); 仿真可以看出,在没有用volatile时,即2处,程序不能进入v_IntOccured(); 但在4处可以进入v_IntOccured(); 关于volatile关键字的说明以及测试 volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化

13、,从而可以提供对特殊地址的稳定访问。使用该关键字的例子如下:int volatile nVint;当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。例如:volatile int i=10;int a = i;。/其他代码,并未明确告诉编译器,对i进行过操作int b = i;volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,

14、它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问。注意,在vc6中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编代码,测试有无volatile关键字,对程序最终代码的影响:首先用classwizard建一个win32 console工程,插入一个voltest.cpp文件,输入下面的代码:#include void main()int i=10;int a = i;printf(i= %dn,a);/下面汇编语句的作用是改变内存中i值,但是又不

15、让编译器知道_asm mov dword ptr ebp-4, 20hint b = i;printf(i= %dn,b);然后,在调试版本模式运行程序,输出结果如下:i = 10i = 32然后,在release版本模式运行程序,输出结果如下:i = 10i = 10输出的结果明显表明,release模式下,编译器对代码进行了优化,第二次没有输出正确的i值。下面,我们把 i的声明加上volatile关键字,看看有什么变化:#include void main()volatile int i=10;int a = i;printf(i= %dn,a);_asm mov dword ptr eb

16、p-4, 20hint b = i;printf(i= %dn,b);分别在调试版本和release版本运行程序,输出都是:i = 10i = 32这说明这个关键字发挥了它的作用!*上午在CSDN的C版逛时,发现有人在问volatile关键字的用义和用法。如果你懂一点点的编译器的知识我想你都会知道编译器在编译你的代码的时候,用进行自动优化的,用以产生优化指令。同上操作系统和一些线程同样也会对你所定义的一些变量做出一些你所不知道的更改。这样的更改我们称为,隐式修改,因为你不知道,编译器在什么情况下,在哪里做出了优化,甚至你都不知道,或是不能肯定编译器到底有没有对你的代码做出优化。看看下面的例子#

17、include void main()int i=10;int a = i;printf(i= %dn,a);_asm mov dword ptr ebp-4, 20h/下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道,来隐式的修改了变量。int b = i;printf(i= %dn,b);然后,在调试版本(debug)模式运行程序,输出结果如下:i = 10i = 32然后,在release版本模式运行程序,输出结果如下:i = 10i = 10呵呵结果看到了吗?输出的结果明显表明,release模式下,编译器对代码进行了优化,第二次没有输出正确的i值。所以得出一个结论在VC中

18、release模式编译代码时编译器会自动对你的代码来做起优化的。而调试版本(debug)模式下便不会。下面,我们把 i的声明加上volatile关键字,看看有什么效果:#include void main()volatile int i=10;int a = i;printf(i= %dn,a);_asm mov dword ptr ebp-4, 20hint b = i;printf(i= %dn,b);这下你再在调试版本和release版本运行程序,看看输出结果是不是都是:i = 10i = 32估计大家看到这里便会明白了,volatile这个关键字最最主要的意思是做什么的了。在MSDN中

19、volatile是一个限定符,也称为keyword或描述符,volatile 关键字指示字段可由操作系统、硬件或并发执行的线程在程序中进行修改。当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。一般说来,volatile用在如下的几个地方: 1、中断服务程序中修改的供其它程序检测的变量需要加volatile; 2、多任务环境下各任务间共享的标志应该加volatile; 3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能有不同意义;声明方式为volatile dec

20、laration备注系统总是在 volatile 对象被请求的那一刻读取其当前值,即使上一条指令从同一对象请求值。而且,该对象的值在赋值时立即写入。volatile 修饰符通常用于由多个线程访问而不使用 lock 语句来序列化访问的字段。使用 volatile 修饰符能够确保一个线程检索由另一线程写入的最新值。备注部分由MSDN原文所说。本文参考:关于volatile关键字的说明以及测试(作者:iwaswzq)有关volatile (函数前加volatile) 和inline的用法(作者:kobefly)*关键字Const与Volatile的使用关键字const有什么含意? 我只要一听到被面试

21、者说:“const意味着常数”,我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只要能说出const意味着“只读”就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。) 如果应试者能正确回答这个问题,我将问他一个附加的问题: 下面的声明都是什么意思? const int a; int const a; const

22、int *a; int * const a; int const * a const; /*/ 前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字 const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重

23、关键字const呢?我也如下的几下理由: ; 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。) ; 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。 ; 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。 Volatile 8. 关键字volatile有什么含意?并给出三个不同

24、的例子。 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: ; 并行设备的硬件寄存器(如:状态寄存器) ; 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) ; 多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1