1、问题现象
代码O0编译运行正常,O2编译会运行进入HardFault_Handler。
2、引起HardFault_Handler的常见原因
1). 越界操作数组。
2). 使用非法指针(如空指针)。
3、进入HardFault_Handler中断后,查看CFSR寄存器
我使用的是STM32F4系列单片机,它的内核是cortex-M4,故参考cortex-M4 device generic user guide。在4.3.10查看CFSR寄存器(Configurable Fault Status Register)的详细描述,CFSR寄存器由UFSR、BFSR、MMFSR组成,进入HardFault_Handler中断,读取CFSR寄存器的值,查看异常的位,对照指南中各个位的描述即可确定引起HardFault_Handler的原因。
keil在调试模式下,可以通过Peripherals->Core Peripherals->Fault Reports很方便地查看UFSR、BFSR、MMFSR三个寄存器的值,可以看到是发生了UNALIGNED错误。
查看指南对UFSR寄存器的描述,发现是发生了访问非对齐地址内存。
最后通过汇编调试,发现运行完LDM指令后就会进入HardFault_Handler
4、定位到LDM指令引起
LDM指令不支持访问非对齐地址内存,故只要将LDM指令访问的全局变量进行4字节对齐即可。
例如char test attribute((aligned(4)));//使该变量的地址起始值按照4字节对齐