• 嵌入式养成计划-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
    
    • 1
    • 2

    135.4.4 软中断代码编写

    .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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
  • 相关阅读:
    固有时间尺度分解(Intrinsic Time Decomposition,ITD)
    Unity3D Shader新手入门教程:3D溶解与腐蚀特效详解
    解决方案:解决https页面加载http资源报错
    web前端面试-- 手写原生Javascript方法(new、Object.create)
    Selenium结合Jenkins进行持续集成
    分布式系统中的乐观和错误假设
    chrome 插件开发指南
    WPF不弹出控件的情况下,将控件内容生成截图
    电脑重装系统后usbcleaner怎么格式化u盘
    Mysql事物详解(重要)
  • 原文地址:https://blog.csdn.net/qq_52625576/article/details/134410243