以下是《中断控制(Interrupt).pdf》中的关于中断优先分组(Interrupt priority grouping)的介绍。ARMCortex-M3处理器内核可以配置的中断优先级最多可以有256级。虽然Stellaris系列ARM只实现了8个中断优先级,但对于一个实际的应用来说已经足够了。在较为复杂的控制系统中,中断优先级的设置会显得非常重要。
函数IntPrioritySet()和IntPriorityGet( )用来管理一个片内外设的优先级。当多个中断源同时产生时,优先级最高的中断首先被处理器响应并得到处理。正在处理较低优先级中断时,如果有较高优先级的中断产生,则处理器立即转去处理较高优先级的中断。正在处理的中断不能被同级或较低优先级的中断所打断。
函数IntPriorityGroupingSet( )和IntPriorityGroupingGet( )用来管理抢占式优先级和子优先级的分组设置,参见表1和表2的描述。
重要规则:多个中断源在它们的抢占式优先级相同的情况下,子优先级不论是否相同,如果某个中断已经在服务当中,则其它中断源都不能打断它(可以末尾连锁);只有抢占式优先级高的中断才可以打断其它抢占式优先级低的中断。
由于Stellaris系列ARM只实现了3个优先级位,因此实际有效的抢占式优先级位数只能设为0~3位。如果抢占式优先级位数为3,则子优先级都是0,实际上可嵌套的中断层数是8层;如果抢占式优先级位数为2,则子优先级为0~1级,实际可嵌套的层数为4层;依次类推,当抢占式优先级位数为0时,实际可嵌套的层数为1层,即不允许中断嵌套。
表1 函数IntPriorityGroupingSet( ) 功能
| 设置中断控制器的优先级分组
| 原型
| void IntPriorityGroupingSet(unsigned longulBits)
| 参数
| ulBits:指定抢占式优先级位的数目,取值0~7,但对Stellaris系列ARM取值3~7效果等同
| 返回
| 无
|
表2 函数IntPriorityGroupingGet( ) 功能
| 获取中断控制器的优先级分组
| 原型
| unsigned long IntPriorityGroupingGet(void)
| 参数
| 无
| 返回
| 抢占式优先级位的数目,范围0~7,但对Stellaris系列ARM返回值是3~7效果等同
| 我看完之后尤其不明白其中的“由于Stellaris系列ARM只实现了3个优先级位”是指3个优先等级,还是什么?如果是指3个优先等级的话,岂不是和“Stellaris系列ARM只实现了8个中断优先级”相矛盾?
对此,《DS-LM3S1138-11108》2.5.6章节明确写道:
为了增强系统控制中断的能力,NVIC支持优先级分组,将中断优先级寄存器入口分为两个区域:
l一个定义了分组后的组别所对应优先级的上层区域。
l一个定义了各组中的子优先级的下层区域。
中断异常的抢占仅仅是由组优先级决定的,也就是所谓的上层区域。当处理器正在运行中断异常1的处理程序时,另外一个具有相同的组优先级的中断异常2产生了,那么中断异常2将不会抢占中断异常1。
如果组优先级相同的两个中断异常同时被挂起,那么他们的处理顺序是由子优先级决定的,并且他们之间不能发生嵌套,即抢占,只能等一个执行完毕后才能执行另一个。
如果组优先级和子优先级都相同,那么中断异常将按照中断向量表中中断号的顺序从小到大依次被处理。
可以总结出:组优先级高的(即值小,如1的优先级高于2)才能抢占组优先级低的中断异常;组优先级相同的中断异常之间不能相互抢占。因此这里的组优先级即为上文提到的抢占式优先级,而子优先级就是所谓的下层区域,即分组后组内中断异常的优先等级。
有了对抢占式优先级和子优先级的认识后,我们再来看《DS-LM3S1138-11108》P120中关于优先级分组的配置。
NVIC寄存器APINT中的[10:8]为用来配置组优先级和子优先级的可配置范围,其取值与对应关系见表3。PRIGROUP区域设置不同的值对应中断优先级寄存器PRIx中[7:5]位的二进制格式划分点的位置不同,从而选择不同的组优先级和子优先级。
表3 中断分组的组优先级和子优先级的配置 PRIGROUP区域a
| 二进制格式b
| 组优先级区域
| 子优先级区域
| 组优先级可配置范围
| 子优先级可配置范围
| 0x00~0x04
| Bxxx.
| [7:5]
| 无
| 0~7
| 0
| 0x05
| Bxx.y
| [7:6]
| [7]
| 0~3
| 0~1
| 0x06
| Bx.yy
| [7]
| [7:6]
| 0~1
| 0~3
| 0x07
| B.yyy
| 无
| [7:5]
| 0
| 0~7
| a:NVIC寄存器APINT中[10:8]位的取值
b:x表示用来控制组优先级可配置范围的二进制位,y表示用来控制子优先级可配置范围的二进制位,小数点为划分位置
理解了中断优先级分组的过程后,显而易见本文开头提出的问题:“由于Stellaris系列ARM只实现了3个优先级位”是指3个优先等级,还是什么?明显这个“3个优先级位”是指中断优先级寄存器PRIx中[7:5]这3位二进制位,23=8正好是最多能设置8个中断抢占等级,与前面的“Stellaris系列ARM只实现了8个中断优先级”也对应起来了,这样问题就迎刃而解了!。 |