ARM hardfault handler出现有以下几种情况:
1. 内存访问没有对齐。
比如对于M0的CPU,访问指针需要4字节对齐,访问word需要2字节对齐,如果把指针放在不是4字节对齐的地方,访问就会出现hard fault。
这协议栈的设计当中,为了节约内存,通常会在协议栈的各个layer之间共享内存,那么就需要保证这段buffer的成员变量访问时满足对齐的规则了。
如果不做特别制定,编译器都会帮你做对齐的工作。
2. 空指针访问。
对于FPGA平台,对于0地址的修改,通常不会当时就产生hardfault,而是过段时间产生hard fault,并且出现 hardfault时,PC和LR寄存器都是0,这样就很难定位
问题在哪边了。原因是FPGA平台是ROM模拟的RAM,所以0地址读写通常也不会有问题。但是如果0地址附近存放了一些重要的信息,那么这些信息就会被破坏掉。
导致出现hard fault。
There's many references to Debugging a Hard Fault on Cortex-M3 & M4; eg
Niall Cooling's Developing a Generic Hard Fault handler for ARMv7-M
also:
http://supp.iar.com/Support/?Note=23721
https://community.freescale.com/thread/306244 - which references http://www.keil.com/appnotes/files/apnt209.pdf
http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
http://support.code-red-tech.com/CodeRedWiki/DebugHardFault
But hard to find anything specifically for Cortex-M0 (or M0+)
The ARMv6-M Architecture Reference Manual seems to be saying that many of the features that the above references rely upon are not provided in Cortex-M0; eg, there's no CFSR and no HFSR.
I have managed to implement a Hard Fault handler (from suggestions above), and it is called when a Hard Fault occurs - just not sure how much of the information is actually valid/useful once I'm there...
If using Cortex-M0+ processor, and if the Micro Trace Buffer (MTB) is available, then the instruction trace feature allows you to view the recent execution history. Application note covering usage of MTB in Keil MDK-ARM is available on Keil website: http://www.keil.com/appnotes/docs/apnt_259.asp
In summary, when debugging HardFaults on Cortex-M0/Cortex-M0+ processors, several pieces of information are very useful:
If the SP is pointing to an invalid memory location, then you won’t be able to extract the stack frame. In these occasions, you can:
If the SP is pointing to a valid location, then you should be able to extract some useful information from the stack frame.
Faults related to memory access instructions can be caused by:
You can also get a HardFault exception if you executed SVC instruction in an exception handler with same or higher priority than the SVC priority level. The fault happened because the current context does not have the right priority level for the SVC.
Due to area constraints, the fault status registers are not available on the Cortex-M0/M0+. (The more registers inside the processor, the more power it might consume and also increase the silicon area, which affect cost).