【ARM Cortex-M3指南】8:中断行为

2024-05-07 19:28
文章标签 行为 中断 指南 arm cortex m3

本文主要是介绍【ARM Cortex-M3指南】8:中断行为,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 八、中断行为
    • 8.1 中断/异常流程
      • 8.1.1 压栈
      • 8.1.2 取向量
      • 8.1.3 寄存器更新
    • 8.2 异常退出
    • 8.3 嵌套中断
    • 8.4 末尾连锁中断
    • 8.5 延迟到达
    • 8.6 进一步了解异常返回值
    • 8.7 中断等待
    • 8.8 中断相关的错误
      • 8.8.1 压栈
      • 8.8.2 出栈
      • 8.8.3 取向量
      • 8.8.4 非法返回

八、中断行为

8.1 中断/异常流程

异常发生时,同时会伴随着多种情况,例如,

  • 压栈(将8个寄存器的内容压入栈中);
  • 取向量(从向量表中读取异常处理的起始地址);
  • 更新栈指针(SP)、链接寄存器(LR)和程序计数器(PC)。

8.1.1 压栈

当异常发生时,寄存器R0~R3、R12、LR、PC和程序状态(PSR)会被压入栈中。如果运行的代码使用了进程栈指针(PSP),此时就会用进程栈;而如果正在运行的代码使用主栈指针(MSP),则使用主栈。之后,异常处理会始终使用主栈,因此所有的嵌套中断都会使用主栈

被压入栈的8个字组成的块通常被称作栈帧,在Cortex-M3版本2之前,栈帧默认可以从任意地址开始。在Cortex-M3版本2中,栈帧默认位于双字对齐的地址上,通过对嵌套中断控制器的配置控制寄存器写0可以将该对齐特性关闭。栈帧特性在Cortex3版本 1上也是可用的,只是使能时需要将STKALIGN写1。第12章中有这个寄存器的更多细节。

异常栈帧中的数据排列如图9.1所示,压栈的顺序如图9.2所示(假定异常后的栈指针[SP]为N)。由于高级高性能总线(AHB)的流水线特性,地址和数据相差一个流水线状态。

PC和PSR的数值会被首先压栈,这样取指令(需要修改PC)和更新中断程序状态寄存器(IPSR)就会更早些。压栈后,SP会更新,栈中的数据排列如图9.1所示。

将R0~R3、R12、LR、PC和PSR进行压栈的原因是,根据C标准(《ARM架构C/C++标准过程调用标准》,AAPCS,参考文献[5]),它们为调用者保存寄存器。在这种设定下,由于异常处理可能会修改的寄存器已经保存在栈中了,中断处理就可以用普通C函数实现了。

通用寄存器(R0~R3和R12)位于栈帧的最后,这样它们很容易被SP相关的寻址访问。因此,使用压栈的寄存器为软件中断传递参数也非常容易。

image.png

8.1.2 取向量

尽管数据总线被寄存器压栈占用,指令总线也在执行中断流程的其他重要任务:从向量表中取出异常向量(异常处理的起始地址)。由于压栈和取向量是在相互独立的总线接口上进行的,因此它们可以同时执行。

8.1.3 寄存器更新

在压栈和取向量完成后,异常向量会开始执行。在异常处理的入口处,多个寄存器会得到更新,它们是:

  • SP:SP(MSP或者PSP)在压栈过程中会更新为新的地址,在中断服务程序执行过程中,如果需要访问栈的话则会使用MSP。
  • PSR:IPSR会被更新为新的异常编号。
  • PC:在取向量结束并且开始从异常向量中取指时会被修改为向量处理。
  • LR:LR会被更新为特殊值EXC_RETURN,这个特殊值会引发中断返回操作,LR的最后4位提供了异常返回信息。

NVIC的多个寄存器也会得到更新,例如,异常的挂起状态会被清除并且异常的活跃状态会置位。

8.2 异常退出

在异常处理最后,需要执行异常退出(有些处理器也称为中断返回)恢复系统状态,这样被中断的程序才可以继续执行。三种方式可以触发中断返回流程,它们都需要使用在异常处理开始时存储在LR中的特殊值(见表9.1)。

有些微处理器架构在中断返回时使用特殊的指令(如8051的reti),而Cortex-M3则使用普通的返回指令,这样整个中断处理可以被当做C函数来实现。

在执行异常返回指令时,如表9.1所示,出栈和NVIC寄存器更新过程就会执行。

image.png

8.3 嵌套中断

Cortex-M3处理器内核和NVIC中内置了对嵌套中断的支持,无须使用汇编包装代码使能嵌套中断。事实上,除了为每个中断源设置合适的优先级之外,你什么也不用做。首先,Cortex-M3处理器中的NVIC会处理优先级解码,因此,在处理器处理异常时,其他所有具有相同或更低优先级的异常都会被屏蔽;其次,硬件自动压栈和出栈使得嵌套中断在执行时,无须考虑丢失寄存器数据的风险。

不过,需要考虑的一件事是,如果允许嵌套中断,应确保主栈中有足够的空间。由于每个异常等级都会使用8字的栈空间,而且异常处理可能还会需要额外的栈空间,结果可能是实际使用的栈空间比预想的要大。

Cortex-M3不允许异常重入,由于每个异常都有分配好的优先级,而且在异常处理过程中,具有相同或更低优先级的异常会被屏板掉,在这个处理结束之前,同一个异常是无法执行的。由于这个原因,请求管理调用(SVC)指令无法在SVC处理内部使用,而这么做的话会引发错误异常。

8.4 末尾连锁中断

Cortex-M3使用了多种方法来改进中断等待,首先来看一下末尾连锁(tail chaining,见图9.3)。

image.png

若异常发生时,处理器正在执行另一个相同或更高优先级的异常,该异常就会进入挂起状态。处理器执行完当前的异常处理后,才可以处理挂起中断。处理器没有将寄存器从栈中恢复(出栈)后再次将它们压入栈中(压栈),而是跳过了出栈和压栈过程,直接进入挂起的异常处理。这样,两次异常处理的时间间隙就减小很多。

8.5 延迟到达

延迟到达(late arrival)异常处理为提高中断性能的另外一个特性。在异常发生后,处理器开始了压栈过程,并且在这期间产生了一个更高抢占优先级的中断,后到的中断就会首先处理。

例如,若异常#1(低优先级)在异常#2(高优先级)前几个周期产生,处理器的处理如图9.4所示,异常处理#2在压栈完成后就会执行。

image.png

8.6 进一步了解异常返回值

在进入异常处理后,LR被更新为特殊值EXC RETURN,该数值的高28位为1,并且当它在异常处理结束后被加载到PC中时,会引起处理器执行异常返回流程。

能够产生异常返回的指令如下:

  • POP/LDM
  • 以PC为目的的LDR
  • BX到任何寄存器

EXC RETURN数值中从31到4位全部为1,3到0位则提供了异常返回操作所需的信息(见表9.2)。当进入异常处理后,LR的数值会自动更新,因此无须手动生成这些数值。

第0位表示异常退出后的进程状态,由于Cortex-M3只支持Thumb®状态,因此第0位必须为1。

若线程使用MSP(主栈),在进入异常时,LR会被设置为0xFFFFFFF9,而当进入嵌套异常时,LR则为0xFFFFFFF1。若线程使用PSP(进程栈),在进入第一个异常时, LR会被设置为0xFFFFFFFD,而当进入嵌套异常时,LR则为OxFFFFFFF1。

image.png

image.png

image.png

image.png

由于EXC RETURN数值的格式,中断不能返回到地址区域0xFFFFFFF0~0xFFFFFFFF。不过,由于该区域为不可执行区域,因此是不存在问题的。

8.7 中断等待

中断等待指的是从请求到中断处理开始执行的延迟时间,对于Cortex-M3处理器,如果存储器系统为零等待,并且假定总线系统支持取向量和压栈同时进行,那么中断等待可以低至12个周期。其中包括寄存器压栈、取向量和中断处理的取指。不过,等待时间还受存储器访问等待状态和其他几个因素的制约。

对于末尾连锁中断,由于无须执行压栈操作,从一个异常处理切换到另一个异常处理的等待时间可以低至6个周期。

当处理器执行除法之类的多周期指令时,在中断处理完成后,之前的指令可能会被舍弃并开始重新执行。这种处理同样适用于双字加载(LDRD)和双字存储(STRD)指令。

要降低异常等待,Cortex-M3处理器允许在多加载和多存储(LDM/STM)期间执行异常。若LDM/STM正在执行,当前存储器访问会完成,而下一个寄存器编号则被保存在压栈的xPSR中(中断继续指令[ICI]位)。异常处理完成后,多加载/存储指令会从上次传输停止的地方继续执行。不过例外情况是存在的,如果被打断的多加载/存储指令是IF THEN(IT)指令块的一部分,加载/存储指令会被取消并在中断完成后重新开始。这是因为ICI位和IT执行状态位在执行程序状态寄存器(EPSR)中的位置相同。

另外,若总线接口上存在缓冲写等传输,处理器会等到传输完成。这样做是必要的,因其可以保证总线错误处理抢占正确的处理。

当然,如果处理器已经在执行另外一个相同或更高优先级的中断,或者如果中断屏被寄存器已经屏被掉了中断请求,则中断会被阻塞。在这些情况下,在阻塞去除前,中断会处于挂起状态。

8.8 中断相关的错误

异常处理可能会引发多种错误,下面来看一下。

8.8.1 压栈

如果在压栈期间发生了总线错误,压栈过程会被终止并且总线错误会被触发或挂起。若总线错误未使能,硬件错误处理会执行。要不然,如果总线错误处理的优先级比原异常高,总线错误处理就会执行;否则,在原异常完成前错误异常会一直处于挂起状态。这种情形被称作压栈错误,而且可以通过总线错误状态寄存器(0xE000ED29)中的STKERR位(第4位)表现出来。

如果栈错误是由存储器保护单元(MPU)冲突引起的,存储器管理错误就会执行,而且存储器管理错误状态寄存器(0xE000ED28)中的MSTKERR(第4位)会指示出这个问题。若存储器管理错误未使能,硬件错误处理就会执行。

8.8.2 出栈

如果总线错误发生在出栈期间(中断返回),出栈过程会终止并且总线错误异常会被触发或挂起。若总线错误为使能,硬件错误异常就会执行。要不然,若总线错误处理的优先级比当前正在执行的任务要高(内核有可能已经在执行其他的异常了,也就是发生了中断嵌套),总线错误处理就会执行。这种情形也被称作出栈错误,它可以通过总线错误状态寄存器(0xE000ED29)中的UNSTKERR位(第3位)表现出来。

类似地,若出栈错误由MPU冲突引起,存储器管理错误就会执行,而且存储器管理错误状态寄存器(0xE000ED28)中的MUNSTKERR(第3位)会指示出这个问题。若存储器管理错误未使能,硬件错误处理就会执行。

8.8.3 取向量

如果总线错误或存储器管理错误发生在取向量阶段,硬件错误处理就会执行,而且硬件错误状态寄存器(0xE000ED2C)中的VECTTBL(第1位)会指示出这个问题。

8.8.4 非法返回

如果EXC RETURN的数值为非法值或者与处理器的状态不匹配(如使用 0 xFFFFFFF1返回到线程模式),就会触发使用错误。如果使用错误处理未使能,硬件错误处理就会执行。根据错误的实际原因的不同,使用错误状态寄存器(0xE000ED2A)中的 INVPC位(第2位)或INVSTATE(第1位)会置位。

这篇关于【ARM Cortex-M3指南】8:中断行为的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/968176

相关文章

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

Spring Boot结成MyBatis-Plus最全配置指南

《SpringBoot结成MyBatis-Plus最全配置指南》本文主要介绍了SpringBoot结成MyBatis-Plus最全配置指南,包括依赖引入、配置数据源、Mapper扫描、基本CRUD操... 目录前言详细操作一.创建项目并引入相关依赖二.配置数据源信息三.编写相关代码查zsRArly询数据库数

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

JavaScript错误处理避坑指南

《JavaScript错误处理避坑指南》JavaScript错误处理是编程过程中不可避免的部分,它涉及到识别、捕获和响应代码运行时可能出现的问题,本文将详细给大家介绍一下JavaScript错误处理的... 目录一、错误类型:三大“杀手”与应对策略1. 语法错误(SyntaxError)2. 运行时错误(R

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详

MySQL中慢SQL优化方法的完整指南

《MySQL中慢SQL优化方法的完整指南》当数据库响应时间超过500ms时,系统将面临三大灾难链式反应,所以本文将为大家介绍一下MySQL中慢SQL优化的常用方法,有需要的小伙伴可以了解下... 目录一、慢SQL的致命影响二、精准定位问题SQL1. 启用慢查询日志2. 诊断黄金三件套三、六大核心优化方案方案

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解