[012] [ARM-Cortex-M3/4] 异常与中断处理流程

ARM
Contents
异常与中断处理流程
程序执行方式
处理流程
保存与恢复现场
为什么要保存现场
需要保存的现
场(寄存器)
M3/4硬件保存与
恢复现场流程

1 异常与中断处理流程

1.1 程序执行方式

ARM中控制程序执行的三种方式:

  1. 正常程序是顺序执行的,在CM3中每执行一条指令,PC += 4;
  2. 通过跳转指令,程序可以跳转到特定的地址标号/特定的子程序处执行;
  3. 当异常/中断发生时,系统执行完当前指令后,将跳转到相应的ESR/ISR处执行。当执行完后程序返回发生中断的指令的下一条指令处执行。(进入ESR/ISR前先保护被中断程序的执行现场,从异常程序退出时,要恢复现场)

1.2 处理流程

  • 初始化

    • 设置中断源

    • 设置中断控制器(中断屏蔽寄存器组、优先级)

    • 设置CPU总开关,使能中断

  • 执行正常程序

  • 产生中断->中断信号发给中断控制器->CPU

  • CPU每执行完一条指令,都会检查有无中断/异常产生(硬件)

  • 发现有异常/中断产生->开始处理:

    • 保护现场
    • 分辨异常/中断,调用对于异常/中断的处理函数
    • 恢复现场

1.2.1 Cortex-M3/4处理流程

参考资料:DDI0403E_B_armv7m_arm.pdfARM Cortex-M3与Cortex-M4权威指南.pdfPM0056.pdf

image-20220316203733443

  • 保存现场(硬件):把被中断瞬间的寄存器的值保存进栈里
  • 分辨异常/中断(硬件)
  • 根据异常/中断号,从向量表中得到函数地址,跳转过去执行
  • 函数执行完后,从栈中恢复现场(软件触发,硬件恢复)

1.2.2 Cortex-A7处理流程

参考资料:ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf

image-20220316204101536

  • CPU切换到对应的异常模式
    • 用户模式(usr)
    • 快速中断模式(fiq)
    • 外部中断模式(irq)
    • 特权模式(sve)
    • 中止模式(abort)
    • 未定义指令模式(undefined)
    • 系统模式(sys)
  • 保存被中断时的CPSR到SPSR
    • CPSR:current program status register,当前程序状态寄存器
    • SRSR:saved program status register,保存的程序状态寄存器
  • 向量表上放置的是跳转指令(如发生任何中断时,CPU会从向量表里找到下面第6项(0~7),得到ldr pc, _irq指令,执行后就跳转到_irq函数),在跳转到的函数中:
    • 保存现场
    • 分辨异常/中断
    • 调用对应的处理函数
    • 恢复现场
_start: 
    b	reset
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq

上面启动代码来自:u-boot-arch-arm-lib-vectors.s

综上,两者区别

  • 保存现场:cortex M3/M4里是硬件完成,cortex A7等是软件实现
  • 分辨异常/中断:cortex M3/M4里是硬件完成,cortex A7等是软件实现
  • 调用处理函数:cortex M3/M4里是硬件来调用,cortex A7等是软件自己去调用
  • 恢复现场:cortex M3/M4里是软件触发、硬件实现,cortex A7等是软件实现

2 保存与恢复现场

2.1 为什么要保存现场

举例分析:

image-20220322012630727

上述4条汇编指令,它们被异常打断时,需要保证在异常处理完后,被打断的程序还能正确运行,需要保存的数据:

  • 执行第1条指令时程序被打断,恢复运行时,R0要保持不变

  • 执行第2条指令时程序被打断,恢复运行时,R0、R1要保持不变

  • 执行第3条指令时程序被打断,比较结果保存在程序状态寄存器里,恢复运行时,程序状态寄存器保持不变

上述指令要读取a、b内存,当被打断时无需保存,因为只要程序不越界,内存就保持不变。因此关键在于R0、R1、程序状态寄存器的保存:

  • 在处理异常前,把这些寄存器保存在中,即为保存现场
  • 在处理完异常后,从中恢复这些寄存器,即为恢复现场

2.2 需要保存的现场(寄存器)

image-20220316235000381

根据ATPCS:C函数可以修改R0~R3、R12、R14(LR)及PSR寄存器(M3/M4中称为XPSR,A7中称为CPSR)。若C函数需要使用R4~R11,就应该把它们保存到栈里,在函数结束前在从栈中恢复它们。

因此,寄存器被拆分成2部分:

  • 调用者保存的寄存器(R0-R3,R12,LR,PSR):函数调用子程序后,若还需使用其中某些寄存器,则在调用前需保存到栈中,调用结束后再从栈中恢复。
  • 被调用者保存的寄存器(R4-R11):被调用者需要使用其中某些寄存器时,则需将它们保存到栈中,函数退出前恢复它们的原始值,因此其他程序可能在使用这些寄存器。

例如,函数A(调用者)调用函数B(被调用者)时:

对于函数A:

  • R0-R3用来传参数给函数B,函数B可能会修改这些寄存器,函数A若还需使用,则必须保存它们;
  • R12,LR,PSR若还需使用,也要保存

对于函数B:

  • 用到R4-R11中的某些寄存器,都要在函数入口保存、在函数返回前恢复
  • 保证在B函数调用前后,函数A看到的R4-R11保持不变

函数B就可以视为异常/中断处理函数,在函数A被打断,执行异常/中断处理前,需要保存:

  • 保存调用者使用到的寄存器(R0-R3,R12,LR,PSR)
  • PC

2.3 M3/4硬件保存与恢复现场流程

2.3.1 异常堆栈帧(exception stack frame)

在异常入口处被压入栈空间的数据块为栈帧。对于Cortex-M3或不具有浮点单元的Cortex-M4处理器,栈帧都是8个字(32字节)大小的,对于具有浮点单元的Cortex-M4则可能是8或26个字。

ATPCS要求栈指针的数值在函数入口和出口处是双字对齐的,即SP的值必须能被8整除,若在中断产生时栈帧未对齐到双字上,M3/4会自动插入一个字(栈本身即是字<4字节>对齐的),双字对齐特性可通过SCB->CCR的STKALIGN位设置,若异常不符合ATPCS,则可将该特性关闭。(F1默认不开启,但启动文件使用PRESERVE8做了8字节对齐)也可以通过伪指令REQUIRE8PRESERVE8配置堆栈8字节对齐。

进入异常前,依次把xPSR, PC, LR, R12以及R3-R0由硬件自动压入适当的堆栈中(响应异常时,若当前代码正在使用PSP,则压入PSP,否则就压入MSP),其中,PC(SP-0x24处)即为图中返回地址

image-20220319163920075

▲ 双字栈对齐时,Cortex-M3或Cortex-M4(无浮点单元)处理器的异常栈帧

压栈时xPSR的bit9表示栈指针SP数值是否被调整过,上图为双字对齐,因此不会额外插入一个字,且xpsr bit9 = 0。若使能了双字对齐特性,且SP数值未对齐到双字边界上,栈中会被插入一段空间,SP被强制对齐到双字地址,且xpsr bit9 = 1,表明插入了一段区域:

image-20220319172123214

▲ 非双字栈对齐时,Cortex-M3或Cortex-M4(无浮点单元)处理器的异常栈帧

自动入栈的过程中,把寄存器写入堆栈内存的时间顺序,并不是与写入的空间顺序相对应的。但是机器会保证:正确的寄存器将被保存到正确的位置:

image-20220319171342774

▲ 内部入栈序列
  • 先保存PC与xPSR:可以更早地启动服务例程指令的预取——因为这需要修改PC;同时,也做到了在早期就可以更新xPSR中IPSR位段的值。
  • 后压入R3-R0,R12:为了更容易地使用SP基址来索引寻址(这也方便了LDM等多重加载指令。因为LDM必须加载地址连续的一串数据,而现在R0-R3, R12的存储地址连续了),这种顺序也舒展了参数的传递过程,即可方便地通过读取入栈的R0-R3取出参数

入栈操作由数据(系统)总线完成,而指令总线同时会从向量表中找出正确的异常向量,然后在服务程序的入口处预取指,即入栈和取指同时进行

2.3.2 更新寄存器

在入栈和取向量操作完成之后,执行服务例程之前,还要更新一系列的寄存器:

  • SP:在入栈后会把堆栈指针(PSP或MSP)更新到新的位置。在执行服务例程时,将由MSP负责对堆栈的访问。
  • PSR:更新IPSR位段的值为新响应的异常编号。
  • PC:在取向量完成后,PC将指向服务例程的入口地址
  • LR:LR = EXC_RETURN

此外,NVIC中也会更新若干个相关有寄存器。

2.3.3 异常返回EXC_RETURN

M3/M4在调用异常处理函数前,把LR设置为一个特殊的值——EXC_RETURN,当异常处理结束后,硬件PC=EXC_RETURN,触发异常返回机制

  • 恢复先前压入栈中的寄存器,堆栈指针的值也改回先前的值。
  • 更新NVIC寄存器:活动位被硬件清除,对于外部中断,倘若中断输入再次被置为有效,悬起位也将再次置位。

EXC_RETURN合法值如下:

image-20220317013032668

▲ EXC_RETURN的位域

image-20220317013205472

▲ EXC_RETURN的合法值

如果主程序在线程模式下运行,并且在使用MSP时被中断,则在服务例程中LR=0xFFFF_FFF9;若使用PSP时被中断,则在服务例程中LR=0xFFFF_FFFD(主程序被打断前的LR已被自动保存至异常栈帧):

image-20220320222716951

如果主程序在Handler模式MSP)下运行,则在服务例程中LR=0xFFFF_FFF1,在嵌套时,更深层ISR所看到的LR总是0xFFFF_FFF1:

image-20220320222909813

执行异常返回

  • 可通过EXC_RETURN bit2判断异常返回的栈帧使用的是MSP还是PSP
  • 在每次出栈操作结束时,处理器还会检查出栈xPSR数值的第9位,并且若压栈时插入了额外的空间则会将其去除。

image-20220320222512480

END

  • 10
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: "arm cortex-m3与cortex-m4权威指南"的英文原版名称是"ARM Cortex-M3 and Cortex-M4 Technical Reference Manual". ### 回答2: "arm Cortex-M3与Cortex-M4权威指南英文原版"的英文名称是"The Definitive Guide to ARM Cortex-M3 and Cortex-M4". 这本指南被广泛认为是学习和理解ARM Cortex-M3和Cortex-M4处理器架构的权威指南。它详细介绍了这两款处理器的特点、功能和各种编程技巧。这本指南适用于嵌入式系统开发人员、硬件工程师和软件开发人员,帮助他们深入了解ARM Cortex-M3和Cortex-M4处理器的内部工作原理,并利用它们开发高效、可靠和高性能的嵌入式应用程序。 "The Definitive Guide to ARM Cortex-M3 and Cortex-M4"涵盖了广泛的主题,包括处理器核心、内存体系结构、中断系统、外设接口、低功耗模式以及软件开发工具和技术。通过对这些主题的深入讲解,读者可以学习如何编写高效的嵌入式代码,优化系统性能,减少能耗,并提高应用程序的可靠性。 该指南还提供了丰富的示例代码和实践性的项目,帮助读者将所学知识应用于实际项目中。此外,书中还包含了大量的图表和说明,以帮助读者更好地理解复杂的概念和技术。 总之,"arm Cortex-M3与Cortex-M4权威指南英文原版"是一本深入介绍ARM Cortex-M3和Cortex-M4处理器架构的权威指南,对嵌入式系统开发人员和硬件工程师来说是一本宝贵的参考书籍。 ### 回答3: ARM Cortex-M3与Cortex-M4权威指南的英文原版分别为: 1. ARM Cortex-M3 Technical Reference Manual 2. ARM Cortex-M4 Technical Reference Manual

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

柯西的彷徨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值