如何真正实现PT60的中断嵌套

Document created by K.h. Qin Employee on Nov 11, 2014Last modified by Diana Torres on Feb 28, 2017
Version 4Show Document
  • View in full screen mode

最近在支持几个PT60的家电项目,遇到一个共同的问题,就是程序运行的时候,显示数码管会有不规律的闪烁。

几个项目都是以触摸TSI为核心的,对方工程师反应,如果把TSI的中断关闭就不会有闪烁现象。数码管的扫描程序是在MTIM的中断中完成的,经初步分析推测,应该中断时序错乱导致的问题。

因此我们想着这个应该用中断嵌套的方式可以解决。

中断嵌套的定义简单来说,就是当MCU正在处理一个低优先级的中断的时候,来了一个高优先级的中断,系统此时就会放下低优先级转向去执行高优先级的,完了之后继续回来执行低优先级的。

按照这个逻辑,我们应该只要将各个中断的优先级预先设好就没有问题了。项目一共用了四个中断TSI,RTC(这两个中断组合完成TSI扫描按键,是基于sam之前写的的算法),MTIM(数码管扫描),KBI(用作低功耗唤醒)。

因此,我们把MTIM的优先级设成最高,就应该不会再出现闪烁的现象了,但改完之后,结果依旧失败。

 

经过不断讨论以及查找数据手册,最终实现了,但不得不说PT60实现中断嵌套还是挺麻烦的。

我们一步一步来:

 

1.首先我们来看CPU是执行中断的顺序。其余步骤没有什么特别,关键就在于第2步。

1.jpg

2.我们来看这个I位的作用。当进入某个中断之后,这个I位就会被自动置位,也就是系统将整个interrupts都给关掉了,这么做的原因也就是为了让系统在执行某个中断的时候,不会被其他的中断给干扰打断。

那么这就是为什么我们会中断嵌套失败的根本原因!

2.jpg

3.因此,如果我们需要使用中断嵌套的话,那么就需要在每个中断程序里面添加这个清楚CCR寄存器I位的指令,asm cli。

3.png

4.因为中断嵌套被启用了,有潜在的风险会导致进中断前一些堆栈数据出错或者中断优先级出问题等,那么在中断程序的最后,我们再加一句话,让一切恢复正常就可以了

IPC_SC_PULIPM = 1;

4.png

5.png

 

经过以上步骤,中断嵌套就能够实现了。

 

 

但在这个过程中,遇到了几个问题,也和大家分享下

1.PT60的中断会自己嵌套自己:

6.jpg

手册中有提到,高优先级和同级中断都是可以抢占低优先级的。

我举个例子来说明:

现在有两个中断,1号中断--低优先级0级,2号中断--高优先级1级。 1号中断正在执行的过程中,此时2号中断过来打断了他,系统必然要先把2号中断执行完。之后再回去执行1号中断剩下的部分。但很不巧,此时新的1号中断又来了,就是说上一次的1号中断还没跑完,又被新的1号抢占了,也就是自己嵌套了自己,最后必然导致全部中断的时序都出现了问题。

这是一种潜在的隐患,我们的解决方法就是:让0级的1号中断一开始执行中断程序之后,让其把自身的中断等级提高一级,中断结束的时候在加上上面提到的恢复语句又变回0级。这样的话,我旧的1号中断(1级)还没执行完,新的一号中断(0级)即使来了,也无法抢占,必须乖乖的等着让旧的先执行完。下面这几条语句就是提高中断等级的,我们实验的时候让中断只有0和1级。

8.png

 

2.在执行asm cli指令之前必须要清除中断标志位:

接上,如果不清楚标志位的话就打开asm cli的话,那么系统就一直不断地让这个中断再进,也就是中断自己不断地在嵌套自己,最终把堆栈给压爆了,程序也就跑飞了。

 

东西很简单,但是确实值得注意。

附件是测试的程序,有需要的可以参考。 

Outcomes