Cortex-A7和Cortex-M7架构处理器取中断向量全流程分析
0 参考资料
Cortex M3权威指南(中文).pdf
ARM Cortex-A(armV7)编程手册V4.0.pdf
1 Cortex-A7和Cortex-M7处理器架构取中断向量全流程分析
1.1 什么是中断向量?
中断向量就是中断服务函数入口地址,例如我们发生了EXTI0中断,就需要执行EXT0中断对应的中断服务函数EXTI0_IRQHandler,这个中断服务函数入口地址就是中断向量。
1.2 什么是中断向量表?
通常来说CPU会有各种各样不同的中断,它们对应的中断服务函数也不一样。CPU为了在中断发生时更快地跳转到对应的中断服务函数响应中断,就人为将中断向量按顺序存储在内存中(一般是Flash),这样就形成了一张映射表。CPU只要知道这片内存的首地址、中断ID、每个中断向量占据的内存空间,就能很快找到中断源对应的中断服务函数,响应中断。以Cortex-M3为例,它的中断向量表部分定义如下:

1.3 什么是中断向量表偏移地址?什么是中断向量表基址?
我们已经知道中断向量表的作用,CPU为了能够访问向量表,需要知道向量表的地址,这个就是中断向量表基址(起始地址)。
为了实现这一目的,有些CPU(如Cortex-M3架构处理器)提供了一个中断向量表偏移寄存器,通过中断向量表相对于存储器首地址的偏移量计算出中断向量表基址。还有些CPU(如Cortex-A7架构处理器)提供了中断向量表基址寄存器,可以直接修改中断向量表基址。
以Cortex-M3为例,它的中断向量表偏移量寄存器定义如下:
注意:
Cortex-M3向量表的起始地址是有要求的:必须先求出系统中共有多少个向量,再把这个数字向上增大到是 2 的整次幂,而起始地址必须对齐到后者的边界上。
1.4 Cortex-M7架构处理器是怎么取中断向量的?
本例以基于Cortex-M7的stm32H743为例,分析Cortex-M7架构处理器是如何取中断向量的。
1.4.1 设置中断向量表偏移地址
在stm32H743复位后首先会执行Reset_Handler函数(此时中断均是失能状态,如果是由BOOT引导的APP,则需要在进入APP前将所有中断失能,避免在中断向量表偏移地址未被正确设置前进入中断导致不可预知的错误)。Reset_Handler函数内容如下:

在SystemInit函数的最后会设置VTOR寄存器,以修改中断向量表偏移地址:

1.4.2 CPU如何查找中断向量?
以stm32官方例程来说,中断向量表被放到了镜像文件的起始位置。查看其启动文件(startup_stm32h743zitx.s)如下:

和stm32H743参考手册定义的中断向量表一一对应:

注:
_estack是栈底地址,由于stm32H743栈向下生长,可以认为这是栈区最高地址。
查看.map文件,找到Reset_Handler、NMI_Handler函数的入口地址:


打开镜像文件,内容如下:

可以看到,Cortex-M7直接将中断向量放入中断向量表中,CPU根据中断ID及中断向量表偏移地址在中断向量表中对应的地址取出中断向量即可。至于为什么镜像中的中断向量是实际的中断向量+1,主要是为了避免产生fault异常:

说明:Cortex-M3处理器仅支持Thumb-2(文中所说的Thumb就是指Thumb-2)模式,企图转入ARM模式将会产生fault异常。
注:关于Thumb、ARM、Thumb-2指令集的说明如下:

Cortex-M7也仅支持Thumb-2指令集,可以看到stm32CubeIDE工程无法切换到其它指令集:

1.4 Cortex-A7架构处理器是怎么取中断向量的?
本例以基于Cortex-A7的stm32MP135为例,分析Cortex-A7架构处理器是如何取中断向量的。
1.4.1 设置中断向量表基地址(首地址)
在stm32MP135复位后首先会执行Reset_Handler函数(此时中断均是失能状态,如果是由BOOT引导的APP,则需要在进入APP前将所有中断失能,避免在中断向量基地址未被正确设置前进入中断导致不可预知的错误)。Reset_Handler函数内容如下:

上图红框标记处开始设置中断向量表基地址。
也就是将Vectors函数的地址作为中断向量表基地址,Vectors函数内容如下:

和Cortex-A7的中断向量一一对应(Reset_Handler对应于Not used):

.align 7表示Vectors函数地址按照2^7字节对齐,也就是按照128字节对齐。有关VBAR寄存器的描述如下:

1.4.2 CPU如何查找中断向量?
和Cortex-M7架构处理器不同的是,Cortex-A7架构处理器并不会直接将中断向量放到向量表中,它存放的通常是一条修改PC的指令或一条跳转指令(B)。官方说明如下:

这是因为Cortex-A7发生中断时不会直接从中断向量表取出中断向量,而是会将PC值修改到中断向量表里中断对应的地址。而这个地址存放的是一条指令,用来跳转到对应的中断服务函数。以stm32MP135为例,其中断向量表如下:

对应的.list文件如下:

可以看到stmMP135采用的就是官方推荐的第二种写法。例如,发生IRQ中断,PC会设置为0x2ffe0118,执行pc, [pc, #28]语句,执行完之后PC值为0x2ffe53bf。之所以是实际中断向量+1,是为了告诉CPU接下来切换到Thumb(Thumb-2)状态,需要执行Thumb(Thumb-2)指令:

为了实现在Thumb(Thumb-2)状态下处理异常/中断,本例在Reset_Handler函数中已经设置了SCTLR寄存器的T位值为1:

相关寄存器说明如下:





说明:当异常/中断发生时CPSR寄存器的T位,会被设置为SCTLR的TE位的值。也就是说进入异常/中断CPU会切换到Thumb(Thumb-2)状态。
注:Cortex-A7所指的Thumb指令集就是Thumb-2指令集,因此本文写成了Thumb(Thumb-2)。

Cortex-A7什么时候在ARM状态?什么时候在Thumb(Thumb-2)状态?

ARM状态只能执行ARM指令,Thumb状态只能执行Thumb指令。当前执行的指令是ARM指令就处于ARM状态,当前执行的指令是Thumb指令就处于Thumb状态。可以通过CPSR寄存器的T位查看CPU处于什么状态,T=0时处于ARM状态,T=1时处于Thumb状态。至于在什么时候切换状态,编译器会帮我们生成能实现正确的代码。
以本文使用的stm32MP135为例,内部bootloader引导程序在SYSRAM中运行,第一个执行的函数就是Reset_Handler函数,它被 attribute ((naked, target(“arm”)))修饰,编译器会将该函数的指令全部编译为ARM指令,对应的函数原型及函数的汇编文件如下:

红框标记处可以看到指令大小均为4字节且全是ARM指令。

2 总结
(1)Cortex-M通过修改中断向量偏移地址来实现对中断向量表基地址修改,限制了它修改的范围。而Cortex-A7可以直接修改中断向量基址,灵活性大大增强,我们可以把中断向量表放到DDR、Flash、SRAM等任意存储器上。
(2)Cortex-M中断向量表存放的是中断向量,Cortex-A7中断向量表存放的是跳转/PC修改指令,通过修改PC来跳转到对应的中断服务函数。
(3)中断发生时,Cortex-M处理器直接在中断向量表找到中断向量并执行对应的中断服务函数。中断发生时,Cortex-A7会跳转中断向量表对应的中断偏移位置,然后执行一条指令修改PC值,跳转到对应的中断服务函数。
(4)Cortex-M7处理器取中断向量流程也适用于Cortex-M3/M4。
相关文章:
Cortex-A7和Cortex-M7架构处理器取中断向量全流程分析
0 参考资料 Cortex M3权威指南(中文).pdf ARM Cortex-A(armV7)编程手册V4.0.pdf1 Cortex-A7和Cortex-M7处理器架构取中断向量全流程分析 1.1 什么是中断向量? 中断向量就是中断服务函数入口地址,例如我们发生了EXTI0中断,就需要执行EXT0中…...
MODELS 2024震撼续章:科技与可持续性的未来交响曲
MODELS 2024国际会议正如火如荼地进行着,每一天都充满了新的发现与启迪,每一场分享都是对技术前沿的一次深刻探索,更是对现实世界可持续性挑战的一次积极回应。现在让我们继续这场科技盛宴,看看小编为您精选几场的学术分享吧~ 会议…...
CICD 持续集成与持续交付
一 、CICD是什么 CI/CD 是指持续集成(Continuous Integration)和持续部署(Continuous Deployment)或持续交付(Continuous Delivery) 1.1 持续集成(Continuous Integration) 持续集…...
“数据面”(Data Plane)是指负责实际数据处理和转发的部分
在计算机网络和服务架构中,“数据面”(Data Plane)是指负责实际数据处理和转发的部分。数据面负责执行具体的网络通信任务,如接收、处理和转发数据包。与数据面对应的是“控制面”(Control Plane)ÿ…...
面试题:MySQL你用过WITH吗?领免费激活码
感谢Java面试教程的Java多线程文章,点击查看>原文 Java面试教程,发mmm116可获取IDEA-jihuoma 在MySQL中,WITH子句用于定义临时表或视图,也称为公共表表达式(CTE)。它允许你在一个查询中定义一个临时结果…...
consul 介绍与使用,以及spring boot 项目的集成
目录 前言一、Consul 介绍二、Consul 的使用三、Spring Boot 项目集成 Consul总结前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是…...
Linux常用命令shell常用知识 。。。。面试被虐之后,吐血整理。。。。
Linux三剑客&常用命令&shell常识 Linux三剑客grep - print lines matching a patternsed - stream editor for filtering and transforming textawkman awk Linux常用命令dd命令ssh命令tar命令curl命令top命令tr命令xargs命令sort命令du/df/free命令 shell 知识functio…...
压力测试指南-压力测试基础入门
压力测试基础入门 在当今快速迭代的软件开发环境中,确保应用程序在高负载情况下仍能稳定运行变得至关重要。这正是压力测试大显身手的时刻。本文将带领您深入了解压力测试的基础知识,介绍实用工具,并指导您设计、执行压力测试,最…...
Linux:LCD驱动开发
目录 1.不同接口的LCD硬件操作原理 应用工程师眼中看到的LCD 1.1像素的颜色怎么表示 编辑 1.2怎么把颜色发给LCD 驱动工程师眼中看到的LCD 统一的LCD硬件模型 8080接口 TFTRGB接口 什么是MIPI Framebuffer驱动程序框架 怎么编写Framebuffer驱动框架 硬件LCD时序分析…...
QT:常用类与组件
1.设计QQ的界面 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> #include <QLineEdit> #include <QLabel>//自定义类Widget,采用public方式继承QWidget,该类封装了图形化界面的相关操作ÿ…...
企业内训|提示词工程师高阶技术内训-某运营商研发团队
近日,TsingtaoAI为某运营商技术团队交付提示词工程师高级技术培训,本课程为期2天,深入探讨深度学习与大模型技术在提示词生成与优化、客服大模型产品设计等业务场景中的应用。内容涵盖了深度学习前沿理论、大模型技术架构设计与优化、以及如何…...
K8S真正删除pod
假设k8s的某个命名空间如(default)有一个运行nginx 的pod,而这个pod是以kubectl run pod命令运行的 1.错误示范: kubectl delete pod nginx-2756690723-hllbp 结果显示这个pod 是删除了,但k8s很快自动创建新的pod,但是…...
数据结构:队列及其应用
队列(Queue)是一种特殊的线性表,它的主要特点是先进先出(First In First Out,FIFO)。队列只允许在一端(队尾)进行插入操作,而在另一端(队头)进行删…...
26个用好AI大模型的提示词技巧
如果你已深入探索过ChatGPT、Microsoft Copilot、风变AI等前沿的生成式AI工具,那么你对“prompt”(提示词)这一核心概念一定有自己的认知。 作为连接你与AI创意源泉的桥梁,“prompt”不仅是触发无限想象的钥匙,更是塑…...
线性表二——栈stack
第一题 #include<bits/stdc.h> using namespace std; stack<char> s; int n; string ced;//如何匹配 出现的右括号转换成同类型的左括号,方便我们直接和栈顶元素 char cheak(char c){if(c)) return (;if(c]) return [;if(c}) return {;return \0;/…...
浏览器发送请求后关闭,服务器的处理过程
之前在开发中,有些后端服务处理非常慢,页面可能会出现504 Gateway time-out的提示,或者服务器还没返回数据,浏览器就关掉了。我们只是看到了浏览器关掉,但是服务器和客户端的状态都是什么样的呢? 问题 在…...
tee命令:轻松同步输出到屏幕与文件
一、命令简介 tee 命令在 Linux 和 Unix 系统中用于读取标准输入的数据,并将其同时输出到标准输出和文件中。简单来说,tee 命令可以用来分割数据流,使其既能够被输出到屏幕,也能够被写入到文件中。 二、命令参数…...
【经验技巧】如何做好S参数的仿测一致性
根据个人经验,想要做好电路板S参数的仿测一致性,如下的相关信息必须被认真对待: 1. PCB叠构(Stack up),仿真模型需要保证设计参数与板厂供应商的生产参数完全一样,这些参数包括: 叠层结构数据;介电常数;损耗因子;蚀刻因子;表面粗糙度。 2. 仿真中,需要保证信号测试…...
js逆向——webpack实战案例(一)
今日受害者网站:https://www.iciba.com/translate?typetext 首先通过跟栈的方法找到加密位置 我们跟进u函数,发现是通过webpack加载的 向上寻找u的加载位置,然后打上断点,刷新网页,让程序断在加载函数的位置 u r.n…...
Spring Boot 进阶-Spring Boot的全局异常处理机制详解
我们知道在软件运行的过程中,总会出现各种各样的问题,各种各样的异常,而程序员的主要任务之一就是解决在程序运行过程中出现的这些异常。在很多程序员开发的代码中我们会看到在关键的地方为了保证程序能够有一个正常的反馈,大量地使用了try catch finally语句。 大量的try …...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
