【嵌入式操作系统-3】Cortex-M7异常模型

异常状态

在Cortex-M7处理器中有四种异常状态

  • 不活跃
    • 异常没有被处理和挂起
  • 挂起
    • 异常发生,等待被CPU处理
  • 活跃
    • 异常正在被CPU处理
  • 活跃和挂起
    • CPU正在处理一个异常,但是还有一个与他相同中断源的异常处于挂起状态

异常类型

异常类型描述
复位异常(Reset)复位异常始终有效,他有一个固定的优先级-3
不可屏蔽中断(NMI)可以由外设发送信号或者软件触发,这是除了复位之外的最高优先级中断
它有一个固定优先级-2,他不可以被其他活跃的异常屏蔽
也不可以被除了复位之外的异常抢占
硬件故障(HardFault)该异常发生于异常处理时出现错误,或者是因为该异常不能被任何其他的异常机制管理
他的优先级固定为-1,意味着它拥有比那些优先级可配置的异常更高的优先级
内存管理错误(MemManage)这是由于内存访问限制,或者MPU设置的内存访问属性造成的错误
这个异常常用于终止在不可执行区域的指令访问
使用故障(UsageFault)这个异常发生和指令执行相关,例如未定义指令,非法的非对齐内存访问
无效的状态和指令执行,异常返回出错,另外还有一些可以配置的的行为也会造成该异常,在未对齐的地址进行半字访问和字访问,除0
SVC这个类似于Linux的系统调用,在带操作系统环境下,使用SVC指令可以触发该异常,用于访问内核资源和设备驱动
PendSVPendSV 是系统级服务的中断驱动请求,在带操作系统环境下,没有其他异常活跃的情况下使用 PendSV 进行上下文切换
SysTick一个向下计数器,当他计数值为0时将触发异常,也可以通过软件触发,在带操作系统的环境下,这个异常可以用作操作系统的系统时钟
Interrupt由于指令或者外设触发的中断,所有外设的中断优先级都是可以配置的,外设通过中断和处理器进行通讯

异常处理程序

类型描述
ISRIRQ0到IRQ239的中断都是由中断服务程序处理,具体的中断号由厂商实现定义
故障处理HardFault、MemManage fault、UsageFault 和 BusFault 都是由故障处理程序处理
系统服务程序NMI、PendSV、SVCall SysTick、均由系统处理程序处理

中断向量表

在这里插入图片描述
在内部引导程序运行期间使用的中断向量表从0x00000000开始,运行用户程序时,中断向量表的地址由用户决定,例如ST的固件库就是将中断向量表存放于0x8000000。

中断优先级

上图中的中断向量表中所有异常都有优先级:

  • 优先级的数字越低代表优先级越高
  • 除了复位异常,故障异常,不可屏蔽中断他们的优先级不可更改,其他的优先级都可以改。

如果软件没有设置优先级,那么所有优先级可配置的异常的优先级都为0。

优先级的最大可配置范围是0-255,实际可用的配置发范围是由实现定义的,这意味着优先级固定为负数的复位异常,故障异常,不可屏蔽中断他们的优先级总是比其他的异常更高。

中断优先级分组

为了在有中断的系统中增加优先级控制,NVIC支持优先级分组。这将每个中断优先级寄存器输入分为两个区域:

  • 高位部分代表组优先级
  • 低位部分在组内定义一个子优先级

只有组优先级会影响到中断抢占,当处理器正在执行一个中断处理程序时,发生另外一个中断,这个中断的组优先级和当前正在处理的中断是相同的,此时不会发生抢占。

如果多个挂起的中断具有相同的组优先级,则子优先级将确定处理它们的顺序。如果多个挂起中断具有相同的组优先级和子优先级,则首先处理中断号最低的中断。

异常和返回

抢占

当处理器正在处理一个异常时,该异常可以被一个更高优先级的异常抢占,这种情况叫做异常嵌套。

异常返回

发生于下面两种情况:

  • 异常处理完成,并且没有正在挂起且优先级够高的异常时。
  • 异常处理已完成,并且没有后到达还未处理的异常。
    处理器从栈上恢复进入中断之前的状态。

Tail-chaining

这种机制加快了异常服务的速度, 在完成一个异常处理程序后,如果有一个处于挂起状态且满足进入异常处理的条件,堆栈弹出将被跳过,控制权将被转移到新的异常处理程序。

Late-arriving

这种机制加速了抢占, 如果在先前异常在状态保存期间有更高优先级的异常发生,处理器将处理更高优先级的异常并从中断向量获取异常处理程序。 状态保存不受影响,状态保存是对这两个异常都是相同的, 因此状态保存不会被打断。 处理器可以接受迟到的异常,直到原有异常的异常处理程序的第一条指令进入处理器的执行阶段。

异常进入

  1. 当一个异常有足够的优先级,并且满足下面其中一个条件:

    • 处理器运行于线程模式
    • 新的异常比原来的异常优先级更高,这种情况下新的异常会抢占原有异常。
  2. 当一个异常抢占另一个异常,这种情况下异常是嵌套的。

  3. 当一个异常拥有更高的优先级,意味着异常屏蔽寄存器对它的限制越小,如果新的异常优先级低于被挂起的异常,那么他不会被处理器响应。

当处理器处理一个异常时,会把当前的信息放到栈上,这个操作叫做入栈,由8个字组成的数据结构叫做栈帧。

使用浮点例程时,Cortex-M7 处理器在入栈时将自动把该架构的浮点状态入栈,下图展示了Cortex-M7 处理器发生中断或者异常时的堆栈帧布局。
在这里插入图片描述
栈帧中包含了异常返回地址,该地址是被中断程序的下一条指令地址,当异常返回后,该地址将恢复到PC中,被中断的程序继续执行。

在入栈的同时,处理器从中断向量表中查找到异常处理程序的地址,入栈完成后,处理器开始执行异常处理程序,与此同时,处理器将会写入一个EXC_RETURN值到LR寄存器中,该值表明哪个栈指针与栈帧一致,以及在中断发生之前处理器处于什么操作模式。

异常返回

异常返回发生在Handler模式,并且执行了以下指令将EXC_RETURN放入PC寄存器中:

  • 一条LDM或者POP指令加载到PC中
  • 一条LDR指令,PC作为目的寄存器
  • 使用任何寄存器执行BX指令

EXC_RETURN是异常进入时放入到LR中的值,异常处理机制依赖于该值来检测处理器何时完成了异常处理,该值的最低5位提供了返回时的栈信息和处理器模式。

EXC_RETURN的5到31位全为1,当这个值被加载到处理器中时,表面处理器已经完成了异常处理。
在这里插入图片描述

故障处理

故障是异常的一个子集,它通常由下面几个原因造成

  • 总线错误
  • 由内部侦测到的错误,例如未定义指令
  • 试图在一个不可执行的内存区域执行指令
  • 如果您的设备包含MPU,违反了对应的权限或试图访问一个不受管理的区域将导致MPU故障(例如使用外部的SDRAM但是没有通过MPU为该区域设定权限,会导致HardFault)
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

咕咚.萌西

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

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

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

打赏作者

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

抵扣说明:

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

余额充值