Cortex-M4处理器 系统异常

异常状态

每个异常都处于以下状态之一:

  • Inactive:异常不活动也不挂起
  • Pending:异常正在等待处理器处理
    来自外设或软件的中断请求可以将相应的中断状态更改为挂起状态
  • Active:处理程序正在处理但尚未完成的异常
    一个异常处理程序可以中断另一个异常处理程序的执行。在这种情况下,两个异常都处于活动状态。
  • Active and pending:异常由处理器处理,并且有来自同一来源的挂起异常

异常类型

  • Reset:在上电或热复位时调用Reset。异常模型将重置视为一种特殊形式的异常。当断言reset时,处理器的操作停止,可能在指令中的任何点停止。当reset被解除断言时,从vector表中reset表项提供的地址重新开始执行。执行在线程模式下作为特权执行重新启动。
  • NMI:不可屏蔽中断(NMI)可以由外设发出信号或由软件触发。这是除reset之外优先级最高的异常。它是永久启用的,并且具有固定的优先级-2,NMI不能是:
    被任何其它异常屏蔽或阻止激活
    除重置之外的任何异常抢占
  • HardFault:是由于异常处理过程中的错误或由于任何其它异常机制无法管理异常而发生的异常。硬件错误的优先级固定为-1,这意味着它们的优先级高于任何具有可配置优先级的异常
  • MemManage:是指内存保护相关故障导致的异常。对于指令和数据内存事务,固定内存保护约束决定了此错误。此错误通常用于终止对非执行(XN)内存区域的指令访问
  • BusFault:BusFault是由于指令或数据内存事务的内存相关错误而发生的异常。这可能是在内存系统的总线上检测到的错误。
  • UsageFault:由于与指令执行相关的错误而发生的异常。这包括:未定义的指令、非法的未对齐访问、指令执行时的无效状态、异常返回时的错误。
    当内核配置为报告UsageFault时,以下情况可能导致UsageFault:
    在字和半字存储器访问上的未对齐地址
  • SVCall:在操作系统环境中,应用程序可以使用SVC指令来访问操作系统内核函数和设备驱动程序。
  • PendSV:PendSV是系统级服务的中断驱动请求。在操作系统环境中,当没有其他异常活动时,使用PendSV进行上下文切换。
  • SysTick:SysTick异常是系统计时器达到零时产生的异常。软件也可以生成SysTick异常。在操作系统环境中,处理器可以将此异常用作系统提示。
  • IRQ:中断(或IRQ)是由外设发出信号或由软件请求产生的异常。所有中断对指令执行都是异步的。在系统中,外设使用中断与处理器通信。

对于异步异常,除了重置之外,处理器可以在触发异常和进入异常处理程序之间执行另一条指令。

特权软件可以禁用具有可配置优先级的异常。

异常处理程序

处理器使用以下命令处理异常:
Interrupt Service Routines(ISRs):中断服务例程(isr) IRQ中断是由isr处理的异常。

Fault handlers:HardFault、MemManage fault、UsageFault和BusFault是由故障处理程序处理的异常故障。

System handlers:NMI、PendSV、SVCall、SysTick和fault异常都是由系统处理程序处理的系统异常。

向量表

向量表包含堆栈指针的重置值,以及所有异常处理程序的起始地址(也称为异常向量)。
Cortex-M4处理器 系统异常_第1张图片
异常向量在向量表中的排列顺序如图所示,每个向量的最低有效位必须为1,表示异常处理程序是Thumb代码。

在系统复位时,向量表固定在地址0x00000000.
特权软件可以写VTOR,将向量表的起始地址重新定位到不同的内存位置,范围为 0x00000080到0x3FFFFF80。

异常优先级

所有异常都有一个相关的优先级。

  • 优先级值越低,优先级越高。
  • 可配置的优先级除了Reset、HardFault和NMI

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

可配置的优先级取值范围是0-。这意味着具有固定优先级值的Reset、HardFault和NMI异常总是具有比任何其它异常更高的优先级。

例如,为IRQ[0]分配较高的优先级值,为IRQ[1]分配较低的优先级值,表示IRQ[1]的优先级高于IRQ[0]。
如果IRQ[1]和IRQ[0]都被断言,IRQ[1]在IRQ[0]之前被处理。

如果多个挂起异常具有相同的优先级,则异常编号最低的挂起异常具有优先级。例如,如果IRQ[0]和IRQ[1]都处于挂起状态,并且具有相同的优先级,则IRQ[0]在IRQ[1]之前被处理。

当处理器执行异常处理程序时,如果发生更高优先级的异常,异常处理程序将被抢占。如果发生的异常与被处理的异常具有相同的优先级,则处理程序不会被抢占,而与异常编号无关。但是,新中断的状态变为挂起。

中断优先级分组

为了在有中断的系统增加优先级控制,NVIC支持优先级分组。
将每个中断优先级寄存器条目划分为两个字段:

  • 上面的字段,用于定义组优先级
  • 一个较低的字段,用于定义组内的子优先级

只有组优先级决定中断异常的抢占。当处理器正在执行中断异常处理程序时,另一个与被处理的中断具有相同组优先级的中断不会抢占该处理程序。

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

异常进入和返回

抢占
当处理器执行异常处理程序时,如果异常处理程序的优先级高于正在处理的异常的优先级,则异常可以抢占异常处理程序。

当一个异常抢占另一个异常时,这些异常称为嵌套异常。

Return
这将在异常处理程序完成时发生,并且:

  • 这里没有具有足够优先级的待处理异常
  • 完成的异常处理程序没有处理延迟到达的异常

处理器弹出堆栈并将处理器状态恢复到中断发生前的状态。

尾链
这种机制加快了异常服务的速度。在异常处理程序完成后,如果存在满足异常条目要求的挂起异常,则跳过堆栈弹出,并将控制转移到新的异常处理程序。

Late-arriving
这种机制加速了抢占。如果在先前异常的状态保存期间发生高优先级异常,处理器将切换到处理高优先级异常,并为该异常启动vector fetch。
状态保存不受延迟到达的影响,因为两个异常保存的状态是相同的。因此状态保存持续不间断地进行。
处理器可以接受延迟到达的异常,直到原始异常的异常处理程序的第一条指令进入处理器的执行阶段。从延迟到达异常的异常处理程序返回时,应用常规的尾链规则。

异常进入

异常进入发生在有足够优先级的挂起异常时,并且:

  • 处理器处于线程模式
  • 新异常的优先级高于正在处理的异常,在这种情况下,新异常会抢占原始异常。

当一个异常抢占另一个异常时,异常是嵌套的。
足够优先级意味着异常具有比掩码寄存器设置的任何限制更多的优先级,参见第2-7页的异常掩码寄存器。优先级低于此的异常处于挂起状态,但不由处理器处理。

当处理器接收异常时,除非该异常是尾链异常或延迟到达异常,否则处理器将信息推入当前堆栈。这个操作被称为堆叠,8个数据字的结构被称为堆栈帧。

当使用浮点例程时,Cortex-M4处理器自动将体系结构的浮点状态堆栈在异常顶上。

Cortex-M4处理器 系统异常_第2张图片

堆叠完成后,堆栈指针立即指向堆栈帧中最低的地址。堆栈帧的对齐是通过配置控制寄存器(CCR)的STKALIGN位控制的。

堆栈帧包含返回地址。这是被中断程序中下一条指令的地址。此值在异常返回时恢复到PC,以便中断的程序恢复。

与堆叠操作并行的是,处理器执行一个vector fetch操作,从vector表中读取异常处理程序的起始地址。当堆叠完成后,处理器开始异常处理程序。同时,处理器向LR写入一个EXC_RETURN值。这表明哪个堆栈指针对应于堆栈帧,以及处理器在entry发生之前处于什么操作模式。

如果在异常进入期间没有更高优先级的异常发生,处理器开始执行异常处理程序,并自动将相应的挂起中断的状态改为活动。

如果在异常进入期间发生另一个更高优先级的异常,则处理器开始执行该异常的异常处理程序,并且不更改先前异常的挂起状态。

异常返回

当处理器处于Handler模式并执行以下指令之一将EXC_RETURN值加载到PC时,将发生异常返回:

  • 加载PC机的LDM或POP指令
  • 以PC机为源地址的LDR指令
  • 使用任何寄存器的BX指令

EXC_RETURN是在异常进入时加载到LR上的值。异常机制依赖此值来检测处理器何时完成异常处理程序。该值的最低五位提供有关返回堆栈和处理器模式的信息。

Cortex-M4处理器 系统异常_第3张图片
所有的EXC_RETURN值都将位[31:5]设置为1。
当这个值加载到PC中时,它向处理器表示异常已经完成,处理器启动相应的异常返回序列。

你可能感兴趣的:(stm32,stm32,系统架构,嵌入式硬件,单片机,学习)