之前介绍了了ARM异常处理(1):异常类型、优先级分组和异常向量表,里面有很多异常类型,其中有几个异常在错误处理中非常有用:

文章目录

  • 1 Bus Fault
  • 2 Memory Management Fault
  • 3 Uage faults
  • 4 Hard Faults

1 Bus Fault

当在AHB接口上传输期间收到错误响应时,就会产生Bus fault。它可能发生在以下几个阶段:

  • 指令预取阶段,通常称为prefetch abort
  • 数据读/写阶段,通常称为data abort

在Cortex-M3中,出现下面几种情况也会产生Bus fault

  • 堆栈在中断处理的开始处PUSH,称为stacking error
  • 堆栈在中断处理的结束处POP,称为unstacking error
  • 当处理器开始中断处理序列时,读取中断向量地址(vector fetch)(Hard fault的一种特殊情况)
特点:

如果没有使能Bus fault的处理程序或总线错误发生在其它的比Bus fault优先级高的异常的异常处理程序时,Hard fault的中断处理函数会取代bus fault执行。如果在处理Hard fault的过程中产生了另一个Bus fault,则内核将会进入锁定状态。


导致AHB错误响应的常见原因

  • 尝试访问一个无效的内存区域
  • 设备没有准备好传输(如没有初始化外设的情况下访问外设)
  • 目标设备不支持的单词传输大小(如某个外设寄存器仅支持按字访问,而程序中按字节访问)
  • 设备不接受传输(如某些外设只能在特权访问级别编程)

1、如何使能Bus fault的处理程序?
设置NVIC中的System Handler Control and State registerBUSFAULTENA位,在此之前,需要保证在中断向量表中设置了Bus fault处理程序的起始地址。

2、进入Bus fault处理程序时,如何判断是什么出错了?
    NVIC有很多错误状态寄存器(Fault Statuc registers),其中有一个就是总线错误状态寄存器(Bus Fault Status register,BFSR),从这个寄存器中可以知道错误时由数据/指令访问还是中断堆栈等原因产生的。
    如果想更精确地定位Bus fault,可以通过堆栈程序计数器来定位错误的指令,且如果BFSR中的BFARVALID位为1的话,则还可以通过读取总线错误地址寄存器(Bus Fault Address Register,BFAR)来确定导致Bus fault的内存位置。

  • 在有些情况下,这些寄存器的信息是不准确的,因为当处理器接收到错误时,可能已经执行的了很多其它指令。比如,对于往一个buffer写入数据而言,如果产生错误可能在多个时钟周期后才产生Bus fault,这称为unprecise bus fault ;而对于读取内存来说,下一条指令在读取完之前无法执行,故此时产生错误会立即产生Bus fault,这称为precise bus fault

Bus Fault Status Register位于内存地址的0xE000ED29处,它的字段如下:

Bits Name Type Reset Value Description
7 BFARVALID - 0 指示BFAR是否有效
6:5 - - - -
4 STKERR R/Wc 0 Stacking error
3 UNSTKERR R/Wc 0 Unstacking error
2 IMPRECISERR R/Wc 0 Imprecise data access violation
1 PRECISERR R/Wc 0 Precise data access violation
0 IBUSERR R/Wc 0 Instruction access violation
  • 访问该寄存器可以按字节访问0xE000ED29,也可以按字访问0xE000ED28后得到第二个字节
  • 向错误指示位写入1时将清除该位的状态

2 Memory Management Fault

内存管理错误可能由非法访问MPU(内存保护单元Memory Protection Unit)或某些非法访问(如执行某些不可执行的内存区域的代码)引起。常见的MPU错误如下:

  • 访问MPU中未定义的内存区域
  • 往只读区域写入数据
  • 用户状态下访问特权模式下才能访问的内存

内存管理错误处理函数与Bus fault一样,有一样的特点,这里不再重复介绍。使能内存管理错误的处理函数,需要设置NVIC中的System Handler Control and State registerMEMFAULTENA位。

NVIC包含一个内存管理错误状态寄存器(Memory Management Fault Status Register,MFSR)来指示内存管理故障的原因。如果状态寄存器中的数据访问非法(DACCVIOL)位或指令访问违反(IACCVIOL位)为1,则可以通过堆栈程序计数器定位错误的代码。如果设置了MFSR中的MMARVALID位,也可以从NVIC中的内存管理地址寄存器(Memory Management Address Register,MMAR)中确定引起错误的内存地址位置。

MFSR寄存器如下表所示,它的地址为0xE000ED28,字段如下:

Bits Name Type Reset Value Description
7 MMARVALID - 0 指示MMAR是否有效
6:5 - - - -
4 MSTKERR R/Wc 0 Stacking error
3 MUNSTKERR R/Wc 0 Unstacking error
2 - - - -
1 DACCVIOL R/Wc 0 Data access violation
0 IACCVIOL R/Wc 0 Instruction access violation
  • 访问该寄存器可以按字节或按字访问0xE000ED28
  • 对于其它FSRs,向错误状态位写入1时将清除错误状态

3 Uage faults

Usage faults可能由以下几种情况引起:

  • 未定义的指令
  • 协处理器指令(Cortex-M3不支持协处理器)
  • 尝试切换到ARM state(可以使用这种机制来测试处理器是否支持ARM state;Cortex-M3不支持,如果切换会发生使用错误)
  • 无效的中断返回(LR寄存器包含无效/不正确的值)
  • 对未对齐的内存使用多个load/store指令

通过设置NVIC的某些位,也可以产生下面两种Usage fault

  • 除法除以0
  • 访问任何不对齐的内存

Usage faults处理程序与Bus fault一样,有一样的特点,使能Usage faults的处理程序,需要设置NVIC中的System Handler Control and State registerUSGFAULTENA位。

NVIC包含一个使用错误状态寄存器(Usage Fault Status Register,UFSR)来指示使用错误的原因。在处理程序内部,还可以使用堆栈的程序计数器值来定位导致错误的程序代码。


导致Usage fault的原因之一:切换到ARM state
Usage fault最常见的原因之一就是无意中将处理器切换到ARM state,这会在用户将一个LSB为0的地址加载到PC之后产生。比如,我们想使用BXBLX指令跳转到一个没有设置地址的LSB,在异常向量表中向量的LSB为0;或者要POP已经在堆栈中的PC值,而LSB为0。在这些情况下,Usage fault会产生,UFSR寄存器中的INVSTATE会被置位。

  • 最低位LSB为1表示使用Thumb state

UFSR寄存器如下表所示,它的地址为0xE000ED2A,字段如下:

Bits Name Type Reset Value Description
9 DIVBYZERO R/Wc 0 指示是否是除以0引起的错误(需要设置DIV_0_TRP)
8 UNALIGNED R/Wc 0 指示是否是字节没对齐引起的错误
7:4 - - - -
3 NOCP R/Wc 0 尝试执行协处理器指令
2 INVPC R/Wc 0 尝试执行EXC_RETURN中错误返回值的异常
1 INVSTATE R/Wc 0 尝试切换为一个无效的状态(如ARM state)
0 UNDEFINSTR R/Wc 0 尝试执行一个未定义的指令
  • 访问该寄存器可以按字节访问0xE000ED2A,也可以按字访问0xE000ED28后得到其最高字节
  • 对于其它FSRs,向错误状态位写入1时将清除该位的错误状态

4 Hard Faults

如果Usage faultsBus faultsMemory management faults没有其对应的错误处理程序,都将产生一个Hard fault。此外,它也会由在异常处理程序执行过程中读向量表(vector fetch)产生的Bus fault而引起。NVIC中有一个硬件错误状态寄存器(HFSR,Hard Fault Status Register),可用于确定错误是否由vector fetch引起。如果不是,则Hard fault的错误处理程序需要检查其他FSRs以确定Hard fault的原因。

HFSR寄存器与其它FSRs一样,错误状态可以通过写入1来清除,该寄存器的地址为0xE000ED2C,其字段如下:

Bits Name Type Reset Value Description
31 DIVBYZERO R/Wc 0 指示错误是否由debug事件引起的
30 FORCED R/Wc 0 指示错误是否是由Usage faultsBus faultsMemory management faults产生的
29:2 - - - -
1 VECTBL R/Wc 0 指示错误是由vector fetch引起的
- - - - -

ARM异常处理(3):Bus faults、Memory management faults、Usage faults、Hard faults详解相关推荐

  1. 编译arm linux内核,编译Linux内核(下)---KConfig、Makefile详解以及ARM平台Linux内核的编译...

    转载自:http://blog.csdn.net/newthinker_wei/article/details/8022696 本文主要介绍Linxu2.6的内核配置系统. 如果你浏览一下源代码目录, ...

  2. Objective-C Memory Management Being Exceptional 异常处理与内存

    Objective-C Memory Management    Being Exceptional  异常处理与内存 3.1Cocoa requires that all exceptions mu ...

  3. 异构内存管理 Heterogeneous Memory Management (HMM)

    https://www.kernel.org/doc/html/latest/vm/hmm.html 目录 异构内存管理 (HMM) 使用特定于设备的内存分配器的问题 I/O 总线.设备内存特性 共享 ...

  4. MIT 6.828 (二) Lab 2: Memory management

    Lab 2: Memory management 做这个实验之前首先需要知道什么是分页.分段在这个实验里面没用到过. 前面是一大堆教你怎么获取lab2资源的,我不知道怎么弄,后来乱搞了一下,就把lab ...

  5. 如何展开Linux Memory Management学习?

    Linux的进程和内存是两座大山,没有翻过这两座大山对于内核的理解始终是不完整的. 关于Linux内存管理,在开始之前做些准备工作. 首先bing到了Quora的<How can one rea ...

  6. 《modern operating system》 chapter 3 MEMORY MANAGEMENT 笔记

    MEMORY MANAGEMENT The part of the operating system that manages (part of) the memory hierarchy is ca ...

  7. SMMU-System Memory Management Unit

    在计算机领域,输入输出内存管理单元(英语:input–output memory management unit,缩写IOMMU)是一种内存管理单元(MMU),它将具有直接記憶體存取能力(可以DMA) ...

  8. Item 36. Class-Specific Memory Management

    Item 36. Class-Specific Memory Management 在类中声明operator new 和 operator delete 成员就可以实现类自己的内存分配与管理. cl ...

  9. [翻译] - Inside SQL Server 2000's Memory Management Facilities

    原文地址:Inside SQL Server 2000's Memory Management Facilities     翻译:RicCC Ken Henderson     Microsoft ...

最新文章

  1. 如何成为一名无人驾驶工程师
  2. java typeof_js中typeof的用法汇总
  3. api 定位 微信小程序 精度_一行代码区分微信小程序或QQ小程序
  4. 使用amap-js引入高德地图AMap及其UI组件AMapUI
  5. gradle构建_指定Gradle构建属性
  6. LeetCode 1940. 排序数组之间的最长公共子序列(二分查找)
  7. Linux学习笔记-消息队列的接收
  8. 一大波PyTorch图像分割模型来袭,俄罗斯程序员出品新model zoo
  9. DHCP原理及报文格式
  10. Git 合并代码操作失误,Rebase current,导致拉取代码一直冲突
  11. jwt重放攻击_JWT+ASP.NET MVC 时间戳防止重放攻击
  12. 信息安全应急预案整理
  13. pyecharts、plotly图表插入PPT中
  14. 天猫整站(简易版)SSM(十四)需要登录才能使用的功能
  15. 这年代,你需要了解一下什么是聚合搜索(附站点推荐)
  16. 贴吧签到助手 服务器版
  17. 相似度度量的不同方法
  18. SRAM、PSRAM、SPI FLASH初步认识
  19. 启锐 588 打印机每次打印都流出一部分,没有重新切换纸张
  20. dellemc服务器中文语言设置,美版windows10系统设置中文语言的方法

热门文章

  1. 身为实验室管理者的你,需要知道的实验室物联网!
  2. 协众信息ui设计岗位招聘要求有哪些?
  3. ProCAST 2014砂型铸造分析基础到高级案例视频教程
  4. GAN生成哆啦A梦,亲测训练50000epoch
  5. 在谷歌浏览器chrome上安装tampermonkey插件
  6. 【夯实Spring Cloud】Spring Cloud中使用Hystrix实现断路器原理详解(上)
  7. 基于C的双声道PCM文件数据处理
  8. django中bulk_create返回id的三种实现
  9. Insar 课程学习
  10. 从程序员到半个CTO