此文为转帖,并稍微编辑了一下。转帖出处就不写了,相信大家也能够找到。最近在使用AT91SAM7X256,搜了一下相关的文章,觉得有意思的就贴在自个的博客里面,就当是备份吧。至于里面的内容是否为真,我也不能确定,仅供参考吧。
太阳之母 发表于 2007-9-20 15:24 ARM 论坛
AT91SAM7A3:虚假中断害我好苦!
嘿嘿
系统中大约有几十个节点,用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()里一开始就关闭了所有中断,为什么这个“虚假中断”还是活的?还没搞明白,呵呵
太阳之母 发表于 2007-9-23 22:47 ARM 论坛
6楼: 嘿嘿
周末回家了
AT91SAM7A3里有个“spurious interrupt”
大概意思是:当某个中断发生了,MCU会自动的去取对应的中断向量,而在取向量的同时,MCU要检查对应的中断是否使能并挂起,这个过程和一般CPU对付中断的过程是类似的,是完全由硬件自动进行的,不同的是:MCU还要去检查一下,这个中断在这么短的时间里,中断条件还满足吗(对应的中断是否使能并挂起)?如果不满足了,就进spurious interrupt了!
打个比方说,MCU正常运行相当于我在睡觉,中断相当于我有上厕所的意识了,可当我进到厕所里,却发现我根本没有上厕所的需求了!!于是我就进了spurious interrupt了!
显然,如果中断是电平触发的,很容易就出这个问题!几乎所有电平触发的中断都可能演变成spurious interrupt。
而在DataSheet中写了:不推荐CAN中断采用边沿触发!!!呵呵,于是我的CAN中断用的就是电平触发,于是就有那个问题了!
文章评论(0条评论)
登录后参与讨论