ARM异常处理(3):Bus faults、Memory management faults、Usage faults、Hard faults详解
之前介绍了了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 register
的BUSFAULTENA
位,在此之前,需要保证在中断向量表中设置了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 register
的MEMFAULTENA
位。
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 register
的USGFAULTENA
位。
NVIC包含一个使用错误状态寄存器(Usage Fault Status Register,UFSR
)来指示使用错误的原因。在处理程序内部,还可以使用堆栈的程序计数器值来定位导致错误的程序代码。
导致Usage fault
的原因之一:切换到ARM state
Usage fault
最常见的原因之一就是无意中将处理器切换到ARM state
,这会在用户将一个LSB为0的地址加载到PC
之后产生。比如,我们想使用BX
或BLX
指令跳转到一个没有设置地址的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 faults
、Bus faults
和Memory 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 faults 、Bus faults 和Memory management faults 产生的
|
29:2 | - | - | - | - |
1 | VECTBL | R/Wc | 0 |
指示错误是由vector fetch 引起的
|
- | - | - | - | - |
ARM异常处理(3):Bus faults、Memory management faults、Usage faults、Hard faults详解相关推荐
- 编译arm linux内核,编译Linux内核(下)---KConfig、Makefile详解以及ARM平台Linux内核的编译...
转载自:http://blog.csdn.net/newthinker_wei/article/details/8022696 本文主要介绍Linxu2.6的内核配置系统. 如果你浏览一下源代码目录, ...
- Objective-C Memory Management Being Exceptional 异常处理与内存
Objective-C Memory Management Being Exceptional 异常处理与内存 3.1Cocoa requires that all exceptions mu ...
- 异构内存管理 Heterogeneous Memory Management (HMM)
https://www.kernel.org/doc/html/latest/vm/hmm.html 目录 异构内存管理 (HMM) 使用特定于设备的内存分配器的问题 I/O 总线.设备内存特性 共享 ...
- MIT 6.828 (二) Lab 2: Memory management
Lab 2: Memory management 做这个实验之前首先需要知道什么是分页.分段在这个实验里面没用到过. 前面是一大堆教你怎么获取lab2资源的,我不知道怎么弄,后来乱搞了一下,就把lab ...
- 如何展开Linux Memory Management学习?
Linux的进程和内存是两座大山,没有翻过这两座大山对于内核的理解始终是不完整的. 关于Linux内存管理,在开始之前做些准备工作. 首先bing到了Quora的<How can one rea ...
- 《modern operating system》 chapter 3 MEMORY MANAGEMENT 笔记
MEMORY MANAGEMENT The part of the operating system that manages (part of) the memory hierarchy is ca ...
- SMMU-System Memory Management Unit
在计算机领域,输入输出内存管理单元(英语:input–output memory management unit,缩写IOMMU)是一种内存管理单元(MMU),它将具有直接記憶體存取能力(可以DMA) ...
- Item 36. Class-Specific Memory Management
Item 36. Class-Specific Memory Management 在类中声明operator new 和 operator delete 成员就可以实现类自己的内存分配与管理. cl ...
- [翻译] - Inside SQL Server 2000's Memory Management Facilities
原文地址:Inside SQL Server 2000's Memory Management Facilities 翻译:RicCC Ken Henderson Microsoft ...
最新文章
- 如何成为一名无人驾驶工程师
- java typeof_js中typeof的用法汇总
- api 定位 微信小程序 精度_一行代码区分微信小程序或QQ小程序
- 使用amap-js引入高德地图AMap及其UI组件AMapUI
- gradle构建_指定Gradle构建属性
- LeetCode 1940. 排序数组之间的最长公共子序列(二分查找)
- Linux学习笔记-消息队列的接收
- 一大波PyTorch图像分割模型来袭,俄罗斯程序员出品新model zoo
- DHCP原理及报文格式
- Git 合并代码操作失误,Rebase current,导致拉取代码一直冲突
- jwt重放攻击_JWT+ASP.NET MVC 时间戳防止重放攻击
- 信息安全应急预案整理
- pyecharts、plotly图表插入PPT中
- 天猫整站(简易版)SSM(十四)需要登录才能使用的功能
- 这年代,你需要了解一下什么是聚合搜索(附站点推荐)
- 贴吧签到助手 服务器版
- 相似度度量的不同方法
- SRAM、PSRAM、SPI FLASH初步认识
- 启锐 588 打印机每次打印都流出一部分,没有重新切换纸张
- dellemc服务器中文语言设置,美版windows10系统设置中文语言的方法