首先我们看到ARBITER2寄存器管理的该组中断里包括了6个中断,分别是INT_TIMER0,INT_TIMER1,INT_TIMER2,INT_TIMER3,INT_TIMER4,INT_UART2,她们的默认中断请求号分别为REQ0,REQ1,REQ2,REQ3,REQ4,REQ5。我们先看PRIORITY寄存器中的ARB_SEL2,该参数由两个位组成,初始值为00。从该表可以看出00定义了一个顺序 0-1-2-3-4-5 ,这个顺序就是这组中断组的优先级排列,这个顺序指明了以中断请求号为0(REQ0)的INT_TIMER0具有最高的中断优先级,其次是INT_TIMER1,INT_TIMER2…。假设现在ARB_SEL2的值被我们设置为01。则一个新的优先级次序将被使用,01对应的优先级次序为0-2-3-4-1-5,从中可以看出优先级最高和最低的中断请求和之前没有变化,但本来处于第2优先级的INT_TIMER1中断现在变成了第5优先级。从ARB_SEL2被设置为00,01,10,11各个值所出现的情况我们可以看出,除最高和最低的优先级不变以外,其他各个中断的优先级其实是在做一个旋转排列(rotate)。为了达到对各个中断平等对待这一目标,我们可以让优先级次序在每个中断请求被处理完之后自动进行一次旋转,如何自动让它旋转呢?我们可以通过ARB_MODE2达到这个目的,该参数只有1个 bit,置1代表开启对应中断组的优先级次序旋转,0则为关闭。事实上当该位置为1之后,每处里完某个组的一个中断后,该组的ARB_SEL便递增在1(达到11后恢复为00)。
现在我们另ARB_MODE2=1,ARB_SEL2=00
则当前ARBITER2的优先级顺序为0-1-2-3-4-5,假设现在该组的1号中断请求INT_TIMER1和2号中断请求INT_TIMER2被同时触发,CPU根据优先级判断后决定先把INT_TIMER1中断向ARBITER6进行发送(在ARBITER6做第最终优先级判断),接着再向ARBITER6发送INT_TIMER2中断。请注意,在INT_TIMER1被处理完毕后,该组中段的优先级次序被自动做了一次旋转,旋转后ARBITER2的优先级顺序变为0-2-3-4-1-5。假设之后某个时刻该组的INT_TIMER1和INT_TIMER2又被同时触发,则此时CPU优先处理的会是INT_TIMER2。若我们另ARB_MODE2=0,则改组的中断优先级次序在任何情况下都不做任何改变,除非我们人为地重新设置了ARB_SEL2的值。
呼。。。好累。。。终于说完了麻烦的优先级-_-…
继续。。。
INTPND 寄存器可能是整个中断处理过程中我们要特别注意的一个寄存器了,他的操作比较特别,怎么特别?请听我慢慢道来.:]
先看一下该寄存器各位详细功能列表
正如你所见的,INTPND 寄存器与SRCPND长得一模一样,但他们在中断异常处理中却扮演着不同的角色,如果说SRCPND是中断信号进入中断处理模块后所经过的第一个场所的话,那么INTPND 则是中断信号在中断处理模块里经历的最后一个寄存器。它的每个位对应一个中断请求,若该位被置1,则表示相应的中断请求被触发,描述到这里你可能会发现它不仅和SRCPND长得一模一样,就连功能都一样,其实不然,他们在功能上有着重大的区别。SRCPND是中断源引脚寄存器,某个位被置1表示相应的中断被触发,但我们知道在同一时刻内系统可以触发若干个中断,只要中断被触发了,SRCPND的相应位便被置1,也就是说SRCPND 在同一时刻可以有若干位同时被置1,然而INTPND则不同,他在某一时刻只能有1个位被置1,INTPND 某个位被置1(该位对应的中断在所有已触发的中断里具有最高优先级且该中断没有被屏蔽),则表示CPU即将或已经在对该位相应的中断进行处理。于是我们可以有一个总结:SRCPND说明了有什么中断被触发了,INTPND说明了CPU即将或已经在对某一个中断进行处理。
特别注意:每当某一个中断被处理完之后,我们必须手动地把SRCPND/SUBSRCPND , INTPND三个寄存器中与该中断相应的位由1设置为0,刚才我说INTPND的操作很特别,它的特别之处就在于对当我们要把该寄存器中某个值为1的位设置为0时,我们不是往该位置0,而是往该位置1。假设SRCPND=0x00000003,INTPND=0x00000001,该值说明当前0号中断和1号中断被触发,但当前正在被处理的是0号中断,处理完毕后我们应该这样设置INTPND和SRCPND:
SRCPND=0x00000002 //位0被置为0
INTPND =0x00000001 //位0被置为0(方法是往该位写入1)
INTOFFSET寄存器的功能则很简单,它的作用只是用于表明哪个中断正在被处理。下面是该寄存器各位详细功能列表
若当前INT_TIMER0被触发了,则该寄存器的值为10,以此类推。
现在我把整个中断流程用一个图加以说明
以上这个图清楚地说明了一个中断异常处理流程。
下面我用INT_TIMER0, INT_TIMER2和INT_UART0三个中断完整地介绍一次中断异常处理。首先我们得做几个假设:
- 假设1:这三个中断的屏蔽被取消。
- 假设2:PRIORITY寄存器中ARB_MODE2,ARB_MODE5皆为0,既不进行优先级的自动旋转排序,任何时候ARBITER2,ARBITER5控制的中断组优先级次序分别为0-1-2-3-4-5和1-2-3-4。
- 假设3:这三个中断皆为IRQ类型。
- 假设4:这三个中断同时被触发。
INT_TIMER0, INT_TIMER2和INT_UART0三个中断被同时触发,此时三个中断信号流向SRCPND寄存器,使该寄存器中的第10位,12位,28位被置为1,中断信号继续向前流经INTMASK 寄存器,这三个中断都没有被屏蔽,于是信号进一步流经INTMODE寄存器,这三个中断皆为IRQ类型,故中断信号继续向前流向PRIORITY寄存器,经过优先级判断,INT_TIMER0中断信号使INTPND 寄存器的第10位置1(INT_TIMER0优先级最高),此时INTOFFSET 寄存器的值为10,CPU转向相应的中断服务例程进行处理。处理完毕后,我们的程序将INTPND和SRCPND的第10置为0,至此INT_TIMER0中断处理完毕。此时SRCPND 的第12位,28位仍为1(这两个中断请求未被处理),故他们会继续被CPU已刚才描述的方式进行处理。
中断异常处理就先讲到这吧 :]