问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Cortex-M3处理器异常处理机制详解

创作时间:
作者:
@小白创作中心

Cortex-M3处理器异常处理机制详解

引用
CSDN
1.
https://m.blog.csdn.net/weixin_40167339/article/details/139241991

Cortex-M3处理器的异常处理机制是嵌入式系统开发中的核心技术之一。本文将深入探讨Cortex-M3的异常类型、优先级管理、向量表结构以及各种故障处理机制,帮助开发者更好地理解和应用这一处理器架构。

异常和中断

异常和中断是一个重要的过程:当CPU内部或外部出现需要处理的事件(中断源)时,会暂停当前正在执行的程序(断点),转去执行中断服务程序,处理完成后返回断点继续执行。其基本流程如下:

虽然异常和中断的处理过程相似,但通常将CPU内部产生的中断称为异常,外部控制器产生的中断称为中断。本文将统一使用"异常"这一术语。

异常类型

Cortex-M3内核支持多种系统异常和外部中断。编号1-15对应系统异常,大于等于16的则为外部中断。除了少数异常的优先级固定外,其他异常的优先级都是可编程的。

Cortex-M3内核通过NVIC(嵌套向量中断控制器)来管理中断,其中VECTACTIVE位段和IPSR寄存器记录了当前正在处理的异常编号。

优先级定义

在Cortex-M3中,优先级对于异常处理至关重要。优先级数值越小,优先级越高。系统预设了三个高优先级异常:复位、NMI(不可屏蔽中断)和硬故障,它们的优先级固定且高于其他所有异常。

Cortex-M3支持最多256级优先级,但实际应用中通常会精简设计,支持8级、16级或32级优先级。优先级被分为抢占优先级和亚优先级两部分,通过应用程序中断及复位控制寄存器(AIRCR)中的优先级组位段进行配置。

例如,如果使用3位来表达优先级,则可用的8个优先级为:0x00(最高)、0x20、0x40、0x60、0x80、0xA0、0xC0和0xE0。

向量表

当发生异常时,Cortex-M3需要定位其处理例程的入口地址。这些入口地址存储在所谓的"异常向量表"中。缺省情况下,向量表位于零地址处,每个表项占用4字节。

为了支持动态重分发中断,Cortex-M3允许向量表重定位。向量表的起始地址必须满足特定的对齐要求,例如,如果有32个中断,则共有32+16(系统异常)=48个向量,向上增大到2的整次幂后值为64,因此地址必须能被64*4=256整除。

如果需要动态更改向量表,起始处必须包含以下向量:

  • 主堆栈指针(MSP)的初始值
  • 复位向量
  • NMI
  • 硬故障服务例程

中断输入及悬起行为

当中断输入脚被激活后,该中断就被标记为悬起状态。即使后来中断源取消了中断请求,已经被标记的中断也会被记录下来,直到其优先级最高时得到响应。

如果在某个中断得到响应之前,其悬起状态被清除了(例如,在PRIMASK或FAULTMASK置位的时候软件清除了悬起状态标志),则中断被取消。中断服务例程也可以在执行过程中把自己对应的中断重新悬起,但需要注意避免进入"死循环"。

如果中断源持续保持请求信号,该中断会在其上次服务例程返回后再次被置为悬起状态。如果在服务例程执行时,中断请求释放了,但是在服务例程返回前又重新被置为有效,CM3会记住此动作,重新悬起该中断。

Fault类异常

Cortex-M3中的Faults可分为以下几类:

  • 总线Faults
  • 存储器管理Faults
  • 用法Faults
  • 硬Fault

总线Faults

当AHB接口上正在传送数据时,如果回复了一个错误信号,会产生总线Faults。这可能发生在取指(称为"预取流产")或数据读/写(称为"数据流产")时。在CM3中,中断处理起始阶段的堆栈PUSH动作和中断处理收尾阶段的堆栈POP动作也可能触发总线异常。

当总线Faults发生时,只要没有同级或更高优先级的异常正在服务,且FAULTMASK=0,就会执行总线Fault的服务例程。如果在检测到总线Fault时还检测到了更高优先级的异常,则先处理后者,而总线Fault则被标记成悬起。

存储器管理Faults

存储器管理Faults多与MPU(内存保护单元)有关,其诱因常常是某次访问触犯了MPU设置的保护策略。MemManage Fault的常见诱因包括:

  • 访问了MPU设置区域覆盖范围之外的地址
  • 往只读区域写数据
  • 用户级下访问了只允许在特权级下访问的地址

MemManage Fault在NVIC"系统Handler控制及状态寄存器"中的使能位是MEMFAULTENA。为了调查MemManage Fault的案发现场,NVIC中有一个"存储器管理Fault状态寄存器(MFSR)"。

用法Faults

用法Faults可能发生在以下场合:

  • 执行了未定义的指令
  • 执行了协处理器指令(Cortex-M3不支持协处理器)
  • 尝试进入ARM状态
  • 无效的中断返回
  • 使用多重加载/存储指令时地址未对齐

用法Fault在NVIC"系统Handler控制及状态寄存器"中的使能位是USGFAULTENA。为了调查用法Fault的案发现场,NVIC中有一个"用法Fault状态寄存器(UFSR)"。

硬Fault

硬Fault是总线Fault、存储器管理Fault以及用法Fault上访的结果。如果这些Fault的服务例程无法执行,它们就会成为"硬伤"——上访成硬Fault。另外,在取向量时产生的总线Fault也按硬Fault处理。

在NVIC中有一个硬Fault状态寄存器(HFSR),它指出产生硬Fault的原因。

SVC和PendSV

SVC(系统服务调用)和PendSV(可悬起系统调用)多用于操作系统之上的软件开发中。

SVC用于产生系统函数的调用请求。例如,操作系统不让用户程序直接访问硬件,而是通过提供一些系统服务函数,用户程序使用SVC发出对系统服务函数的呼叫请求,以这种方法调用它们来间接访问硬件。

SVC异常通过执行"SVC"指令来产生。该指令需要一个立即数,充当系统调用代号。例如:

SVC 0x3 ; 调用3号系统服务

PendSV(可悬起的系统调用)可以像普通的中断一样被悬起。OS可以利用它"缓期执行"一个异常——直到其它重要的任务完成后才执行动作。PendSV的典型使用场合是在上下文切换时(在不同任务之间切换)。

例如,一个系统中有两个就绪的任务,上下文切换被触发的场合可以是:

  • 执行一个系统调用
  • 系统滴答定时器(SYSTICK)中断

通过PendSV,可以完美解决在中断活跃时的上下文切换问题。PendSV会被编程为最低优先级的异常,如果OS检测到某IRQ正在活动并且被SysTick抢占,它将悬起一个PendSV异常,以便缓期执行上下文切换。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号