C语言关键字volatile是一个危险的东东,笔者再用ADS做S3C2440定时器中断实验就因为这个关键字出了错。出现错误情况的准确描述是:定义一个变量时没有用volatile关键字,而且紧接着while(1)循环里边就有对这个变量的读操作。

这个实验想实现的功能是:定时时间为1s,用一个led灯显示这个时间,亮一秒钟,然后再灭一秒钟。程序实现思路是:开irq中断,开定时器0中断,并设置定时器0中断时间为1s;在中断服务程序中利用一个全局变量flag来传递定时时间到信号,每中断一次flag翻转一次;主循环中读取flag标志,根据flag标志决定led灯的亮灭。

中断服务程序

void __irq Timer0_Isr(void)
{
flag=!flag;
rSRCPND|=<<;
rINTPND|=<<;
}

flag定义在主程序中

unsigned int flag=;

主循环程序

int Main()
{
IO_Init();
while(){
if(flag){
Led1_Off();
}
else{
Led1_On();
}
}
return();
}

经测试定时1s,中断服务程序都是能正常工作的,但是led不能闪烁,一直亮。试了很多办法,无果。

后来将变量的定义更改了一下,加一个关键字volatile。就解决了问题。但是,什么原因不得而知。

volatile unsigned int flag=;

走投无路的情况下,只能求助于反汇编代码。

对比源程序

对比反汇编(图片太大,网页浏览时无法完全显示,可以对着图片单击右键,选择图片另存为桌面查看)

看到反汇编代码,很容易知道错误出现在哪儿。没加volatile时候,执行while循环需要重新读取flag的值时,不是从flag对应的内存单元中读的,而是读取保存flag临时数据的r2。虽然中断服务程序会将flag值更改,但是由于读取的是r2而且r2在主循环中始终不变,也就是说不能读到中断服务程序对flag的更新,所以led灯也不可能改变。

当加了volatile后,执行while循环需要重新读取flag的值时,是从flag对应的内存单元中读的,所以主循环能读到中断服务程序对flag的更新,led也能正常工作了。

结论:ADS对加没加volatile的变量处理是有区别的,但是我认为ADS对这种情况的处理不是很正确

之所以这样说,我源于下面三个实验。我用keil和gcc分别作了类似上边的实验,看编译器对没有加volatile的变量处理情况,发现这两个编译器都能正确编译,而唯独ADS对没有加volatile的变量处理的过分。

keil对没有加volatile的变量处理

测试程序

反汇编代码

gcc对没有加volatile的变量处理

第三个实验,在 if(flag) 前边加一个delay_time()函数,发现能够正常工作

试想,ADS仅仅因为在 if(flag)前边加了一个delay()函数,就更改了它的策略,我真觉得ADS对这种情况(定义一个变量时没有用volatile关键字,而且紧接着while(1)循环里边就有对这个变量的读操作)处理的有问题。而且,我认为编译器对volatile的处理好像也不是这样的。我对ADS的编译还存在疑惑,我对编译器对volatile的处理还存在疑惑。

附实验源码下载地址:timeirq.zip

在ADS上由于volatile惹得祸的更多相关文章

  1. kindeditor多图片上传找不到action原来是private File upload成员变量惹得祸

    kindeditor多图片上传找不到action原来是private File upload成员变量惹得祸

  2. VPN断线原因解析- ADSL惹的祸

    在我们使用VPN的时候,最讨厌的就是无故的断线了,可能正在和好基友一起副本,或者正在视频热聊中,还或者youtube视频看的正起劲,突然windows一个对话框弹出 - “连接已经断开”.实在是太影响 ...

  3. win7打开或关闭windows功能 提示“出现错误,并非所有的功能被更改”,管理员权限惹的祸

    2013-07-25 18:12:06 最近要用到windows的telnet功能,本来是很简单的事情,因为管理员权限的问题,花了不少时间,才发现是管理员权限惹的祸,更滑稽的是,自己一直以来都不是管理 ...

  4. 都是SCI惹的祸?

    都是SCI惹的祸? 过去只知道地质学家需要跋山涉水寻找宝藏,最近同一位海外归来的学者谈起,方知少数其它领域的科研人员,也"跋山涉水",在内地研究机构寻找可以写好文章的研究成果,不管 ...

  5. 【ipv6惹的祸】curl 超时

    偶然发现 最近在公司日志平台 总是可以看到很多关于php curl的错误信息 Operation timed out after 0 milliseconds with 0 out of 0 byte ...

  6. 【转】VS2013 C#WinForm程序构造界面拖动控件NumericUpDown时"未响应“是有道词典惹的祸

    很久之前遇到过因为金山词霸和其他软件冲突导致的程序无响应的情况. 没想到今天情况重现,VS2013在可视化编辑NumbericUpDown控件的时候,又出现了”未响应“,发现又是有道词典惹的祸. 可见 ...

  7. 都是iconv惹的祸

    今天在做采集的时候发现只取到了网页的部分内容,当时我就郁闷了,之前都用的采集都可以采集到网页的所有内容,但这次死活就取到部分内容.寻找原因才知道原来是iconv惹的祸. 发现问题时,网上搜了搜,才发现 ...

  8. ie8 background css没有显示?——都是空格惹的祸

    ie8 background css没有显示?——都是空格惹的祸

  9. 都是stm32的JTAG引脚惹的祸

    转载请注明出处:http://blog.csdn.net/qq_26093511/article/category/6094215 最近在调试08接口的LED显示屏,使用的是自己做的STM32板子. ...

随机推荐

  1. RHCA学习笔记:RH442-Unit6 磁盘性能调整

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://alansky.blog.51cto.com/634963/654451 UNIT ...

  2. careercup-递归和动态规划 9.2

    9.2 设想有个机器人坐在X*Y网格的左上角,只能向右.向下移动.机器人从(0,0)到(X,Y)有多少种走法? 进阶: 假设有些点为“禁区”,机器人不能踏足.设计一种算法,找到一条路径,让机器人从左上 ...

  3. QT:QBitArray

    QbitArray类提供位操作序列. include<QBitArray> 公有函数: QBitArray ()   QBitArray  ( int  size , bool  valu ...

  4. *.pro、*.pri、*.prf、*.prl等四种文件

      尽管每次和cmake对比起来,我们总是说 qmake 简单.功能少.但是qmake仍然是一个非常复杂的东西,我想大多人应该和我一样吧: 不是太清楚CONFIG等变量到底如何起作用的 用过的qmak ...

  5. netty Architectural Overview --reference

    reference from:http://docs.jboss.org/netty/3.1/guide/html/architecture.html 2.1. Rich Buffer Data St ...

  6. linux cat 命令详解--转

    使用方式:cat [-AbeEnstTuv] [--help] [--version] fileName 说明:把档案串连接后传到基本输出(萤幕或加 > fileName 到另一个档案) 参数: ...

  7. .Net设计模式_工厂模式(2)

    2.工厂方法模式 引言: 上一篇中我们描述了简单工厂的缺点,而解决方法就是把工厂接口化,把工厂的行为标准化,这就是工厂方法模式. 理解: 工厂能制造A和B鞋,如果消费者现在要求制造C鞋.D鞋...咋办 ...

  8. c++静态成员与静态函数

    1 静态成员的定义 1 静态变量 c++在类里面进行的仅是引用性声明,不会为之分配内存,要求必须单独对静态数据成员进行定义性的声明.形式为: 类型 类名::静态数据成员名: 此时的定义需要再加关键字s ...

  9. [Form Builder]Oracle Form系统变量中文版总结大全

    转:http://yedward.net/?id=57 Form中的系统变量,它存在于一个Form的整个运行时期的会话之中,变量包含了有关Form相关属性的字节信息.有些变量标明了当前状态,还有些变量 ...

  10. Java并发——使用Condition线程间通信

    线程间通信 线程之间除了同步互斥,还要考虑通信.在Java5之前我们的通信方式为:wait 和 notify.Condition的优势是支持多路等待,即可以定义多个Condition,每个condit ...