【裸机开发】认识中断向量表(设置中断向量偏移的原因)

article/2025/9/13 21:42:23

之前的LED驱动不存在中断,也就不包含中断的初始化。如果程序包含了中断,我们应还需要初始化哪些内容?要解决这个问题,我们需要先了解一个中断系统包含了哪些内容。

中断向量表描述中断对应的中断服务函数,保存在程序开始运行的地方,默认是0x00000000

中断控制器(NVIC、GIC)中断系统的管理机构

中断使能:某个外设的中断使能(要使用某个外设的中断,要先使能这个外设的中断)

中断服务函数:当中断产生时,中断服务函数就会被调用(中断处理逻辑都在中断服务函数中)


目录

一、中断向量表

1、什么是中断向量表?

2、中断类型

二、为什么要设置中断向量表偏移 

1、原因分析

2、如何确定偏移量

3、如何设置

三、汇编编写中断向量表框架


一、中断向量表

1、什么是中断向量表?

中断向量表的作用是描述中断对应的中断服务函数。保存在程序开始运行的地方,默认是0x00000000,可以通过设置中断向量偏移,来改变中断向量表的位置。

Cortex-M 的中断向量表中列举出了所有的中断,每一个中断对应一个中断服务函数;而 Cortex-A 的中断向量表则是将中断分为了 7 类

  • 某个中断发生时,先判断属于哪一类
  • 然后,去中断向量表找对应类的中断服务函数
  • 随后,执行对应的中断服务函数
  • 最后,回到程序暂停的下一个位置

中断向量表所写的就是不同中断类型所对应的中断服务函数地址

2、中断类型

中断大致可以分为七种类型,不同的中断类型对应着一种 CPU 工作模式,当中断产生时,CPU 会先切换到对应的模式,然后再处理中断。其中我们最常用的是 Reset IRQ 中断。

  • ResetCPU 复位以后就会进入复位中断,我们可以在复位中断服务函数里面做一些初始化工作,比如初始化 SP 指针、DDR 等
  • Undefined Instruction:如果指令不能识别的话就会产生此中断
  • SWI:Linux 的系统调用会用 SWI 指令来引起软中断,通过软中断来陷入到内核空间
  • Prefetch Abort:预取指令的出错的时候会产生此中断
  • Data Abort:访问数据出错的时候会产生此中断
  • IRQ外设中断都会引起此中断的发生
  • FIQ:快速中断,如果需要快速处理中断的话就可以使用此中断
偏移地址中断类型中断模式
0x00复位中断(Reset)SVC
0x04未定义指令中断(Undefined Instruction)Undef
0x08软中断(Software Interrupt,SWI)SVC
0x0C指令预取中止中断(Prefetch Abort)Abort
0x10数据访问中止中断(Data Abort)Abort
0x14保留(Reserved)-
0x18IRQ 中断(IRQ Interrupt)IRQ
0x1CFIQ 中断(FIQ Interrupt)FIQ

注意:因为中断向量表是放在程序运行的起始位置,所以这里的偏移位置是相对于起始位置而言的

二、为什么要设置中断向量表偏移 

1、原因分析

中断向量表保存在程序运行的起始位置,默认是 0x00000000。根据参考手册中的内存映射表我们发现, 0x00000000 的位置保存了 boot rom,也就是设备上电启动的相关内容,为了不占用其他部分的内容,我们决定对中断向量表施加一个偏移。

中断控制器(GIC)可以配置中断向量表的偏移位置。裸机开发的环境下,我一般在Reset 中断服务函数中手动指定中断向量表的位置;在有 OS 的环境下,OS 会初始化中断控制器,并将中断向量表放置在一个没有被保留的地址空间中。

2、如何确定偏移量

考虑到 RAM 和 DDR 的范围,我们一般将程序保存在 DDR 中。

  • RAM:CPU内部的一段可用内存,imx6ull内部RAM的大小为128K(0X900000~0X91FFFF)
  • DDR:CPU外的存储器,封装在SOC 中,DDR的大小为 256M 或者 512M(虽然看着有2048,但是受到总线约束,CPU可访问的大小是256M)

DDR 的范围较广,考虑到后续的系统移植,所以使用的是DDR。假设中断向量表设为 0x83000000,其实就是在告诉CPU,中断发生时,到 0x83000000 的位置去找对应的中断服务函数。

其实我们也可以将中断向量表和存储地址都设置成 0x87800000

3、如何设置

通过汇编设置

如果是汇编形式,建议放在 Reset 中断服务函数中,因为设备上电就会触发 Reset 中断,然后去执行 Reset 中断服务函数。

/* 复位中断服务函数 */ 
Reset_Handler:/* ... */ldr r0, =0x87800000         /* 设置中断向量表的偏移 */dsbisbmcr p15, 0, r0, c12, c0, 0dsbisb/* ... */

调用 C 函数

我们可以直接调用 C 函数来设置中断向量表,只要在中断发生之前设置即可。一般放在中断初始化的函数中。

/* 设置中断向量表偏移 */
__set_VBAR((uint32_t)0x87800000);

三、汇编编写中断向量表框架

1、局部流程

中断向量表保存在程序运行的起始位置,默认是 0x00000000。其实就是在告诉内核,每一个中断对应的中断服务函数位置在哪。假设我们要设置 Reset 中断的服务函数地址。

.global _start_start:/* 把 Reset_Handler 的地址保存到 pc 指向的位置 */ ldr pc, =Reset_Handler          /* 复位中断服务函数 */ 
Reset_Handler:b Reset_Handler      @ 暂时先死循环,后面再修改              

pc 是程序计数器,用于保存下一次要执行的指令地址。默认情况下,程序从 0x00000000 开始执行,即 pc 最开始拿到的地址就是 0x00000000,这里其实就把 Reset_Handler 的地址保存到了 0x00000000 的位置。

随后,pc 会指向下一个地址,即 0x00000004。

2、整体框架

其他中断也是类似的,我们借助pc寄存器的地址自动递增的特性,逐个设置各个中断服务函数的地址。至于具体实现,这里有 Reset 中断 和 IRQ 中断的汇编部分。

Reset中断:仅包含汇编部分,因为一般只有在复位或者刚上电的时候才会触发,没有需要特意实现的逻辑。Reset 中断服务函数(汇编部分)

② IRQ 中断:包含汇编部分和 C代码部分。

  • 汇编部分用于初始化环境
  • C 代码部分用于逻辑实现
_start:ldr pc, =Reset_Handler          /* 复位中断 */ ldr pc, =Undefined_Handler      /* 未定义指令中断 */ldr pc, =SVC_Handler            /* SVC(Supervisor)中断*/ldr pc, =PrefAbort_Handler      /* 预取终止中断 */ldr pc, =DataAbort_Handler      /* 数据终止中断 */ldr pc, =NotUsed_Handler        /* 保留中断 */ldr pc, =IRQ_Handler            /* IRQ 中断 */ldr pc, =FIQ_Handler            /* FIQ(快速中断) *//* 复位中断 */ 
Reset_Handler:b Reset_Handler/* 未定义指令中断 */ 
Undefined_Handler:b Undefined_Handler/* SVC */ 
SVC_Handler:b SVC_Handler/* 预取终止中断 */ 
PrefAbort_Handler:b PrefAbort_Handler/* 数据终止中断 */ 
DataAbort_Handler:b DataAbort_Handler    /* 保留中断 */ 
NotUsed_Handler:b NotUsed_Handler /* IRQ 中断 */ 
IRQ_Handler:b IRQ_Handler   /* FIQ(快速中断) */ 
FIQ_Handler:b FIQ_Handler  

http://chatgpt.dhexx.cn/article/WKGSqb1y.shtml

相关文章

linux内核学习10.1:Linux内核ARM7架构异常中断向量表

参考:https://www.cnblogs.com/douzi2/p/5112743.html 当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。在异常中断处理程序执行完成后,程序返回到发生中断的指令的下一条指令处执行。 说明 Ker…

汇编_修改中断向量表_自定义中断

文章目录 中断向量表介绍索引方式:修改中断向量表 自定义中断思路实现效果:实现代码执行步骤 中断向量表 介绍 在dos系统中,总共设计了256种中断,每个中断都有一个中断号,通过中断号来映射中断程序的地址。为了实现映…

9.2 中断向量表的结构

计算机组成 9 中断和异常 9.2 中断向量表的结构 我现在已经知道了,在运算的时候 一旦遇到了异常情况,就翻到第一页的第一行开始写的这些操作的指示,开始往下执行。开始往下执行,这就能解决问题了。但是问题在于这段操作&#xff0…

中断向量表的重印射

基于HAL库 以STM30F303RBT6为例: 打开system_stm32f3xx.c文件,修改其中的中断向量表位置,修改flash offset即可。 下载的位置也,也需要修改 做远程升级时,需要在单片机启动前运行一个boo程序,在boot程序中…

嵌入式杂谈之中断向量表

虽说接触了好久的单片机或者说嵌入式开发,不过对于有些概念还是比较模糊,因此此系列将会从一些零碎的小知识点出发,慢慢的遍历整张嵌入式开发的地图。 这次先来看一下中断向量表。 至于为什么会提到中断向量表,主要是因为我自己…

中断向量表--

中断向量表如何确定中断的入口地址? 每个中断对应一个中断号,比如一个中断事件的中断号为0x00,那么它对应的中断程序的入口地址就是0x0000-0x0003,另一个中断事件的中断号为0x01,那么它对应的中断程序的入口地址就是0…

一文了解Cortex-M中断向量表对齐原则

关注星标公众号,不错过精彩内容 来源 | 痞子衡嵌入式 一、Cortex-M中断向量表对齐原则 中断向量表就是一个集中保存系统全部中断处理函数(xxxIRQHandler)地址的常量数组(函数地址要占 4 个字节,因此数组中每个元素大小…

STM32中断向量表复制到SRAM中运行

1、生成Map文件 复制中断向量表前需要知道中断向量表的大小,可以通过编译生成的Map文件查看。 2、查看中断向量表大小 中断向量表的大小是固定的,与程序代码量无关,打开Map文件,直接搜索0x08000000,我使用的 MCU 是…

通过GDK8观察ARM框架下的中断向量表

一、中断向量表介绍 中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。 以上是中断在百度百科中些较为浅显的解释,中断实际…

【STM32】中断向量表

我是通过这个进行学习的,我觉得讲的很好,这里我稍加修改,作为自己的学习笔记: 嵌入式杂谈之中断向量表 前言 STM32根据boot引脚的配置方式有3种启动方式,但是无论哪一种方式,对于STM32来说都是从0x0000 0000启动 ST…

Cortex M4 中断向量表

前言 重新学习Cortex M4的中断向量表内容。中断向量表是Cortex M4自带的功能,厂家可以根据需要自行定义,所以需要学习该内容,直接看Cortex M4内核相关即可。我这查看的是《Cortex M3与M4权威指南.pdf》。 一、中断向量 中断向量是什么&…

中断向量表

关于中断向量的几点注释 1. 系统引导时,中断向量表放在内存何处? 系统刚引导时,内存0x00000到0x0003FF共1KB的空间用于存放中断向量表。每个中断向量占用4个字节,共可存储256个中断向量。 2. 系统引导时,处在实模式下,只可寻址1MB,为什么要用4个字节来寻址中断呢处理程…

TF_REPEATED_DATA ignoring data with redundant timestamp for frame left_wheel at time

使用urdf和xacro编写机器人仿真模型的时候,同时开启gazebo和rviz的时候遇到的问题 ubuntu20.04 ros noetic 开启gazebo并启动rviz时,rviz终端会一直产生一个警告:TF_REPEATED_DATA ignoring data with redundant timestamp for frame left…

ProtoBuf(Google Protocol Buffers)—— repeated 修饰字段注意点(packed修饰)

ProtoBuf—— (repeated 修饰 ) repeated1、定义2、使用事项 参考 repeated 1、定义 repeated类型相当于STL的vector,可以用来存放N个相同类型的内容。proto2 中还有 repeated 可选,在proto3 中则已经被摒弃并且默认格式为pack。…

Responder

在hack the box 最后一个sql注入题时,有这个工具的使用,之前没有接触过,看write up上是需要利用两个IP地址,似乎与内网渗透有关,马上查找相关资料,看到底是个什么东东。 什么是Responder 在攻防领域&…

Reverse

IDA中文不显示解决 参考链接 VScode中文乱码解决参考链接 (1 ~ 10攻防世界)(11~20为Buu,近乎为shift F12查找字符串) 1. xxxorrr 题目链接 题目WP 心得:可能会有其它隐藏函数对所需结果进行操作 2. SignIn RSA算法介绍 c是密文,m是明文…

java中@Repeatable的理解

Repeatable是jdk8中新增的注解,使用如Spring中的ComponentScan注解。在没有Repeatable注解的的注解中,在同一个地方使用相同的注解会报错,有了此元注解注解的注解,就可以在同一个地方使用相同的注解。其官方文档如下 The annotati…

TS:解决docker无法启动,报:start request repeated too quickly for docker.service错误-2021.12.08(已解决)

目录 文章目录 目录1、报错现象2、解决办法3、总结关于我最后 1、报错现象 首先,我当前的环境是:docker 20.10.11,vmworkstation虚机 很奇怪,自己的docker用着用着就出现问题了,查看服务发现起不来,重启docker服务也…

【已解决】TF_REPEATED_DATA ignoring data with redundant timestamp for frame

目录 1 问题背景2 问题探索3 问题解决4 告别Bug 1 问题背景 环境:Ubuntu20.04 ROS-noetic 现象:打开Rviz与Gazebo加载机器人模型时,终端不停刷新警告TF_REPEATED_DATA ignoring data with redundant timestamp for frame,且在未施…

已解决(一分钟)TF_REPEATED_DATA ignoring data with redundant timestamp for frame base_footprint at time解决方案

<1>问题描述 前言-仿真实验需求&#xff1a;获取小车的全局坐标系下的位姿信息&#xff0c;因此使用gmapping建图&#xff0c;并使用地图服务调用发布&#xff0c;自己写了个节点将map坐标系添加到现有的TF树上&#xff0c;最终TF树见最后截图。 进入正题&#xff0c;想…