在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板子. ...
随机推荐
- Android+OpenCV 摄像头实时识别模板图像并跟踪
通过电脑摄像头识别事先指定的模板图像,实时跟踪模板图像的移动[用灰色矩形框标识] ps:一开始以为必须使用OpenCV Manager,可是这样会导致还需要用户去额外安装一个apk,造成用户体验很差, ...
- Centos下的IO监控与分析
近期要在公司内部做个Linux IO方面的培训, 整理下手头的资料给大家分享下 各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuni ...
- IPv6 neighbor discovery
IPv6 neighbor discovery By stretch | Thursday, August 28, 2008 at 5:03 a.m. UTC Neighbor Discovery P ...
- Cookie中用户登录信息登录验证
public class FormServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpSer ...
- web服务器决定支持多少人同时在线的因素
经常遇到一些做WEB用户咨询服务器支持在线人数问题,在此做个简单介绍.非技术性讨论,如有疏漏或错误,敬请原谅和指导.以普通单路服务器为例,CPU处理多个进程,并非是同一时刻处理的,(可以精确到1/10 ...
- python--class test
# !usr/bin/env python3#-*- coding:utf-8 -*- 'a test class'class Student(object): def __init__(se ...
- Form开发中组件控制的几个常用方法
转自:http://oracleseeker.com/2009/09/01/graphical_component_control_in_oracle_ebs_form/ 在Oracle EBS 的F ...
- Ubuntu14.04服务器安装ftp
随笔记录一下Ubuntu下安装ftp 1.远程连接登录服务器之后,输入sudo apt-get update 并回车.如果不运行该命令,直接安装vsftpd,可能会出现有一些软件包无法下载. 2.输入 ...
- Linux学习新篇——常用命令和快捷键总结
最近刚接触Linux,整理了一些常用的命令和快捷键 Tab补全命令 当命令记不清了,输入记得的前几个用Tab就可以将该命令自动补全. 启动tomcat服务用$startup.sh 停止tomcat服务 ...
- 关于使用json 字符串转换为字典问题
问题背景: '{"backend": "www.baidu.org", "record": {"server": &qu ...