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. eclipse设置快捷键sysout+Alt+/后出System.out.println!亲測可用!

    曾经一直用myeclipse,没有这方面的顾虑,如今换到了eclipse,非常多要自己设置了,比方非常多快捷键. 最经常使用的,执行到sysout ,eclipse总是不自己主动补全,非常是恼火!!! ...

  2. 蘑菇街IM

    https://github.com/mogutt TTServer 蘑菇街TeamTalk之消息服务器 Updated 2 days ago   Shell 122 208 TTAutoDeploy ...

  3. CentOS开发环境LAMP搭建

    CentOS开发环境搭建 -------------------------------------------------------------------------准备工作---------- ...

  4. [GIF] GIF Loop Coder - Animating with Arrays

    In this lesson, we discuss animating using arrays, and how different data types are interpolated whi ...

  5. SNMP协议总结

    说明:本文仅供学习交流,转载请标明出处,欢迎转载! SNMP(Simple Network Management Protocal),简单网络管理协议,其前身是SGMP协议(简单网关监控协议),该协议 ...

  6. native为本地方法

    在java中,native方法是指本地方法,当在方法中调用一些不是由java语言写的代码或者在方法中用java语言直接操纵计算机硬件时要声明为native方法. native方法的执行依赖于JVM的设 ...

  7. How does CCFileUTils::fullPathForFilename work

    OverView The purpose of this document is show you how does function CCFileUtils::fullPathForFilename ...

  8. checkbox组件

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  9. 利用Qt制作一个helloworld

    使用QT创建第一个 工程: 1.打开应用程序: 2.单击画面中间偏上的 New Project按钮.[要学习使用啊~,传说它的跨平台行很好,QQ就是用它编辑的.] 3.直接点击右下角的选择 按钮. 4 ...

  10. C#迭代语句

    1,do while语句 do语句重复执行语句或者语句块,直到指定的表达式为false为止.循环体如果为单个语句,可以不放在{}内,如果不是,那么必须放在{}内.如下面的代码 Codeint i=0; ...