【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )(一)

简介: 【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )(一)

1. 异常相关概念



(1) 异常

异常定义 :


1.异常简介 : 由于 内部或者外部的一些事件 , 导致 处理器停下正在处理的工作, 转而去处理这些发生的事;

2.处理器状态 : 当遇到异常的时候, 先将处理器状态保存起来, 以便执行完异常处理程序后, 可以恢复处理器状态, 继续执行异常出现点下面的代码;

3.异常同时出现 : 在一个时间点 可以出现 多个异常;

4.异常向量概念 : 当异常发生的时候, 程序被强行从一个固定的内存地址执行, 每个种类的异常都有对应的一固定内存地址, 这个内存地址就是异常向量 ;



(2) 异常类型简介

异常类型 : ARM 架构 支持 七种类型的异常,


1.Reset : 处理器在工作时, 突然 按下重启键, 就会触发该异常;

2.Undefined instructions : 处理器无法识别指令的异常, 处理器执行的指令是有规范的, 如果 尝试执行 不符合要求的指令, 就会进入到该异常指令对应的地址中;

3.Software interrupt (SWI) : 软中断, 软件中需要去打断处理器工作, 可以使用软中断来执行 ;

4.Prefetch Abort (instruction fetch memory abort) : 预取指令失败, ARM 在执行指令的过程中, 要先去预取指令准备执行, 如果预取指令失败, 就会产生该异常;

5.Data Abort (data access memory abort) : 读取数据失败;

6.IRQ (interrupt) : 普通中断;

7.FIQ (fast interrupt) : 快速中断, 快速中断要比普通中断响应速度要快一些;



2. 异常处理



(1) 异常处理

异常处理简介 :


1.异常向量工作机制 : 异常发生时, ARM 处理器会跳转到对应该异常的 固定地址 去执行异常处理程序, 这个 固定的地址 就是异常向量;

2.默认地址 和 高位地址 : 每个中断类型对应两个异常向量, 默认是 Normal address, 如果经过配置, 配置使用高位的异常向量, 就会使用 High vector address 异常向量; 使用 普通 向量 还是 高位向量, 可以使用 CP15 协处理器进行配置;

3.异常 与 地址 一一对应 : 每个异常都对应着一个地址, 出现指定类型的异常时, 就会跳转到该异常对应的地址执行异常处理程序;

4.注意异常向量断点 ( 保留位 ) : 普通向量 ( Normal Vector ) 地址 0x00000014 和 高位向量 ( High Vector ) 地址 0xFFFF0014 暂时没有使用, 为今后的扩展保留;

image.png








二. 异常向量表代码编写





1. 初始化异常向量表模块代码



Start.S 汇编程序解析 :


1.汇编参考文章 : https://blog.csdn.net/shulianghan/article/details/42408137 ;

2.汇编参考手册下载地址 : https://download.csdn.net/download/han1202012/8328375

3.指明汇编代码段 : 使用 .text 宏 指明汇编代码段;

4.标明程序入口标号 : 先使用 .global _start 将 _start 声明成全局符号; 使用 _start: 标明程序的入口标号是 _start;

5.定义标号( 类似于函数名 ) : 定义自定义标号, 格式 标号:, 例如 irq:;


( 1 ) 定义标号执行的指令 : 标号下面定义要执行的指令, 如果想要执行标号下面的指令, 直接跳转到对应标号即可;

( 2 ) 异常执行的代码内容 : 在下面代码的 27 ~ 49 行就是定义了 7 个异常执行操作的 标号 以及要执行的指令 nop; 这些都是异常发生的时候要处理的代码;

( 3 ) 代码示例 : 下面代码定义了一个 irq 标号, 跳转到该标号即开始执行标号下的代码 nop, irq : nop;

6.空操作 : 如果在某个位置执行指令, 不想做任何操作, 可以使用 nop 表示 什么操作都不执行;


7.定义标号 ( 类似于变量 ) : 定义一个标号, 在标号中存放 32 位的值, 定义格式 标号: .word 存储值的内容;


( 1 ) 示例 : _irq: .word irq, 定义 _irq 标号, .word 表示该标号存储的是 32 位值, 这个值的大小就是 irq 地址;

8.分支指令 : 当异常发生的时候, 需要跳转到对应的异常处理指令中;


( 1 ) 分支指令语法格式 : b{条件} 地址, 如果①满足条件, 就跳转到 地址 位置, 如果②不满足条件, 就执行下面的语句, ③如果没有条件, 就是 100% 执行;

( 2 ) 代码示例 : b reset, 异常发生时, 直接跳转到 reset 标号处执行代码;

9.装载指令 :


( 1 ) 装载指令语法格式 : ldr 寄存器, 地址, 将 地址 中存放的数据 装载 到 寄存器中;

( 2 ) 代码示例 :

a.定义标号 ( 函数 ) : 定义要执行的指令的标号 irq , 即跳转到该标号处, 就开始执行标号下面的指令, irq : nop ;

b.定义标号 ( 变量 ) : 定义一个标号 _irq , 用于存放一个 32 位的值, 这里用于存放 上面 定义的标号 地址, _irq .word irq

c.装载地址到 pc 寄存器 : ldr pc, _irq, 将 _irq 标号中存放的值, 这个值是 irq 标号的地址, 就是跳转到该地址去执行指令;

10.完整汇编代码示例 :

@****************************  
@File:start.S  
@  
@异常处理框架  
@****************************  
.text                                   @ 宏 指明代码段  
.global _start                          @ 伪指令声明全局开始符号  
_start:                                 @ 程序入口标志  
        b   reset                       @ reset 复位异常  
        ldr pc, _undefined_instruction  @ 未定义异常, 将 _undefined_instruction 值装载到 pc 指针中  
        ldr pc, _software_interrupt     @ 软中断异常  
        ldr pc, _prefetch_abort         @ 预取指令异常  
        ldr pc, _data_abort             @ 数据读取异常  
        ldr pc, _not_used               @ 占用 0x00000014 地址                            
        ldr pc, _irq                    @ 普通中断异常  
        ldr pc, _fiq                    @ 软中断异常  
_undefined_instruction: .word undefined_instruction @ _undefined_instruction 标号存放了一个值, 该值是 32 位地址 undefined_instruction, undefined_instruction 是一个地址  
_software_interrupt:    .word software_interrupt    @ 软中断异常  
_prefetch_abort:    .word prefetch_abort            @ 预取指令异常 处理  
_data_abort:        .word data_abort                @ 数据读取异常  
_not_used:      .word not_used                      @ 空位处理  
_irq:           .word irq                           @ 普通中断处理  
_fiq:           .word fiq                           @ 快速中断处理  
undefined_instruction:                              @ undefined_instruction 地址存放要执行的内容  
        nop  
software_interrupt:                                 @ software_interrupt 地址存放要执行的内容  
        nop  
prefetch_abort:                                     @ prefetch_abort 地址存放要执行的内容  
        nop  
data_abort:                                         @ data_abort 地址存放要执行的内容  
        nop  
not_used:                                           @ not_used 地址存放要执行的内容  
        nop  
irq:                                                @ irq 地址存放要执行的内容  
        nop  
fiq:                                                @ fiq 地址存放要执行的内容  
        nop  
reset:                                              @ reset 地址存放要执行的内容  
        nop



目录
相关文章
|
7月前
|
算法 编译器 Linux
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
【Qt4 部署】ARM系统上使用Qt 4 进行开发的QWS 等环境变量部署
143 0
|
2月前
|
编译器
【ARM汇编速成】零基础入门汇编语言之基本认识(一)
【ARM汇编速成】零基础入门汇编语言之基本认识(一)
|
2月前
|
存储 编译器 C语言
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)
|
2月前
|
存储 移动开发 C语言
【ARM汇编速成】零基础入门汇编语言之指令集(三)
【ARM汇编速成】零基础入门汇编语言之指令集(三)
|
2月前
|
编译器 C语言 计算机视觉
【ARM汇编速成】零基础入门汇编语言之指令集(二)
【ARM汇编速成】零基础入门汇编语言之指令集(二)
265 0
|
4月前
|
编解码 安全 Linux
基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究
这段内容讲述了国产操作系统背景下,大牛直播SDK针对国产操作系统与Linux平台发布的RTMP/RTSP直播播放SDK。此SDK支持arm64架构,基于X协议输出视频,采用PulseAudio和Alsa Lib处理音频,具备实时静音、快照、缓冲时间设定等功能,并支持H.265编码格式。此外,提供了示例代码展示如何实现多实例播放器的创建与管理,包括窗口布局调整、事件监听、视频分辨率变化和实时快照回调等关键功能。这一技术实现有助于提高直播服务的稳定性和响应速度,适应国产操作系统在各行业中的应用需求。
143 3
|
6月前
|
C语言
程序技术好文:部分ARM汇编指令解读
程序技术好文:部分ARM汇编指令解读
|
7月前
|
安全 NoSQL Linux
《ARM汇编与逆向工程 蓝狐卷 基础知识》
《ARM汇编与逆向工程 蓝狐卷 基础知识》
115 0
|
7月前
|
Linux 开发工具 芯片
玩转 PI 系列 - 如何在 Rockchip Arm 开发板上安装 Docker Tailscale K3s Cilium?
玩转 PI 系列 - 如何在 Rockchip Arm 开发板上安装 Docker Tailscale K3s Cilium?
|
7月前
|
存储 Ubuntu Linux
ARM-Linux开发与MCU开发的不同之处分析
ARM-Linux开发与MCU开发的不同之处分析
75 0