Cortex-M3架构学习:异常

news2024/9/28 3:29:16

异常类型

 Cortex-M3 在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其 中,编号为 1-15 的对应系统异常,大于等于 16 的则全是外部中断。
 
Cortex-M3支持的中断源数目为 240 个,做成芯片后,厂商可按需选择个数,并且优先级的位数也由芯片厂商最终决定。
 
类型编号为 1-15 的系统异常如下所示,
b5a8abceb1a64bcc9b9974a4f7c5132c.png dabbaba7f3f449929001f8879decad89.png
 
只看上述表的描述很难知道每个系统异常的作用,本文在后面会做出解释。
 
 
外部中断列表如下,
6e507b542297435e9cf23b7c4f03cc54.png
 
 

优先级

在 CM3 中,优先级对于异常来说很关键的,它会决定一个异常是否能被掩蔽,以及在未掩蔽的
情况下何时可以响应。
 
优先级的数值越小,则优先级越高。CM3 支持中断嵌套,使得高优先级异常会抢占(preempt)低优先级异常。
 
有 3 个系统异常:复位,NMI 以及硬 fault,它们有固定的优先 级,并且它们的优先级号是负数,从而高于所有其它异常。
 
所有其它异常的优先级则都是可编程的,但是无法设置成负数。
 
CM3支持3个固定优先级和256个可编程优先级,且支持128级抢占式优先级。
 
Cortex-M3处理器支持灵活的优先级配置,可以通过实现的位数来划分优先级。3位表示优先级意味着系统总共支持2³ = 8个不同的优先级级别。
 
e732fc9b3ef14dabb64328f7e305a06b.png
        在这个优先级寄存器中,通常低5位未实现(未使用),这意味着这些位在硬件层面被固定为零。因此,即使整个寄存器有8位,实际用于描述优先级的位数可能是较少的(例如3位)。当只使用3位来表示优先级时,这些位的值总是对齐到寄存器的高位,表示优先级的编码。
 
具体的编码如下,
  • 0x00:最高优先级(所有位为0)
  • 0x20:次高优先级(高3位为001)
  • 0x40:优先级略低(高3位为010)
  • 0x60:优先级略低(高3位为011)
  • 0x80:中等优先级(高3位为100)
  • 0xA0:优先级较低(高3位为101)
  • 0xC0:更低优先级(高3位为110)
  • 0xE0:最低优先级(高3位为111)
备注:CM3的优先级寄存器的MSB(高位)对齐的 

 

抢占优先级和子优先级

Cortex-M3处理器将完整的256个优先级按位划分为抢占优先级子优先级

这种划分方式由NVIC(嵌套向量中断控制器)中的“应用程序中断及复位控制寄存器”(AIRCR寄存器)中的“优先级组”位段决定。

  • 抢占优先级(Preempt Priority):高位部分,控制中断的抢占关系。具有更高抢占优先级的中断可以抢占低优先级中断。
  • 子优先级(Sub Priority):低位部分,当多个中断有相同的抢占优先级时,子优先级决定哪个中断首先被响应。

抢占优先级和子优先级的优先级组的配置如下,

696fad1c7813478489e385cef17182f1.png

举个例子解释上表,比如当我们选择分组位置为2时,那么八位的优先级寄存器的第7位到第2位表示的是抢占优先级,0位和1位表示子优先级;并且,从上表可以看到,子优先级至少占了1位,所以抢占优先级最多占7位,所以最多为128级。 

向量表 

Cortex-M3的向量表是一个存储指针(函数入口地址)的数组,位于内存的某个特定地址。向量表中的每个条目是一个32位的地址指针,指向该中断或异常的处理程序函数。表的最开始部分包含两个特殊的条目:

  • 初始堆栈指针(Initial Stack Pointer):向量表的第一个条目(地址0x00000000)保存处理器复位时的初始堆栈指针值。处理器复位后会从这里读取堆栈指针,并将其加载到主堆栈指针(MSP)寄存器中。
  • 复位向量(Reset Vector):向量表的第二个条目(地址0x00000004)保存复位异常(Reset)的处理程序地址。当系统复位时,处理器会从这里跳转到启动代码。

在这两个特殊条目之后,向量表的其余部分包含各种异常和中断的处理程序入口地址,如下,

7b66272345bb49e79db78caf50f1c7a2.png

向量表通常位于内存地址0x00000000处。

然而,在Cortex-M3中,可以通过设置NVIC中的向量表偏移寄存器(来改变向量表的基地址。这使得在不同的内存地址区域(如RAM)中存储向量表成为可能。

3310b8c1b24645449271d5c4f12d7cea.png

中断输入及悬起

中断输入 

中断输入是由外部设备或系统内部事件引发的一种信号,用来通知处理器发生了某个事件,要求进行处理。Cortex-M3支持多种类型的中断源,如外部GPIO中断、定时器中断、UART中断等。

中断输入信号被触发后,Cortex-M3的嵌套向量中断控制器(NVIC)会根据中断的优先级来决定如何处理。

NVIC通过中断向量表查找中断服务程序(ISR)的入口地址,并执行相应的处理程序。

流程如下,

  • 中断触发:外部信号或内部事件触发中断。
  • 中断悬起:中断控制器将该中断标记为“悬起状态”。
  • 中断处理:当处理器空闲或优先级合适时,NVIC将转移到对应的中断服务程序(ISR)。
  • 中断结束:执行完中断服务程序后,NVIC清除中断悬起标志,并恢复正常程序执行。

 

中断悬起 

中断悬起是指在中断信号输入后,该中断进入等待处理的状态。Cortex-M3的中断系统允许多个中断同时处于悬起状态,并根据优先级进行调度。

  • 多个中断的悬起:如果多个中断同时触发,NVIC会根据中断的优先级来决定哪个中断优先处理。优先级更高的中断将优先被服务,而优先级较低的中断将继续处于悬起状态,直到处理器有空处理它们。
  • 中断嵌套:如果一个中断正在处理过程中,又有更高优先级的中断触发且悬起,处理器会暂停当前的中断处理,转而执行优先级更高的中断。这就是所谓的中断嵌套。
  • 悬起中断的自动清除:通常,NVIC在执行完中断服务程序后,会自动清除该中断的悬起状态。然而,某些中断可能需要手动清除悬起标志,具体取决于外设和应用程序的设计。

 

Fault异常

 总线Fault 

总线Fault是指当处理器尝试访问总线上的设备或内存时发生的错误。这类错误通常与外设、内存或总线控制器等硬件组件相关。

AHB 回复的错误信号会触发总线 fault的原因有:
  • 企图访问无效的存储器 region。常见于访问的地址没有相对应的存储器。
  • 访问某个外设时,外设无法正常响应(如无法执行读写操作)。
  • 在企图启动一次数据传送时,传送的尺寸不能为目标设备所支持。例如, 某设备只接受字型数据,却试图送给它字节型数据。
  • 因为某些原因,设备不能接受数据传送。例如,某些设备只有在特权级下 才允许访问,可当前却是用户级。
  • 多主设备同时访问同一总线,导致仲裁冲突。

 在发送Fault后,处理方式如下,

  • 处理器进入总线Fault异常,并执行总线Fault处理程序。
  • NVIC中的Bus Fault Status Register(BFSR)会记录具体的Fault原因,帮助开发者调试和定位问题。

总线Fault也分为精确Fault和不精确Fault,如下,

cef9e3dc92dd4e7296afb0510631f778.png

存储器Fault 

存储器管理 faults 多与 MPU 有关,其诱因常常是某次访问触犯了 MPU 设置的保护规范。

 触发存储器Fault的原因如下,

  • 访问了所有 MPU regions 覆盖范围之外的地址
  • 访问了没有存储器与之对应的空地址
  • 往只读 region 写数据,当代码尝试访问被保护的区域,如只读存储器、不可执行的存储器区域,或特定特权模式下才能访问的区域时
  • 用户级下访问了只允许在特权级下访问的地址
  • Cortex-M3有专门的硬件机制来检测栈溢出。若栈指针超出有效的栈区域(由MPU配置),则会引发存储器访问故障。

 和总线 fault 一样,MemManage fault 必须被使能才能正常响应。

 存储器管理 fault 状态寄存器(MFSR),地址为0xE000_ED28,内容如下,

b9850040bfce4bae864f30a8d9684916.png

备注:在 MemManage fault 发生后,如果其服务例程是使能的,则执行服务例程。如果同时还发生了其它高优先级异常,则优先处理这些高优先级的异常,MemManage 异常被悬起。

用法Fault

用法Fault常见触发原因,

  • 未定义指令: 如果程序执行了无效或未定义的指令(通常是由于代码损坏或编译错误),会触发Usage Fault。

  • 除以零错误: 当程序试图执行整数除以零的操作时,Cortex-M3会产生Usage Fault(除非除零检测被禁用)。

  • 对无效地址的访问: 访问无效地址或者超出合法范围的地址(例如NULL指针)可能导致Usage Fault。

  • 对特权指令的非法访问: 在用户模式下执行特权指令,如修改特权寄存器等,可能会引发Usage Fault。

  • 对协处理器的非法访问: 如果程序试图访问未实现的协处理器指令(Cortex-M3没有FPU,因此对浮点运算单元的非法访问也可能引发此Fault)。

  • 未对齐的内存访问: Cortex-M3内核对某些数据访问要求内存地址对齐。例如,32位访问要求地址是4字节对齐,64位访问需要8字节对齐。如果访问未对齐的地址,可能会导致Usage Fault。

  • 尝试进入 ARM 状态:因为 CM3 不支持 ARM 状态,所以用法 fault 会在切换时产生。

 那我们如何捕获用法Fault,可以使用SCB寄存器捕获错误。

在发生Usage Fault时,SCB的CFSR(Configurable Fault Status Register)寄存器会提供详细的错误信息。

UFSR是CFSR(Configurable Fault Status Register)的一部分,位于该寄存器的高16位,负责记录各种与Usage Fault相关的错误。

f2cf704a2ff24e93b7ffa175c1cc61ee.png

硬Fault 

硬fault 是总线 fault、存储器管理 fault 以及用法 fault 上访的结果。
 
如果这些 fault 的服务例程无法执行,它们就会成为“硬伤”——上访(escalation)成硬 fault。
 
在 NVIC 中有一个硬 fault 状态寄存器(HFSR),它指出产生硬 fault 的原因。

2423aeff0cf046d4b8d80767daeae559.png

 

SVC和PendSV

在Cortex-M3内核中,SVC(Supervisor Call)PendSV(Pending Supervisor Call)是两个与操作系统任务管理密切相关的异常(异常号分别为11和14),通常用于实现系统调用和任务切换等功能。

SVC

SVC指令是一种特权指令,允许程序从用户模式切换到特权模式以执行系统调用。

它通常用于操作系统内核提供的服务,比如任务管理、内存管理或硬件资源的访问。 

在使用操作系统时,应用程序(通常在用户模式下运行)不能直接访问硬件资源,而是通过操作系统提供的接口间接控制硬件。SVC就是这种接口机制的一部分。

SVC工作机制:

  • 用户程序执行一条SVC指令(SVC指令后跟一个立即数,比如0x3,作为系统服务调用的索引)。
  • SVC指令被执行时,处理器自动产生一个SVC异常,这时处理器会切换到特权模式,保存当前上下文,并跳转到操作系统定义的SVC_Handler中断服务例程。
  • SVC_Handler根据传递的立即数,决定要执行的具体系统服务。
  • 处理完用户的系统服务请求后,操作系统返回控制权给用户程序,继续执行剩余的代码。

SVC和操作系统之间的示意图如下,

3487d6dfc77f4d4ab661a65ef552a7f8.png

 备注:我们不能在 SVC 服务例程中嵌套使用 SVC 指令(事实上这样做 也没意义),因为同优先级的异常不能抢占自身。这种作法会产生一个用法 fault。同理,在 NMI 服务例程中也不得使用 SVC,否则将触发硬 fault。

PendSV 

PendSV是Cortex-M3中的另一种异常,主要用于实现任务切换,通常用于延迟或悬挂执行低优先级的任务。

PendSV不会像SVC一样通过指令触发,而是通过设置相关寄存器触发。例如,操作系统在需要任务切换时,会手动设置PendSV中断悬起位(SCB->ICSR中的PENDSVSET位),来触发PendSV异常。

当需要切换任务时,操作系统会触发PendSV异常,以便保存当前任务状态,并切换到下一个任务。

PendSV的典型应用场景:

  • 任务调度:在RTOS中,PendSV用于触发任务调度器。每次任务切换时,操作系统会触发PendSV,保存当前任务状态并恢复下一个任务的状态。
  • 延迟任务处理:由于PendSV的优先级最低,它通常被用于在中断结束后,处理低优先级的任务或操作系统调度操作。

PendSV异常处理流程:

  1. 操作系统检测到需要任务切换时,设置PendSV。
  2. 当没有其他高优先级中断需要处理时,处理器进入PendSV异常。
  3. 操作系统保存当前任务的上下文任务的寄存器、堆栈指针),选择下一个任务,并恢复它的上下文。

 备注:PendSV中断的优先级为最小,当然也可以通过NVIC进行修改。

PendSV 的典型使用场合是在上下文切换时(在不同任务之间切换)。

下面我们来看看为什么需要PendSV悬起,来延迟执行上下文切换。

假设有这么一个系统,里面有两个就绪的任务,并且通过 SysTick 异常启动上下文切换。
 
正常情况如下,
  3c3ac3af6d7d49efa67568b19a507caa.png

也就是当滴答定时器的时间到达以后,正常进行任务的上下文切换,但是有这样一种情况,就是现在SysTick中断触发的那一刻,处理器正在执行其他中断服务程序(ISR) ,由于滴答定时器中断的优先级一般比外部中断优先级高,那么滴答定时器中断就会抢占外部中断ISR,导致外部中断只能等滴答定时器中断执行完上下文切换在继续进行,但是这是会产生冲突的,因为一般的中断的优先级都比任务切换的优先级高,就会发生一些不好的事(具体的大家可以自行搜索),图解如下,

3851bc75d72a4a19b00e3b5983dad2b6.png

为了处理这个问题,PendSV中断就可以完美解决这个问题。

当出现上述情况时,滴答定时器的服务函数只会调用PendSV中断,将PendSV悬起,由于PendSV的优先级设置为最低优先级,这时候虽然滴答定时器触发仍然会抢占之前的外部中断(ISR),但是并不会在这期间进行任务切换,因为任务切换选择在PendSV中进行,此时ISR仍然继续执行,确切的说当所有的高优先级中断都执行完后,此时会触发之前悬起的PendSV,并在其中断服务函数中进行上下文切换,很好的避免上下文切换和中断一起进行这个问题。

图解如下,

e536e56b3425451abc7de8fff7ef32de.png

备注:由于一般中断服务函数中所执行的程序都非常短,所以不必担心在处理PendSV时前面的高优先级中断处理很长时间,任务之间切换不会被显著延迟。

 

总结 

SVC与PendSV的对比

88aef8757da84024a2b7a93b123747dd.png

  • SVC(Supervisor Call,系统服务调用):用于执行系统服务调用,例如创建任务、删除任务、启动调度等。它通过SVC指令触发,可以从用户模式切换到特权模式,执行内核级的操作。

  • PendSV(Pending Supervisor Call,可悬起系统调用):主要用于任务切换。在需要任务切换时,通过触发PendSV中断来保存当前任务的上下文,并恢复下一个任务的上下文。

 

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

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

相关文章

docker进入容器运行命令详细讲解

​ 大家好,我是程序员小羊! 前言: 在 Docker 中,进入容器并运行命令是常见的操作,尤其是当你想要调试、检查日志或手动运行某些程序时。Docker 提供了几种方式来进入容器和执行命令。 前提条件 确保你的 Docker 容器…

C++基础面试题 | 什么是C++中的虚继承?

文章目录 回答重点菱形继承问题虚继承解决菱形继承问题虚继承的二义性解决 虚继承总结拓展知识:virtual关键字的用法1. 虚函数 (Virtual Function)2. 纯虚函数 (Pure Virtual Function)3. 虚析构函数 (Virtual Destructor)4. 虚继承 (Virtual Inheritance)5. 虚函数…

一篇文章带你入门机器学习 Part1 -->Machine Learning from Scratch

学习网站:Machine Learning from Scratch Machine Learning from Scratch (Part1神经网络) 神经网络——Neural Networks神经网络是如何工作的?训练神经网络 神经网络——Neural Networks 在人工神经网络的背景下:一个神经元是一…

046全排列

题意 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 提示&#xff1a; 1 < nums.length < 6 -10 < nums[i] < 10 nums 中的所有整数 互不相同 难度 中等 示例 示例 1&#xff1a; 输入&#xff1…

uniapp+若依 开发租房小程序源码分享

1、使用Uniapp开发的前台&#xff0c;基于 Vue.js 开发所有前端应用的框架&#xff0c;开发者编写一套代码&#xff0c;可发布到iOS、Android、Web&#xff08;响应式&#xff09;、以及各种小程序 2、基于SpringBoot的权限管理系统&#xff0c;易读易懂、界面简洁美观。 核心…

WordBN字远笔记!更新1.2.2版本|Markdown编辑器新增高亮功能,界面新增深色模式

WordBN字远笔记1.2.2版本更新描述 WordBN字远笔记在1.2.2版本中进行了多项重要的更新与改进&#xff0c;旨在提升用户的编辑体验和视觉舒适度。 以下是本次更新的两大亮点&#xff1a;Markdown编辑器新增高亮功能以及界面新增深色模式。 1. Markdown编辑器新增高亮功能 在1…

零倾覆力矩点(ZMP)

系列文章目录 前言 在机器人学中&#xff0c;零倾力矩点&#xff08;ZMP&#xff09;是一个特征点&#xff0c;主要用于足式运动。在下文的一些假设中&#xff0c;我们将看到&#xff0c;它非正式地代表了一个系统接触反作用力的结果点。例如&#xff0c;下图中的刚体处于静态平…

leetcode:布尔运算(动态规划版)

最近又要考试&#xff0c;勉励自己复习一些之前学过的&#xff01;&#xff01;&#xff01; 开始使用的是DFS&#xff0c;遍历所有可能的情况&#xff0c;发现超时&#xff01; 下面的是动态规划的一个模板&#xff0c;dp[i][j][result]表示从s的第i个元素到第个元素&#xf…

Auracast认证:蓝牙广播音频的革新之旅

低功耗音频&#xff08;LE Audio&#xff09;技术的突破&#xff0c;为蓝牙世界带来了前所未有的广播音频功能。Auracast™&#xff0c;作为蓝牙技术联盟精心打造的音频广播解决方案&#xff0c;正引领着一场全新的音频分享革命。它不仅革新了传统蓝牙技术的局限&#xff0c;更…

HuggingFace Embedding 转为 Ollama Embedding

Ollama 是基于 LlamaCpp 开发的 CPU 上的推理引擎&#xff0c;通过 LlamaCpp 提供的脚本可以将大语言模型装换为 gguf 的二进制跟是文件&#xff0c;从而通过 Ollama 就行推理。Ollama 支持HuggingFace 大多开源模型&#xff0c;例如 Llama、Qwen、Gemma 和 Phi3 等等。 GGUF …

【Leetcode:2848. 与车相交的点 + 模拟计数】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

软件研制功能点拆分

最近需要进行软件研制概算明细表中的估算对象原始功能点&#xff0c;记录一下学习过程&#xff0c;共有EI(external input 外部输入)、EO(外部输出)、EQ(外部查询)、ILF(internal logic 内部逻辑文件)、EIF(外部接口文件)五个。 功能点计数项分为数据功能&#xff08;逻辑文件&…

【数据仓库】数据仓库常见的数据模型——范式模型

目录 一、范式 1、第一范式 2、第二范式 3、第三范式 4、进一步范式化&#xff1a;BCNF、4NF 和 5NF 简介 &#xff08;1&#xff09;Boyce-Codd 范式&#xff08;BCNF&#xff09; &#xff08;2&#xff09;第四范式&#xff08;4NF&#xff09; &#xff08;5&#x…

光华里社区“电亮生活”行动:智能科技携手志愿温情,老旧小区焕发新生机

在朝阳区建外街道光华里社区&#xff0c;一场关于“电”的革命正悄然改变着居民的生活面貌。面对老旧小区普遍存在的电力设施陈旧、线路老化、电压不稳等老大难问题&#xff0c;社区党委没有坐视不管&#xff0c;而是携手北京中兴物业管理有限公司广联物业管理中心党支部&#…

泽众P-One性能测试平台支持分布式全链路压测

在当今数字化转型加速的时代&#xff0c;高性能、高可用性的系统已成为企业竞争力的核心要素之一。为了确保系统能够在高并发、大数据量的环境下稳定运行&#xff0c;分布式全链路压测成为了不可或缺的一环。P-One凭借其强大的功能&#xff0c;支持分布式全链路压测&#xff0c…

什么是 SMB 服务器以及它如何工作?

在本文中&#xff0c;您将了解 SMB 服务器以及它们如何促进网络文件共享。 我们将介绍它们的基本功能、主要特性以及如何安全地设置它们。无论您是新手还是需要复习&#xff0c;本指南都将帮助您更好地了解 SMB 服务器。 什么是 SMB 服务器&#xff1f; SMB&#xff08;服务器…

day19JS-AJAX数据通信

1. 什么是AJAX 原生生js中有两种通信&#xff0c;一个ajax&#xff0c;还有一个是fetch。 AJAX 并不是编程语言&#xff0c;是一种从网页访问 Web 服务器的技术。AJAX 代表异步 JavaScript 和 XML。 AJAX 使用浏览器内建的 XMLHttpRequest 对象从 web 服务器请求数据&#xff0…

【开放词汇检测】MM-Grounding-DINO论文翻译

摘要 Grounding-DINO 是一种先进的开放式检测模型&#xff0c;能够处理包括开放词汇检测&#xff08;Open-Vocabulary Detection&#xff0c;OVD&#xff09;、短语定位&#xff08;Phrase Grounding&#xff0c;PG&#xff09;和指代表达理解&#xff08;Referring Expressio…

Java多线程——模拟接力赛跑

题目&#xff1a; 多人参加1000米接力跑 每人跑100米&#xff0c;换下个选手 每跑10米显示信息 解题思路&#xff1a; 1.必须要用到多线程的锁&#xff0c;否则就会出现三个选手乱跑的情况&#xff0c;我们需要一个一个跑 2.使用给oneRunner上锁的方式更细的控制资源比直接给…

qt画板v1.0

qt图形视图做的一个工具&#xff0c;具备画板功能&#xff0c;对初学习有很大作用