当前位置: 首页 > news >正文

ARM单片机中断处理过程解析

前言

中断,在单片机开发中再常见不过了。当然对于中断的原理和执行流程都了然于胸,那么对于ARM单片机中断的具体处理行为,你真的搞清楚了吗?

今天来简单聊一聊,ARM单片机中断处理过程中的具体行为是什么样的,搞清楚了这些,让你彻底理解中断是如何执行的。

掌握了这些内容后,以后在开发过程中遇到中断问题,可以做到游刃有余。

本篇文章主要梳理一下 Cortex-M3 内核的单片机在处理中断事件的具体行为,以及不同的中断是如何处理的。

中断响应

Cortex-M3 单片机在开始响应一个中断时,会进行以下三个操作:

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

响应中断的第一个动作,就是自动保存现场的必要部分:依次把 xPSR, PC, LR, R12 以及 R3-R0 由硬件自动压入适当的堆栈中。

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

入栈顺序以及入栈后堆栈中的内容,如下图所示。在自动入栈的过程中,把寄存器写入堆栈内存的时间顺序,并不是与写入的空间顺序相对应的。但是机器会保证:正确的寄存器将被保存到正确的位置 。

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

取出中断服务例程地址,从中断向量表中找出正确的异常向量,然后在服务程序的入口处预取指。这部分由指令总线(I-Code总线)完成。

在入栈和取向量操作完成之后,执行中断服务例程之前,还要更新一系列的寄存器:

  • SP:在入栈后会把堆栈指针(PSP 或 MSP)更新到新的位置。在执行服务例程时,将由 MSP 负责对堆栈的访问。
  • PSR:更新 IPSR 位段(PSR的最低部分)的值为新响应的异常编号。
  • PC:在取向量完成后, PC将指向服务例程的入口地址。
  • LR:在出入 ISR 的时候, LR 的值将重新诠释为 “EXC_RETURN”。在异常进入时由系统计算并赋给 LR,并在异常返回时使用它。(后面会讲解 EXC_RETURN)

以上是在响应异常时通用寄存器的变化。另一方面,在 NVIC 中,也会更新若干个相关有寄存器。

在完成以上工作之后,系统开始执行中断服务程序里的指令。当指令执行完毕,进入中断返回处理阶段。

中断返回

当异常服务例程执行完毕后,需要做一个“异常返回”动作,从而恢复先前的系统状态,才能使被中断的程序得以继续执行 。触发中断返回的指令:

有些处理器会使用特殊的返回指令来标示中断返回,例如 8051 就使用 reti。但是在 CM3 中,是通过向 PC 中写入 EXC_RETURN 来识别返回动作的。

在进行中断返回操作后,会进行下面的处理:

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

中断返回值

前面已经讲到,在进入异常服务程序后,将自动更新 LR 的值为特殊的 EXC_RETURN 。这是一个高 28 位全为1的值,只有[3:0] 的值有特殊含义:

当中断服务例程把这个值送往 PC 时,就会启动处理器的中断返回操作。因为 LR 的值是由 CM3 自动设置的,所以只要没有特殊需求,就不要改动它。

总结一下上表,可以得到,合法的 EXC_RETURN 值共3个:

如果主程序在线程模式下运行,并且在使用 MSP 时被中断,则在服务例程中 LR=0xFFFF_FFF9(主程序被打断前的 LR 已被自动入栈)。

如果主程序在线程模式下运行,并且在使用 PSP 时被中断,则在服务例程中 LR=0xFFFF_FFFD(主程序被打断前的 LR 已被自动入栈) 。

这样描述可能比较抽象,不好理解。那就通过两张图来直观感受一下。

主程序运行在线程模式,且使用主堆栈,进入中断后,以及有中断嵌套情况下,模式切换和 LR 的变化如下图。

如果主程序在 Handler 模式下运行,则在服务例程中 LR = 0xFFFF_FFF1(主程序被打断前的LR已被自动入栈)。这时的所谓“主程序”,其实更可能是被抢占的服务例程。事实上,在嵌套时,更深层 ISR 所看到的 LR 总是 0xFFFF_FFF1。

主程序运行在线程模式,且使用进程堆栈的情况下,LR 值的变化如下

通过这两张图,可以很好地理解异常返回值的变化情况。

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

中断嵌套

Cortex-M3 内核单片机支持中断嵌套,即高优先级中断可以抢占低优先级去执行指令。我们要根据实际使用情况,为每个中断建立适当的优先级。

NVIC 和 CM3 处理器会根据优先级的设置来控制抢占与嵌套行为。有了自动入栈和出栈,我们不用担心在中断发生嵌套时,会使寄存器的数据损毁。

我们知道,所有服务例程都只使用主堆栈(MSP)。所以当中断嵌套加深时,对主堆栈的压力会增大:每嵌套一级,就至少再需要8个字,即32字节的堆栈空间(这没算上 ISR 对堆栈的额外需求),并且何时嵌套多少级也是不可预料的。

如果主堆栈的容量本来就已经所剩无几了,中断嵌套又突然加深,则主堆栈有溢出的凶险。堆栈溢出是很致命的,新入栈数据会覆盖掉主堆栈前面的数据,数据遭到了破坏。

若在服务例程返回前混迭区的数据又被更改了,则在执行中断返回后,系统极可能功能紊乱,甚至出现程序跑飞的问题。

要注意的,相同的异常(中断)是不允许重入的。因为每个异常都有自己的优先级,并且在异常处理期间,同级或低优先级的异常是要阻塞的。

因此对于同一个异常,只有在上次实例的服务例程执行完毕后,方可继续响应新的请求。因此,在 SVC 服务例程中,就不得再使用SVC指令,否则将产生 fault 现象。

咬尾中断

Cortex-M3 内核为了缩短中断延迟,新增了 “咬尾中断” 机制。

当处理器在响应某个中断时,如果又发生低优先级或者相同优先级中断,则被阻塞。在当前的中断执行返回后,系统处理悬起的中断时,不再先POP,然后又把 POP 出来的内容PUSH回去;而是继续使用上一个中断已经 PUSH 好的成果。

这么一来,看上去好像后一个中断把前一个中断的尾巴咬掉了,前前后后只执行了一次 入栈/出栈 操作。于是,这两个异常之间的“时间沟”变窄了很多。

晚到中断

CM3 的中断处理还有另一个机制,这就是“晚到的异常处理”。

当 CM3 对某异常的响应序列还处在早期:入栈的阶段,尚未执行其服务例程时,如果此时收到了高优先级异常的请求,则本次入栈就成了为高优先级中断所做的了。

入栈后,将执行高优先级异常的服务例程。可见,它虽然来晚了,却还是因优先级高而优先执行。

比如,若在响应某低优先级 异常#1 的早期,检测到了高优先级 异常#2,则只要 #2 没有太晚,就能以“晚到中断”的方式处理:在入栈完毕后执行ISR #2。

如果 异常#2 来得太晚,以至于已经执行了 ISR #1 的指令,则按普通的抢占处理,这会需要更多的处理器时间和额外的堆栈空间。

在 ISR #2 执行完毕后,则以“咬尾中断”方式,来启动 ISR #1 的执行。

原文作者:【 一起学嵌入式

相关文章:

ARM单片机中断处理过程解析

前言 中断,在单片机开发中再常见不过了。当然对于中断的原理和执行流程都了然于胸,那么对于ARM单片机中断的具体处理行为,你真的搞清楚了吗? 今天来简单聊一聊,ARM单片机中断处理过程中的具体行为是什么样的&#xf…...

关于SEDEX会员与平台的相关问题汇总

【关于SEDEX会员与平台的相关问题汇总】 01.会员资格有效期是多久? Sedex会员资格有效期为12个月,您也可以选择更长期的会员资格。您支付会员年费时,在“订阅信息”框下的“延长订阅期限”中输入年数,即可获得更长的会员资格时效。…...

解读Spring-context的property-placeholder

在spring中&#xff0c;如果要给程序定义一些参数&#xff0c;可以放在application.properties中&#xff0c;通过<context:property-placeholder>加载这个属性文件&#xff0c;然后就可以通过value给我们的变量自动赋值&#xff0c;如果你们的程序可能运行在多个环境中&…...

【Rust】枚举类型创建单链表以及常见的链表操作方法

目录 单链表 用枚举表达链表 枚举enum Box容器 创建节点 1. 创建并打印 2. match 匹配 3. 节点初始化 4.节点嵌套 追加节点 1. 尾插法 2. 链表追加方法 3. 头插法 4. 改写成单链表方法 遍历链表 1. 递归法 2. 递推法 3. 改写成单链表方法 自定义Display tr…...

Excel 两列数据中相同的数据进行同行显示

一、要求 假设您有两个列&#xff0c;分别是A列和B列&#xff0c;需要在C列中找出A列对应的B列的值。 二、方案 方法1&#xff1a;寻常思路 凸显重复项对A列单独进行筛选–按颜色进行排序&#xff0c;然后升序对B列重复上述操作即可 方法2&#xff1a;两个公式 VLOOKUP 纵向查找…...

Windows本地安装配置Qcadoo MES系统

简介 Qcadoo MES是一款功能强大且灵活的开源MES&#xff08;制造执行系统&#xff09;&#xff0c;旨在为制造业务提供全面的管理和监控解决方案。本篇博客将教您如何在Windows操作系统上安装和配置Qcadoo MES系统&#xff0c;以便您能够轻松管理和监控制造过程。 环境要求 …...

涛思数据与拾贝云达成战略合作,携手赋能工业数字化转型

2023 年 7 月 27 日&#xff0c;北京涛思数据科技有限公司&#xff08;以下简称“涛思数据”&#xff09;与广州拾贝云科技有限公司&#xff08;以下简称“拾贝云”&#xff09;于广州签署战略合作协议。双方围绕电力行业的需求与痛点展开积极讨论&#xff0c;就如何量身打造最…...

nginx 配置多域名多站点 Ubuntu

nginx 配置多域名多站点 Ubuntu 一、安装 nginx apt install nginx二、配置文件说明 nginx 的配置文件在 /etc/nginx 目录下&#xff0c;它的默认内容是这样的 root2bd0:/etc/nginx# ll total 72 drwxr-xr-x 8 root root 4096 Jul 31 15:21 ./ drwxr-xr-x 104 root root …...

Docker实践:使用Docker搭建个人开发环境(极简版)

文章目录 说明教程1. 编写 Dockerfile2. 编写 docker-compose.yml3. 使用容器创建容器启动容器进入容器命令行VSCode 4. 关闭容器5. 备份容器导出导入 6. 重置容器 相关资料文章合集详细了解本文在个人电脑上安装 Docker容器使用 NVIDIA 显卡托管镜像运行GUI程序 说明 本文是在…...

SQL从三个表中根据时间分别查询并汇总数量一行展示

需求&#xff1a;如果您要从三个表中根据时间分别查询并汇总数量&#xff0c;然后将结果以时间和数量一行展示&#xff0c;可以使用子查询和条件聚合。 入库主表 入库明细表 出库主表 出库明细表 退货主表 退货明细表 SQL代码 SELECT time,sum(a.inQty) as inQty,sum(a.outQty…...

同样是跨端框架,React会不会被VUE取代?

看到知乎上有比较多的类似问题&#xff0c;正好这两个框架在以往的一些项目中都有实践过&#xff0c;就借着本篇文章说说我个人的看法。 先摆个结论&#xff1a;不会&#xff0c;毕竟各有千秋&#xff0c;除非跨端框架有被更好的概念所替代&#xff0c;又或者App已经彻底过气了…...

Excel·VBA定量装箱、凑数值金额、组合求和问题

如图&#xff1a;对图中A-C列数据&#xff0c;根据C列数量按照一定的取值范围&#xff0c;组成一个分组装箱&#xff0c;要求如下&#xff1a; 1&#xff0c;每箱数量最好凑足50&#xff0c;否则为47-56之间&#xff1b; 2&#xff0c;图中每行数据不得拆分&#xff1b; 3&…...

通过Jmeter压测存储过程

目录 一、存储过程准备&#xff1a; 二、测试工具准备&#xff1a; 三、工具配置及执行&#xff1a; 1、配置JDBC Connection Configuration&#xff1a; 2、配置吞吐量控制器&#xff08;可跳过&#xff09;&#xff1a; 3、配置JDBC Request&#xff1a; 对于存储过程…...

Spring笔记之Spring对IoC的实现

文章目录 IoC控制反转依赖注入set注入注入外部Bean注入内部Bean注入简单类型通过注入方式实现javax.sql.DateSource接口测试简单类型 级联属性赋值&#xff08;了解&#xff09;注入数组注入List集合注入Set集合注入Map集合注入Properties注入null和空字符串不给属性赋值使用 注…...

【eNSP】Telnet远程登录

Telnet远程登录 eNSP软件TelnetTelnet远程登录-路由连接关闭防火墙eNSP根据图1画图路线配置路由端口IP配置路由R1改名配置接口IP 配置路由R2 配置R2的远程登录设置登录用户授权级别退出登录超时时间 Telnet测试 eNSP软件 eNSP(Enterprise Network Simulation Platform)是一款由…...

SOP/详解*和**/python数据结构(iter,list,tuple,dict)/ 解包

一、错误解决合集 1. > combined_seq.named_children() 2. isinstance 2th parameter : must be a type or tuple of types > 改为tuple&#xff0c;不要用列表。改为 LLLayer (nn.Conv2d,nn.Linear) 3. File “test.py”, line 90, in calculate_fin_fout print(“hi”…...

使用webdriver-manager解决浏览器与驱动不匹配所带来自动化无法执行的问题

1、前言 在我们使用 Selenium 进行 UI 自动化测试时&#xff0c;常常会因为浏览器驱动与浏览器版本不匹配&#xff0c;而导致自动化测试无法执行&#xff0c;需要手动去下载对应的驱动版本&#xff0c;并替换原有的驱动&#xff0c;可能还会遇到跨操作系统进行测试的时候&…...

【vue】Vue中debugger报错 unexpected ‘debugger’ statement no-debugger

前言&#xff1a; Vue中debugger报错 unexpected ‘debugger’ statement no-debugger &#xff08;意外的“调试器”语句没有调试器&#xff09; eslink规则没有开启’debugger’ &#xff0c;被规则屏蔽了&#xff0c;需要手动放开 解决方法 方式一&#xff1a; 找到.esl…...

课题方向a

首先在无线感知的研究方向下,辅以深度学习和计算机视觉的技术和知识,可以从事哪些具体课题的研究?请你尽可能多的给出课题名称供我选择 在无线感知的研究方向下,辅以深度学习和计算机视觉的技术,有很多具体课题可以进行研究。以下是一些供您选择的课题名称: 基于深度学习…...

【Matter】基于Ubuntu 22.04 交叉编译chip-tool

编译工程之际&#xff0c;记录一下编译过程&#xff0c;免得后续遗忘&#xff0c;总结下来chip-tool 交叉编译涉及到的知识点&#xff1a; 需要了解如何支持交叉编译&#xff0c;基于GN编译框架需要理解应用库如何交叉编译&#xff0c;理解pkg-config的使用meson 编译&#xf…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...

拟合问题处理

在机器学习中&#xff0c;核心任务通常围绕模型训练和性能提升展开&#xff0c;但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正&#xff1a; 一、机器学习的核心任务框架 机…...