Cortex-M系列:错误异常

目录

总线错误

1、不存在的地址:

2、未对齐访问

3、对私有外设总线(PPB)的非特权访问和默认的存储器访问权限相冲突

存储管理错误

使用错误

HardFault

参考资料


总线错误

维基的解释为:

In computing, a bus error is a fault raised by hardware, notifying an operating system (OS) that a process is trying to access memory that the CPU cannot physically address: an invalid address for the address bus, hence the name. In modern use on most architectures these are much rarer than segmentation faults, which occur primarily due to memory access violations: problems in the logical address or permissions.[2]

在计算机领域,总线错误是一种由硬件生成的错误,用来告知操作系统,有一个程序正试图访问CPU从物理层面无法访问的内存,即一个对于地址总线来说的无效地址。从大多数当代CPU架构的使用情况来看,总线错误比(存储器区)段错误多得多,后者主要是由于 内存的非法访问(逻辑地址或访问权限问题)引起的。

维基说的总线错误不常见,是针对有已经有完善驱动的操作系统来说的。对于单片机,感觉还是比较常见的。

Cortex-M7用户手册的解释为:(注:个人认为只解释的表象

A BusFault is an exception that occurs because of a memory related fault for an instruction or data memory transaction. This might be from an error detected on a bus in the memory system.

1、不存在的地址:

软件指示CPU去读/写一个具体的物理内存地址。相应地,CPU将这个物理地址写入地址总线,并要求所有有响应这个特定地址的其他硬件设备传回结果。如何没有其他硬件设备响应,则CPU将产生一个异常,声明整个计算机系统无法识别请求的物理地址。

知道内在机理后,“地址不存在”直接取决于其他硬件设备的响应,于是可以解释为以下3总情况:

a\地址真的不存在:

架构上分配的空间,下图所示[3]:

Cortex-M系列:错误异常_第1张图片

但实际使用的就少的说,可参见STM32H7编程手册“Table 7. Memory map and default device memory area attributes”,以及具体型号所拥有的内存。如表中写的"Reserved"地址就是真正不存在的地址了。

 

b\设备未准备好接受某传输。

void SystemInit (void)

{   

    ...

#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)

    SystemInit_ExtMemCtl();

#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */

    ...

}

如固件库中,若未对片外RAM进行初始化就读写片外RAM。

c\收到传输请求的总线从设备返回一个错误响应。

例如,若总线从设备不支持传输的类型/大小或者外设不允许正在执行的操作,就会出现这种情况。

2、未对齐访问

如sprintf等函数的dest参数必须4字节对齐。否则会产生错误。例子参见[6]

3、对私有外设总线(PPB)的非特权访问和默认的存储器访问权限相冲突

Cortex-M系列:错误异常_第2张图片

注:SCB的权限未提及,不太清楚。“3”是cortexM特有的,看上去不是很符合总线错误定义中“物理”这一特性,反倒点像段错误,原因未知。

 

存储管理错误

In computing, a segmentation fault (often shortened to segfault) or access violation is a fault, or failure condition, raised by hardware with memory protection, notifying an operating system (OS) the software has attempted to access a restricted area of memory (a memory access violation). On standard x86 computers, this is a form of general protection fault. The OS kernel will, in response, usually perform some corrective action, generally passing the fault on to the offending process by sending the process a signal. Processes can in some cases install a custom signal handler, allowing them to recover on their own, but otherwise the OS default signal handler is used, generally causing abnormal termination of the process (a program crash), and sometimes a core dump.[4]

在计算机领域,段错误或者说非法访问是由一种具有内存保护机制的硬件产生的错误或情况。它用来告知操作系统有软件尝试访问一个被限制的内存区域,即进行内存非法访问。在标准的x86计算机下,这是一种一般保护错误。作为响应,OS内核通常会执行一些纠正操作,普遍是通过向违规进程发送信号的方式将错误传递给违规进程。 在某些情况下,进程可以安装自定义信号句柄,允许它们自行恢复,但在其他情况下将使用OS默认信号处理程序,这通常会导致进程异常终止(程序崩溃),有时还会导致核心转储

Cortex-M7用户手册的解释为:

A MemManage fault is an exception that occurs because of a memory protection related fault. The fixed memory protection constraints, or the MPU if implemented, determines this fault, for both instruction and data memory transactions. This fault is always used to abort instruction accesses to Execute Never (XN) memory regions.

内存的访问是有一定的规则的(亦即权限),一些是CPU设计时已经考虑的,而另一些则是通过MPU来设置的规则。

1、CPU设计时已经考虑的部分:

a\非特权任务试图访问只支持特权访问的存储器区域。

b\在PERIPHERAL、DEVICE或SYSTEM等永不执行(XN)区域执行程序代码

2、MPU可设置的规则:

a\访问未在任何MPU区域中定义的存储位置(私有外设总线除外,其总可被特权代码访问)

b\存储器访问和MPU定义的访问权限冲突

 

从错误发生时程序所在的过程上看:

1、程序执行

2、取出程序期间的数据访问

3、执行过程中的栈操作:又分为压栈错误和出栈错误

使用错误

Cortex-M7用户手册的解释为:

A UsageFault is an exception that occurs because of a fault related to

instruction execution. This includes:

• An undefined instruction.

• An illegal unaligned access.

• Invalid state on instruction execution.

• An error on exception return.

The following can cause a UsageFault when the core is configured to

report them:

• An unaligned address on word and halfword memory access.

• Division by zero.

HardFault

FORCED:出现总线错误、存储错误或使用错误,但对应的异常没有使能,那么将会进入HardFault,并且强制位(FORCED)置位。

VECTOR:该标志位这是由于取中断向量失败引起的。只要是使用官方的启动文件(即“.s”文件),那么引起该错误大概率是中断向量表偏移错误导致。因为若使用官方".s"文件,若忘记定义用户自己的中断服务函数(或者说函数句柄Handler),那么由汇编伪指令[WEAK],中断向量将指向多个标签共用一个汇编函数的位置,并且由于B . 的存在(同C语言中的while(1))。

WWDG_IRQHandler                                                         

…;省略部分

WAKEUP_PIN_IRQHandler



                                B       .



                                ENDP



                                ALIGN

DEBUGEVT:由调试事件触发,具体可能要了解调试架构才能知道了。

例子

在Keil中可以打开Faullt Reports来查看相关寄存器。若是总线错误,那么可以查看辅助总线寄存器,查看是那条总线引起的,根据该寄存器分析错误原因需要了解一些总线架构的知识。

当错误发生时,分析错误原因的方法可分为两类:栈跟踪和指令跟踪(CPU要有ETM单元,要有支持ETM功能的调试器)。栈跟踪可以参考[5]

 

Cortex-M系列:错误异常_第3张图片

参考资料

[1] ARM Cortex-M3 与Cortex-M4权威指南

[2] Bus error https://en.wikipedia.org/wiki/Bus_error

[3] Arm cortex-m4 programmer model Arm cortex-m4 programmer model

[4] Segmentation fault https://en.wikipedia.org/wiki/Segmentation_fault

[5] 如何找到导致程序出现HardFault的代码 https://bbs.21ic.com/icview-1305754-1-1.html

[6] https://blog.csdn.net/u012450329/article/details/53939417

 

你可能感兴趣的:(嵌入式,stm32,arm)