打印

AT91SAM7A3:虚假中断害我好苦!

[复制链接]
3083|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
太阳之母|  楼主 | 2007-9-20 15:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
嘿嘿
系统中大约有几十个节点,用CAN连接,主控用AT91SAM7A3(内部带两个CAN接口),从节点用51+SJA1000。

AT91SAM7A3用IAR开发环境,初始化代码来自于TAMEL网站上的样例,用了两个文件:汇编的Cstartup.s79 和C语言的Cstartup_SAM7.c。
51用KEIL开发环境。

主控运行时打开看门狗,CAN通信按常规用中断方式接收,随机性的发生看门狗复位(间隔时间不定,数十分钟或几天,施加频繁的人为干扰,几分钟就复位),改查询方式接收则没问题(但可能丢失CAN数据!!),初步判断中断出问题了。

反复修改CAN的初始化代码和中断服务代码,无效。
在main()函数中首先关闭全部中断,然后仅仅打开CAN中断,无效。

查AT91SAM7A3的初始化代码,发现有个平时没有怎么留意的所谓“虚假中断”,仔细看数据手册,强烈怀疑CAN中断出问题和这个“虚假中断”有关!

“虚假中断”的中断服务代码是用汇编写的一个死循环:
AT91F_Spurious_handler  
                     b AT91F_Spurious_handler

而在初始化代码C语言部分(文件Cstartup_SAM7.c)中,初始化了虚假中断的中断服务函数:
    AT91C_BASE_AIC->AIC_SPU = (int)AT91F_Spurious_handler;

其它中断也是这样:初始化以后默认的服务代码都是一个死循环,因为我后面把不用的中断都关闭了,而且也没有这样的中断事件发生,所以改不改就无所谓了

改虚假中断服务代码,在Cstartup_SAM7.c文件中写一个函数:
void AT91F_Spurious_handler_C() 
{}

将Cstartup_SAM7.c文件中的 AT91C_BASE_AIC->AIC_SPU = (int)AT91F_Spurious_handler;
改为 AT91C_BASE_AIC->AIC_SPU = (int)AT91F_Spurious_handler_C;

恢复系统(让看门狗工作,以中断方式做CAN接收),运行正常。用ZLG的蓝盒子(USBCAN-II)当干扰源,反复连续发送数据,系统工作正常。

基本可以确定:问题解决了!

体会:
1、样例代码一定要仔细看,结合项目的要求,仔细修改。
2、没有用到的资源或者似乎与应用无关的问题,很可能影响系统运行,比如这里的虚假中断,原以为跟系统没什么关系,因为总觉得:中断需要有触发条件,我不给你这个条件,中断就不会发生,后来才知道:在AT91SAM7A3里,所有的中断都有可能“和平演变成”虚假中断!!!某些情况下,这种和平演变的几率还很大(几分钟一次)!
3、中断实在是个好玩意儿!呵呵
4、我明明在main()里一开始就关闭了所有中断,为什么这个“虚假中断”还是活的?还没搞明白,呵呵


相关帖子

沙发
multiice| | 2007-9-20 15:50 | 只看该作者

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

使用特权

评论回复
板凳
太阳之母|  楼主 | 2007-9-20 15:58 | 只看该作者

嘿嘿

我的main()函数:
void main()
{
    AT91C_BASE_AIC->AIC_IDCR=0xffffffff;                   //关闭所有中断
    AT91C_BASE_AIC->AIC_ICCR=0xffffffff; //清除可能处于挂起状态的所有中断
    ... ...
}

使用特权

评论回复
地板
太阳之母|  楼主 | 2007-9-20 16:37 | 只看该作者

嘿嘿

仔细看了一下,“虚假中断”不是真正的中断,所以是无法关掉的!

使用特权

评论回复
5
阿南| | 2007-9-20 19:05 | 只看该作者

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

能否仿真跟踪进入“虚假中断”(特别是关中断禁止情况下),能否找出进入“虚假中断”的原因(因为从您的帖子中感觉出您自己还是有些模糊)。


中断也有可能是在进入main()函数之前产生。或是禁止中断之前,已有中断标志位置位

使用特权

评论回复
6
太阳之母|  楼主 | 2007-9-23 22:47 | 只看该作者

嘿嘿

周末回家了
AT91SAM7A3里有个“spurious interrupt”
大概意思是:当某个中断发生了,MCU会自动的去取对应的中断向量,而在取向量的同时,MCU要检查对应的中断是否使能并挂起,这个过程和一般CPU对付中断的过程是类似的,是完全由硬件自动进行的,不同的是:MCU还要去检查一下,这个中断在这么短的时间里,中断条件还满足吗(对应的中断是否使能并挂起)?如果不满足了,就进spurious interrupt了!

打个比方说,MCU正常运行相当于我在睡觉,中断相当于我有上厕所的意识了,可当我进到厕所里,却发现我根本没有上厕所的需求了!!于是我就进了spurious interrupt了!

显然,如果中断是电平触发的,很容易就出这个问题!几乎所有电平触发的中断都可能演变成spurious interrupt。

而在DataSheet中写了:不推荐CAN中断采用边沿触发!!!呵呵,于是我的CAN中断用的就是电平触发,于是就有那个问题了!

使用特权

评论回复
7
dld2| | 2007-9-24 07:42 | 只看该作者

喜欢生动比喻

我有上厕所意识了。

使用特权

评论回复
8
again_gyf| | 2007-9-25 23:29 | 只看该作者

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

很受用!谢谢!希望有什么好经验分享下哦!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

223

帖子

1

粉丝