【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

相关文章

使用JavaScript将PDF页面中的标注扁平化的操作指南

《使用JavaScript将PDF页面中的标注扁平化的操作指南》扁平化(flatten)操作可以将标注作为矢量图形包含在PDF页面的内容中,使其不可编辑,DynamsoftDocumentViewer... 目录使用Dynamsoft Document Viewer打开一个PDF文件并启用标注添加功能扁平化

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

如何安装 Ubuntu 24.04 LTS 桌面版或服务器? Ubuntu安装指南

《如何安装Ubuntu24.04LTS桌面版或服务器?Ubuntu安装指南》对于我们程序员来说,有一个好用的操作系统、好的编程环境也是很重要,如何安装Ubuntu24.04LTS桌面... Ubuntu 24.04 LTS,代号 Noble NumBAT,于 2024 年 4 月 25 日正式发布,引入了众

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

如何掌握面向对象编程的四大特性、Lambda 表达式及 I/O 流:全面指南

这里写目录标题 OOP语言的四大特性lambda输入/输出流(I/O流) OOP语言的四大特性 面向对象编程(OOP)是一种编程范式,它通过使用“对象”来组织代码。OOP 的四大特性是封装、继承、多态和抽象。这些特性帮助程序员更好地管理复杂的代码,使程序更易于理解和维护。 类-》实体的抽象类型 实体(属性,行为) -》 ADT(abstract data type) 属性-》成

FreeRTOS学习笔记(四)Freertos的中断管理及临界保护

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Cortex-M 中断管理1.1 中断优先级分组1.2 相关寄存器1.3 相关宏定义1.4 FreeRTOS 开关中断 二、临界段及其保护2.1 taskENTER_CRITICAL( ) 和 taskEXIT_CRITICAL( )2.2 taskENTER_CRITICAL_FROM_ISR( )

bash: arm-linux-gcc: No such file or directory

ubuntu出故障重装了系统,一直用着的gcc使用不了,提示bash: arm-linux-gcc: No such file or directorywhich找到的命令所在的目录 在google上翻了一阵发现此类问题的帖子不多,后来在Freescale的的LTIB环境配置文档中发现有这么一段:     # Packages required for 64-bit Ubuntu