AT91SAM7A3:虚假中断害我好苦!

[复制链接]
3818|7
 楼主| 太阳之母 发表于 2007-9-20 15:24 | 显示全部楼层 |阅读模式
嘿嘿<br />系统中大约有几十个节点,用CAN连接,主控用AT91SAM7A3(内部带两个CAN接口),从节点用51+SJA1000。<br /><br />AT91SAM7A3用IAR开发环境,初始化代码来自于TAMEL网站上的样例,用了两个文件:汇编的Cstartup.s79&nbsp;和C语言的Cstartup_SAM7.c。<br />51用KEIL开发环境。<br /><br />主控运行时打开看门狗,CAN通信按常规用中断方式接收,随机性的发生看门狗复位(间隔时间不定,数十分钟或几天,施加频繁的人为干扰,几分钟就复位),改查询方式接收则没问题(但可能丢失CAN数据!!),初步判断中断出问题了。<br /><br />反复修改CAN的初始化代码和中断服务代码,无效。<br />在main()函数中首先关闭全部中断,然后仅仅打开CAN中断,无效。<br /><br />查AT91SAM7A3的初始化代码,发现有个平时没有怎么留意的所谓“虚假中断”,仔细看数据手册,强烈怀疑CAN中断出问题和这个“虚假中断”有关!<br /><br />“虚假中断”的中断服务代码是用汇编写的一个死循环:<br />AT91F_Spurious_handler&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;AT91F_Spurious_handler<br /><br />而在初始化代码C语言部分(文件Cstartup_SAM7.c)中,初始化了虚假中断的中断服务函数:<br />&nbsp;&nbsp;&nbsp;&nbsp;AT91C_BASE_AIC-&gtAIC_SPU&nbsp;=&nbsp;(int)AT91F_Spurious_handler;<br /><br />其它中断也是这样:初始化以后默认的服务代码都是一个死循环,因为我后面把不用的中断都关闭了,而且也没有这样的中断事件发生,所以改不改就无所谓了<br /><br />改虚假中断服务代码,在Cstartup_SAM7.c文件中写一个函数:<br />void&nbsp;AT91F_Spurious_handler_C()&nbsp;<br />{}<br /><br />将Cstartup_SAM7.c文件中的&nbsp;AT91C_BASE_AIC-&gtAIC_SPU&nbsp;=&nbsp;(int)AT91F_Spurious_handler;<br />改为&nbsp;AT91C_BASE_AIC-&gtAIC_SPU&nbsp;=&nbsp;(int)AT91F_Spurious_handler_C;<br /><br />恢复系统(让看门狗工作,以中断方式做CAN接收),运行正常。用ZLG的蓝盒子(USBCAN-II)当干扰源,反复连续发送数据,系统工作正常。<br /><br />基本可以确定:问题解决了!<br /><br />体会:<br />1、样例代码一定要仔细看,结合项目的要求,仔细修改。<br />2、没有用到的资源或者似乎与应用无关的问题,很可能影响系统运行,比如这里的虚假中断,原以为跟系统没什么关系,因为总觉得:中断需要有触发条件,我不给你这个条件,中断就不会发生,后来才知道:在AT91SAM7A3里,所有的中断都有可能“和平演变成”虚假中断!!!某些情况下,这种和平演变的几率还很大(几分钟一次)!<br />3、中断实在是个好玩意儿!呵呵<br />4、我明明在main()里一开始就关闭了所有中断,为什么这个“虚假中断”还是活的?还没搞明白,呵呵<br /><br /><br />
multiice 发表于 2007-9-20 15:50 | 显示全部楼层

中断真的关闭了,不可能进入,芯片没有这么脆弱

  
 楼主| 太阳之母 发表于 2007-9-20 15:58 | 显示全部楼层

嘿嘿

我的main()函数:<br />void&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;AT91C_BASE_AIC-&gtAIC_IDCR=0xffffffff;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//关闭所有中断<br />&nbsp;&nbsp;&nbsp;&nbsp;AT91C_BASE_AIC-&gtAIC_ICCR=0xffffffff;&nbsp;//清除可能处于挂起状态的所有中断<br />&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;...<br />}
 楼主| 太阳之母 发表于 2007-9-20 16:37 | 显示全部楼层

嘿嘿

仔细看了一下,“虚假中断”不是真正的中断,所以是无法关掉的!
阿南 发表于 2007-9-20 19:05 | 显示全部楼层

楼主可否详细介绍这个“虚假中断”,

能否仿真跟踪进入“虚假中断”(特别是关中断禁止情况下),能否找出进入“虚假中断”的原因(因为从您的帖子中感觉出您自己还是有些模糊)。<br /><br /><br />中断也有可能是在进入main()函数之前产生。或是禁止中断之前,已有中断标志位置位
 楼主| 太阳之母 发表于 2007-9-23 22:47 | 显示全部楼层

嘿嘿

周末回家了<br />AT91SAM7A3里有个“spurious&nbsp;interrupt”<br />大概意思是:当某个中断发生了,MCU会自动的去取对应的中断向量,而在取向量的同时,MCU要检查对应的中断是否使能并挂起,这个过程和一般CPU对付中断的过程是类似的,是完全由硬件自动进行的,不同的是:MCU还要去检查一下,这个中断在这么短的时间里,中断条件还满足吗(对应的中断是否使能并挂起)?如果不满足了,就进spurious&nbsp;interrupt了!<br /><br />打个比方说,MCU正常运行相当于我在睡觉,中断相当于我有上厕所的意识了,可当我进到厕所里,却发现我根本没有上厕所的需求了!!于是我就进了spurious&nbsp;interrupt了!<br /><br />显然,如果中断是电平触发的,很容易就出这个问题!几乎所有电平触发的中断都可能演变成spurious&nbsp;interrupt。<br /><br />而在DataSheet中写了:不推荐CAN中断采用边沿触发!!!呵呵,于是我的CAN中断用的就是电平触发,于是就有那个问题了!<br /><br />
dld2 发表于 2007-9-24 07:42 | 显示全部楼层

喜欢生动比喻

我有上厕所意识了。
again_gyf 发表于 2007-9-25 23:29 | 显示全部楼层

楼主给了我很多需要注意的东东!

很受用!谢谢!希望有什么好经验分享下哦!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

223

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部