Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)


layout: post
title: “中断的具体行为”
date: 2024-1-17 15:39:08 +0800
tags: Cotex-M3 Cotex-M3权威指南


中断的具体行为

  • 入栈:把8个寄存器的值压入栈
  • 取向量:从向量表中找出对应的服务程序入口地址
  • 选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接寄存器LR,更新程序计数器PC

入栈

自动保存现场的必要部分:依次把xPSR, PC, LR, R12以及R3-R0由硬件自动压入适当的堆栈中

如果当响应异常时,当前的代码正在使用PSP,则压入PSP,也就是使用进程堆栈;否则就压入MSP,使用主堆栈。一旦进入了服务例程,就将一直使用主堆栈。

Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)_第1张图片

Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)_第2张图片

Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)_第3张图片

先把PC与xPSR的值保存,就可以更早地启动服务例程指令的预取——因为这需要修改PC;同时,也做到了在早期就可以更新xPSR中IPSR位段的值

优先入栈这几个寄存器的原因是使得中断控制函数可以使用C语言进行编写, 编译器优先使用入栈了的寄存器来保存中间结果当然,如果程序过大也可能要用到R4-R11,此时编译器负责生成代码来push它们。

取向量

数据总线在忙的时候指令总线会获取到程序的入口

更新寄存器

  • SP:在入栈 后会把堆栈指针(PSP或MSP)更新 到新的位置。在执行服务例程时,将由MSP负责对堆栈的访问。
  • PSR:更新IPSR位段(地处PSR的最低部分)的值为新响应的异常编号。
  • PC:在取向量完成后,PC将指向服务例程的入口地址,
  • LR:在出入ISR的时候,LR的值将得到重新的诠释,这种特殊的值称为“EXC_RETURN”,在异常进入时由系统计算并赋给LR,并在异常返回时使用它。EXC_RETURN的二进制值除了最低4位外全为1,而其最低4位则有另外的含义(后面讲到,见表9.3和表9.4)。

异常返回

Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)_第4张图片

在CM3中,是通过把EXC_RETURN往PC里写来识别返回动作的。

  1. 出栈:先前压入栈中的寄存器在这里恢复。内部的出栈顺序与入栈时的相对应,堆栈指针的值也改回先前的值。
  2. 更新NVIC寄存器:伴随着异常的返回,它的活动位也被硬件清除。对于外部中断,倘若中断输入再次被置为有效,悬起位也将再次置位,新一次的中断响应序列也可随之再次开始。

以上的行为是自动的

中断的嵌套

NVIC和CM3处理器会根据优先级的设置来控制抢占与嵌套行为。因此,在某个异常正在响应时,所有优先级不高于它的异常都不能抢占之,而且它自己也不能抢占自己。

有了自动入栈和出栈,就不用担心在中断发生嵌套时,会使寄存器的数据损毁,从而可以放心地执行服务例程。

有一件事情却必须更加一丝不苟地处理了,否则有功能紊乱甚至死机的危险。这就是计算主堆栈容量的最小安全值。

相同的异常是不允许重入的。因为每个异常都有自己的优先级,并且在异常处理期间,同级或低优先级的异常是要阻塞的。因此对于同一个异常,只有在上次实例的服务例程执行完毕后,方可继续响应新的请求。由此可知,在SVC服务例程中,就不得再使用SVC指令,否则将fault伺候。

咬尾中断

当处理器在响应某异常时,如果又发生其它异常,但它们优先级不够高,则被阻塞

在中断退出又进入的过程中, 不需要在进行一次出站入栈的过程

Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)_第5张图片

晚到(的高优先级)异常

如果是在低优先级中断入栈的时候产生的高优先级中断, 会在入栈结束之后进入高优先级的处理函数, 之后使用咬尾中断处理

异常返回值

在进入异常处理函数的时候, LR寄存器保存的值是EXC_RETURN

高28位全为1的值,只有[3:0]的值有特殊含义

Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)_第6张图片

Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)_第7张图片

进入之前的LR会被自动入栈

Cotex-M3中断处理的具体行为(状态保存以及恢复机制等)_第8张图片

EXC_RETURN的格式可见,我们不能把0xFFFF_FFF0-0xFFFF_FFFF中的地址作为任何返回地址。其实也并不用担心会弄错,因为CM3已经把这个范围标记成“取指不可区”

中断延迟

中断延迟的定义是:从检测到某中断请求,到执行了其服务例程的第一条指令时,已经流逝了的时间。

在CM3中,若存储器系统够快,且总线系统允许入栈与取指同时进行,同时该中断可以立即响应,则中断延迟是雷打不动的12周期(满足硬实时所要求的确定性)。

进行了入栈、取向量、更新寄存器以及服务例程取指的一系列操作。

处理咬尾中断时,省去了堆栈操作,因此切入新异常服务例程的耗时可以短至6周期。

异常响应期间的Fault

入栈期间

入栈期间引起了总线fault,则本次入栈操作将被强行中止,并且把总线异常悬起或者在允许时立即响应。若除能了总线fault,则此次故障将成为“硬伤”——上访至硬fault。在总线fault被使能的情况下,如果它的优先级比正在响应的异常高,则抢占之,否则将悬起直到引起fault的异常执行完毕。

入栈操作引起MPU访问违例,则产生存储管理fault,并且必须能立即执行MemFault服务例程,否则将无条件上访成硬fault。

出栈期间

中断返回时的出栈期间引起了总线fault,则本次出栈操作将被强行中止,并且把总线异常悬起或立即响应。若除能了总线fault,则此次故障将成为“硬伤”——上访至硬fault。其它情况下,只要总线fault的优先级比当前的高(也包括比当前最深嵌套的优先级高),则可以立即响应。这种情况称为“出栈错误”

取向量期间

直接上硬fault, MPU的限制则管不着取向量操作

无效返回

LR中的EXC_RETURN不是合法的值(合法值见表9.4,包括企图返回ARM状态),则引起用法fault。如果用法fault被除能,也上访成硬fault。

你可能感兴趣的:(Cotex-M3内核知识,stm32,mcu,单片机,笔记,经验分享)