【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位)会置位。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3017671.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习第二天(监督学习,无监督学习,强化学习,混合学习)

1.是什么 基于数据寻找规律从而建立关系,进行升级,如果是以前的固定算式那就是符号学习了 2.基本框架 3.监督学习和无监督式学习: 监督学习:根据正确结果进行数据的训练; 在监督式学习中,训练数据包括输…

【数据结构与算法】力扣 239. 滑动窗口最大值

题干描述 给你一个整数数组 nums,有一个大小为 k **的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1: 输入: nums [1,3,-1,-3,5,3…

HP Z620 服务器打开VTx虚拟技术

在使用Virtual Box的时候,虚拟主机启动报错:提示需要VTx。于是到bios里面去设置VTx。 这里有个小坑,就是HP 的bios配置里面,VTx不在常规的“System Configuration”、“Advanced”等地方,而是在“Security”菜单里&…

[C++基础学习-04]----C++数组详解

前言 在C中,数组是一种用来存储相同类型元素的数据结构。一维数组是最简单的数组形式,它由一系列按顺序存储的元素组成。二维数组则是由一维数组构成的数组,可以看作是一堆一维数组堆叠在一起形成的矩阵。 正文 01-数组简介 一维数组和二维…

uni-app安卓本地打包个推图标配置

如果什么都不配置,默认的就是个推小鲸鱼图标 默认效果 配置成功效果 个推图标配置 新建目录 drawable-hdpi、drawable-ldpi、drawable-mdpi、drawable-xhdpi、drawable-xxhdpi、drawable-xxxhdpi 目录中存放图标 每个目录中存放对应大小的图标,大图…

react引入阿里矢量库图标

react引入阿里矢量库图标 登录阿里矢量库,将项目所需的图标放一起 react项目中新建文件夹MyIcon.js 3. 在页面中引入,其中type为图标名称

C++之类与对象

1、类声明 2、共有、私有、保护成员。(就比如说你一个变量是private的,然后在main函数中,就调用不了,只能在这个类.cpp中调用) 3、数据抽象和封装 4、内联函数 内存体积会增大,以空间换时间:编…

php使用服务器端和客户端加密狗环境部署及使用记录(服务器端windows环境下部署、linux环境宝塔面板部署、客户端部署加密狗)

php使用服务器端和客户端加密狗环境部署及使用记录 ViKey加密狗环境部署1.windows环境下部署开发文档验证代码提示Fatal error: Class COM not found in 2.linux环境下部署(宝塔面板)开发文档验证代码提示Fatal error: Uncaught Error: Call to undefine…

什么是HTTP/2?

HTTP/2(原名HTTP 2.0)即超文本传输协议第二版,使用于万维网。HTTP/2主要基于SPDY协议,通过对HTTP头字段进行数据压缩、对数据传输采用多路复用和增加服务端推送等举措,来减少网络延迟,提高客户端的页面加载…

机器人码垛机的主体结构及技术特点

在现代物流和生产线上,机器人码垛机以其高效、准确的特点,成为了不可或缺的重要设备。那么,这个神奇的机器人究竟由哪些部分组成?它的内部结构又有哪些奥秘呢?接下来,就让我们一起揭开它的神秘面纱! 一、机器人码垛机的主体结构…

QT-TCP通信

网上的资料太过于书面化,所以看起来有的让人云里雾里,看不懂C-tcpsockt和S-tcpsocket的关系 所以我稍微画了一下草图帮助大家理解两个套接字之间的关系。字迹有的飘逸勉强看看 下面是代码 服务端: MainWindow::MainWindow(QWidget *parent) …

动态规划算法:简单多状态问题

例题一 解法(动态规划): 算法思路: 1. 状态表⽰: 对于简单的线性 dp ,我们可以⽤「经验 题⽬要求」来定义状态表⽰: i. 以某个位置为结尾,巴拉巴拉; ii. 以某个位置为起…

语音识别--使用YAMNet识别环境音

⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计3077字,阅读大概需要3分钟 🌈更多学习内容, 欢迎👏关注👀【文末】我的个人微信公众号&#xf…

HG-KN73J-S100 三菱伺服电机(750W型)

HG-KN73J-S100属于三菱MR-JE系列伺服系统,可以与伺服驱动器MR-JE-70A、MR-JE-70B、MR-JE-70C配套使用。HG-KN73J-S100完全替换HF-KN73J-S100。HG-KN73J-S100规格、HG-KN73J-S100参数。 HG-KN73J-S100参数说明:MR-JE低惯性/小容量、0.75Kw三菱伺服电机HG-…

【管理咨询宝藏94】某国际咨询公司供应链财务数字化转型方案

本报告首发于公号“管理咨询宝藏”,如需阅读完整版报告内容,请查阅公号“管理咨询宝藏”。 【管理咨询宝藏94】某国际咨询公司供应链&财务数字化转型方案 【格式】PDF版本 【关键词】国际咨询公司、制造型企业转型、数字化转型 【核心观点】 - 172…

SAP PP学习笔记12 - 评估MRP的运行结果

上一章讲了MRP的概念,参数,配置等内容。 SAP PP学习笔记11 - PP中的MRP相关概念,参数,配置-CSDN博客 本章来讲 MRP跑完之后呢,要怎么评估这个MRP的运行结果。 1,Stock/Requirements List and MRP List 在…

MySQL日志机制【undo log、redo log、binlog 】

前言 SQL执行流程图文分析:从连接到执行的全貌_一条 sql 执行的全流程?-CSDN博客文章浏览阅读1.1k次,点赞20次,收藏12次。本文探讨 MySQL 执行一条 SQL 查询语句的详细流程,从连接器开始,逐步介绍了查询缓存、解析 S…

这些CTF,不仅学技术,还有巨额奖金!

前言: 不会吧,不会吧,不会还有安全er不知道CTF是什么吧? 在程序员的世界里,也有ACM这样的编程大赛,成为各路编程高手一较高下展示能力的平台。 那在网络安全的圈子里,各路黑客红客白帽子们又…

Flutter弹窗链-顺序弹出对话框

效果 前言 弹窗的顺序执行在App中是一个比较常见的应用场景。比如进入App首页,一系列的弹窗就会弹出。如果不做处理就会导致弹窗堆积的全部弹出,严重影响用户体验。 如果多个弹窗中又有判断逻辑,根据点击后需要弹出另一个弹窗,这…

Gradle 进阶学习 之 build.gradle 文件

build.gradle 是什么? 想象一下,你有一个大型的乐高项目,你需要一个清单来列出所有的乐高积木和它们如何组合在一起。在软件开发中,build.gradle 就是这个清单,它告诉计算机如何构建(组合)你的软…