嵌入式养成计划-54----ARM--异常处理流程

一百三十五、异常处理流程

135.1 arm处理器工作模式

135.2 异常源和异常模式关系

135.2.1 异常源

  • 异常源就是引发处理器进入相应异常模式

135.2.2 对应关系

异常模式 异常源
FIQ模式 FIQ类型异常源 引发处理器进入FIQ模式
IRQ模式 IRQ类型异常源 引发处理器进入IRQ模式
SVC模式 上电复位(RESET) 引发处理器进入svc模式
swi(软中断指令) 引发处理器进入svc模式
undef模式 未定义异常源 引发处理器进入undef模式
abort模式 prefetch abort 引发处理器进入abort模式
data abort 引发处理器进入abort模式

135.2.3 总结

  1. 五种异常模式,对应七种异常源
  2. 异常源具有优先级,复位优先级最高
  3. 根据不同的异常源,进入不同异常模式,执行异常处理程序

135.3 异常处理流程(重点)

135.3.1 框图

135.3.2 保存现场(四大步三小步)

  1. 保存CPSR寄存器中的值,到SPSR_寄存器中
  2. 修改CPSR寄存器中的值
    1. 修改CPSR寄存器中的模式位,修改为对应的异常模式
    2. 修改CPSR寄存器中的T位,T=0为arm状态,执行arm指令集
    3. 根据需要,禁止相应的中断位
  3. 保存函数的返回地址,到LR寄存器中
  4. 修改PC指向异常处理程序的入口

135.3.3 恢复现场

  1. 将SPSR_寄存器中,恢复给CPSR寄存器
  2. 将LR寄存器中的值,恢复给PC

135.3.4 为什么引入异常向量表

  • 问题:修改PC指向异常处理程序的入口 ==> 入口就是一个标签,标签就是函数名,每个人编写的函数名不一致
  • 答:函数名不一致,每个函数名就是地址,arm公司设置异常向量表,通过操作一块地址空间

135.4 异常向量表

135.4.1 什么是异常向量表

  1. 异常向量表是一块寻址空间,这块寻址空间占用32字节,平均分成8份,每份占用4字节空间
  2. 异常向量表存放七种异常源,1份进行保留
  3. 异常向量表地址固定,不可以进行修改
  4. 通过指定异常向量表的基地址,根据偏移地址,可以找到对应的异常源

135.4.2 框图

135.4.3 软中指令

复制代码
软中断指令码:swi
格式:swi 软中断号(0 ~ 0xffffff)====> 0 ~ 16,777,215

135.4.4 软中断代码编写

cpp 复制代码
.text @文本段 
.global _start  @声明一个_start全局函数
    
_start:  @指定汇编中函数入口
    @0.构建异常向量表
        b reset
        b undef_interrupt
        b software_interrupt
        b prefetch_abort
        b data_abort
        b .
        b irq
        b fiq    
reset:            
    @1.系统一上电处于SVC模式,初始化SVC模式栈指针0x40000800
    ldr sp,=0x40000800
    @2. 从SVC模式切换到user模式,初始化user模式栈指针0x40000700
    msr cpsr,#0xD0
    ldr sp,=0x40000700
    @3.r0 = 0x1  r1 = 0x2
    mov r0,#0x1
    mov r1,#0x2
    @4.执行软中断指令 swi 2  ====> 保存现场(四大步三小步)
    swi 2
    @ r0 = r0 + r1 = 0x3
    add r0,r0,r1
    b stop
    
undef_interrupt:
software_interrupt:
    @ 压栈保存现场 r0 = 0x1  r1 = 0x2
    stmfd sp!,{r0-r12,lr}
    @3.r0 = 0x3  r1 = 0x4
    mov r0,#0x3
    mov r1,#0x4
    @4. r0 = r0 + r1 = 0x7
    add r0,r0,r1
    @5. 出栈恢复现场
    ldmfd sp!,{r0-r12,pc}^ @^:将SPSR_<MODE>寄存器中,恢复给CPSR寄存器

prefetch_abort:
data_abort:
irq:
fiq:
        
stop:  @ 声明一个stop函数标签
    b stop     @ 跳转到stop标签下的第一条指令执行 相当于C语言中while(1)
.end
相关推荐
梁洪飞3 小时前
内核的schedule和SMP多核处理器启动协议
linux·arm开发·嵌入式硬件·arm
虚构之人12 小时前
二进制漏洞挖掘(WinAFL Fuzzing)Windows篇
汇编·网络安全·信息安全·系统安全
代码游侠15 小时前
学习笔记——Linux字符设备驱动
linux·运维·arm开发·嵌入式硬件·学习·架构
syseptember1 天前
Linux网络基础
linux·网络·arm开发
代码游侠1 天前
学习笔记——Linux字符设备驱动开发
linux·arm开发·驱动开发·单片机·嵌入式硬件·学习·算法
程序猿阿伟1 天前
《Apple Silicon与Windows on ARM:引擎原生构建与模拟层底层运作深度解析》
arm开发·windows
wkm9561 天前
在arm64 ubuntu系统安装Qt后编译时找不到Qt3DExtras头文件
开发语言·arm开发·qt
unicrom_深圳市由你创科技2 天前
基于ARM+DSP+FPGA异构计算架构的高速ADC采集卡定制方案
arm开发·fpga开发
松涛和鸣2 天前
DAY69 Practical Guide to Linux Character Device Drivers
linux·服务器·arm开发·数据库·单片机·嵌入式硬件
松涛和鸣2 天前
69、Linux字符设备驱动实战
linux·服务器·网络·arm开发·数据库·驱动开发