深入理解 Cortex-M 处理器中异常与中断的优先级

对于 Cortex-M 处理器(包括 ARMv6-M 和 ARMv7-M)异常是否能被处理器接受以及何时被处理器接受并执行异常处理,是由异常的优先级和处理器当前的优先级决定的。更高优先级的异常(优先级编号更小)可以抢占低优先级的异常(优先级编号更大),这就是异常/中断嵌套的情形。有些异常(复位,NMI 和 HardFault)具有固定的优先级,其优先级由负数表示,这样,它们的优先级就会比其他的异常要高。其他异常则具有可编程的优先级,范围为 0 ~ 255。

Cortex-M3 和 Cortex-M4 处理器在设计上具有 3 个固定的最高优先级以及 256 个可编程优先级(具有 128 个抢占等级)。可编程优先级的实际数量由芯片设计商决定。多数 Cortex-M3 或 Cortex-M4 芯片支持的优先级较少,如 8/16/32 等。这是因为大量的优先级会增加 NVIC 的复杂度,也会增加功耗且降低速度。多数情况下,应用程序只需少量的编程优先级。因此,芯片设计人员需要基于目标应用的优先级数量定制处理器设计。优先级的减少是通过去除优先级配置寄存器的最低位(LSB)实现的。

中断优先级由优先级寄存器控制,宽度为 3~8 位。例如,若设计中只实现了 3 位优先级,优先级配置寄存器就如下图所示:

图片

对于上图的示例,由于第 0~4 位没有实现,它们读出来总是为 0,对这些位的写操作会被忽略。根据这种设置,可能的优先级为 0x00(高优先级)、0x20、0x40、0x60、0x80、0xA0、0xC0 以及 0xE0(最低)。

类似的,如果设计中实现了 4 位优先级,就会得到 16 个可编程的优先级:

图片

以上两个位宽的优先级实现等级如下图所示:

图片

实际使用的位数越多,可用的优先级就越多。不过,优先级位数增多也意味着芯片内部的逻辑门数增多,进而增加芯片的功耗。对于 ARMv7-M 架构,宽度最少为 3 位( 8 个等级)。对于 Cortex-M3 和 Cortex-M4 处理器,所有优先级寄存器的复位值都为 0 。

上文中提到优先级的减少是通过去除优先级配置寄存器的最低位(LSB)实现的,之所以这里是移除最低位(LSB)而不是最高位(MSB),是因为这样处理可以使 Cortex-M 处理器间的软件移植工作更容易。

若一个在具有 4 位优先级配置寄存器的设备上运行的程序要想移植到一个具有 3 位优先级配置寄存器的设备,如果移除的是 MSB 而不是 LSB,则此时的优先级配置可能会相反。例如,对于某些应用程序,IRQ#0 的优先级为 0x05,而 IRQ#1 的优先级为 0x03,此时 IRQ#1 的优先级更高。但当移除了最高位 bit 2,则 IRQ#0 优先级会变为 0x01,比 IRQ#1 的优先级还要高!

以下是一个具有 3 位、5 位和 8 位优先级寄存器对应的示例:

图片

这里可能会有个疑问:为什么优先级配置寄存器为 8 位宽时,只有 128 个抢占等级?

这是因为 8 位寄存器会被进一步分为两个部分:分组优先级和子优先级(注:早期的技术参考手册会将分组优先级称为抢占优先级)。

利用系统控制块(SCB)中的一个名为优先级分组的配置寄存器(后续文章会讲到),每个具有可编程优先级的优先级配置寄存器可被分为两个部分。上半部分(左边的位)为分组(抢占)优先级,而下半部分(右边的位)则为子优先级,如下图所示:

图片

在处理器已经在运行一个中断处理时能否产生另外一个中断,是由该中断的抢占优先级决定的。子优先级只会用于具有两个相同分组优先级的异常同时产生的情形,此时,具有更高子优先级(数值更少)的异常会被优先处理。

软件可以通过下表所示的 CMSIS-Core 函数来访问优先级组的设置,以及获取其相关信息:

图片

注意,NVIC_DecodePriority 的结果由修改 *pPreemptPriority 以及 *pSubPriority 这两个指针所指向的数值后得到。

由于优先级分组的存在,分组(抢占)优先级的最大宽度为 7,因此也就有了 128 个等级。若优先级分组被设置为 7,所有具有可编程优先级的异常就会处于相同的等级,这些异常间就不会产生抢占。而 HardFault、NMI 和 复位是例外,因为他们的优先级分别为 -1,-2 和 -3,因此可以抢占上述可编程优先级的异常。

在确定实际的分组优先级和子优先级时,必须要考虑以下因素:

  • 实际的优先级配置寄存器

  • 优先级分组设置

例如,若配置寄存器的宽度为 3 (第 7 ~ 5 位可用)且优先级分组为 5,则会有 4 个分组/抢占优先级(第 7 ~ 6 位),而且每个分组/抢占优先级具有两个子优先级,如下图所示:

图片

按照上图的设置,可用的子优先级就如下图所示:

图片

对于相同的设计,若优先级分组为 0x01,则只会有 8 个分组优先级,且每个抢占等级中没有进一步的子优先级(优先级寄存器的 bit[1:0] 此时总是为 0)。优先级配置寄存器的定义如下图:

图片

其可用等级如下图:

图片

若 Cortex-M3/M4 实现了优先级配置寄存器中的所有 8 位,则它所具有的抢占等级最大只会是 128,此时优先级分组为 0。其优先级域定义如下图所示:

图片

若两个中断同时被确认,且它们拥有相同的分组/抢占优先级和子优先级,则异常编号更小的中断的优先级更高(IRQ#0 的优先级高于 IRQ#1)。

最后要注意,为了避免中断优先级被意外修改,在写入应用中断和复位控制寄存器(地址为 0xE000ED0C)时要非常小心。多数情况下,在配置了优先级分组后,若不是要产生一次复位,就不要再使用这个寄存器了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WKJay_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值