在ADS上由于volatile惹得祸
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惹得祸的更多相关文章
- kindeditor多图片上传找不到action原来是private File upload成员变量惹得祸
kindeditor多图片上传找不到action原来是private File upload成员变量惹得祸
- VPN断线原因解析- ADSL惹的祸
在我们使用VPN的时候,最讨厌的就是无故的断线了,可能正在和好基友一起副本,或者正在视频热聊中,还或者youtube视频看的正起劲,突然windows一个对话框弹出 - “连接已经断开”.实在是太影响 ...
- win7打开或关闭windows功能 提示“出现错误,并非所有的功能被更改”,管理员权限惹的祸
2013-07-25 18:12:06 最近要用到windows的telnet功能,本来是很简单的事情,因为管理员权限的问题,花了不少时间,才发现是管理员权限惹的祸,更滑稽的是,自己一直以来都不是管理 ...
- 都是SCI惹的祸?
都是SCI惹的祸? 过去只知道地质学家需要跋山涉水寻找宝藏,最近同一位海外归来的学者谈起,方知少数其它领域的科研人员,也"跋山涉水",在内地研究机构寻找可以写好文章的研究成果,不管 ...
- 【ipv6惹的祸】curl 超时
偶然发现 最近在公司日志平台 总是可以看到很多关于php curl的错误信息 Operation timed out after 0 milliseconds with 0 out of 0 byte ...
- 【转】VS2013 C#WinForm程序构造界面拖动控件NumericUpDown时"未响应“是有道词典惹的祸
很久之前遇到过因为金山词霸和其他软件冲突导致的程序无响应的情况. 没想到今天情况重现,VS2013在可视化编辑NumbericUpDown控件的时候,又出现了”未响应“,发现又是有道词典惹的祸. 可见 ...
- 都是iconv惹的祸
今天在做采集的时候发现只取到了网页的部分内容,当时我就郁闷了,之前都用的采集都可以采集到网页的所有内容,但这次死活就取到部分内容.寻找原因才知道原来是iconv惹的祸. 发现问题时,网上搜了搜,才发现 ...
- ie8 background css没有显示?——都是空格惹的祸
ie8 background css没有显示?——都是空格惹的祸
- 都是stm32的JTAG引脚惹的祸
转载请注明出处:http://blog.csdn.net/qq_26093511/article/category/6094215 最近在调试08接口的LED显示屏,使用的是自己做的STM32板子. ...
随机推荐
- int& a = b 的思考
在PCL显示点云部分程序中,涉及到了如下程序 // 定义相关变量 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::Point ...
- 在不同平台上CocosDenshion所支持的音频格式
在大多数平台上,cocos2d-x调用不同的SDK API来播放背景音乐和音效.CocosDenshion在同一时间只能播放一首背景音乐,但是能同时播放多个音效. 背景音乐 Platform supp ...
- How to add route for IPV6 interface
Firewall : ifconfig eth1 inet6 add 2000::1/64 ifconfig eth4 inet6 add 5000::1/64 ------------------- ...
- Git使用完全解析(一)
是时候来系统的介绍一下Git了.毫无疑问,Git是目前最优秀的分布式版本控制工具,木有之一,可是我见到的很多人还是不会用,我的老东家每天忍受着SVN带来的痛苦,却迟迟不愿切换到Git上,个人感觉,许多 ...
- Java基础知识强化之IO流笔记56:IO流练习之 登录注册IO版
1. 登录注册IO版的Java项目框架,如下: 2. 具体代码实现: (1)User.java(cn.itcast.game): package cn.itcast.pojo; /** * 这是用户 ...
- openoffice转换过程中遇到繁体字文档转换失败的问题
今天发现上线的文档转换功能中存在一个文档转换不成功,查看后台日志标志文档无法加载成功,提示日志如下: INFO: connected Jul 08, 2015 2:50:33 PM com.artof ...
- Magento模型和ORM基础
对于任何一个MVC架构,模型(Model)层的实现都是占据了很大一部分.对于Magento来说,模型占据了一个更加重要的位置,因为它常常包含了一部分商业逻辑代码(可以说它对,也可以说它错).这些代码在 ...
- jquery处理textarea中的手动换行
textarea的手动换行会产生换行标志,但这个标志存在却看不到,存入数据库中后读出来显示在页面上却不会换行,如何处理呢? 网上众说纷纭,经过测试用 textarea的内容.replace(/\n/g ...
- UIView的frame和bounds区别
UIView的frame和bounds区别 iOS中,大家肯定对view和frame都不陌生,我们设置view在父view中的位置和大小时,只需要设置frame就可以了. 可能大家也有查过网上的一些资 ...
- 使windows server 2003 开机不显示登录页面
1.运行“regedit”,以打开“注册表管理器”:运行注册表编辑器,依次展开[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersi ...