Cortex-M3 内核HardFault错误调试定位方法

时间:2022-10-06 23:54:52

首先更改startup.s的启动文件

把里面的HardFault_Handler代码段换成下面的代码:

HardFault_Handler\     
PROC
IMPORT hard_fault_handler_c ;函数申明
TST LR, #4 ;根据LR.2判断使用的什么堆栈
ITE EQ
MRSEQ R0, MSP ;使用MSP堆栈
MRSNE R0, PSP ;使用PSP堆栈
B hard_fault_handler_c ;执行函数
ENDP

添加hard_fault_handler_c函数

然后把hard_fault_handler_c函数放在c文件的代码中。代码如下:

void hard_fault_handler_c(unsigned int * hardfault_args) 
{
static unsigned int stacked_r0;
static unsigned int stacked_r1;
static unsigned int stacked_r2;
static unsigned int stacked_r12;
static unsigned int stacked_lr;
static unsigned int stacked_pc;
static unsigned int stacked_psr;
static unsigned int SHCSR;
static unsigned char MFSR;
static unsigned char BFSR;
static unsigned short int UFSR;
static unsigned int HFSR;
static unsigned int DFSR;
static unsigned int MMAR;
static unsigned int BFAR;
stacked_r0 = ((unsigned long) hardfault_args[0]);
stacked_r1 = ((unsigned long) hardfault_args[1]);
stacked_r2 = ((unsigned long) hardfault_args[2]);
stacked_r3 = ((unsigned long) hardfault_args[3]);
stacked_r12 = ((unsigned long) hardfault_args[4]);
/*异常中断发生时,这个异常模式特定的物理R14,即lr被设置成该异常模式将要返回的地址*/
stacked_lr = ((unsigned long) hardfault_args[5]);
stacked_pc = ((unsigned long) hardfault_args[6]);
stacked_psr = ((unsigned long) hardfault_args[7]);

MFSR = (*((volatile unsigned char *)(0xE000ED28))); //存储器管理fault状态寄存器
BFSR = (*((volatile unsigned char *)(0xE000ED29))); //总线fault状态寄存器
UFSR = (*((volatile unsigned short int *)(0xE000ED2A)));//用法fault状态寄存器
HFSR = (*((volatile unsigned long *)(0xE000ED2C))); //硬fault状态寄存器
DFSR = (*((volatile unsigned long *)(0xE000ED30))); //调试fault状态寄存器
MMAR = (*((volatile unsigned long *)(0xE000ED34))); //存储管理地址寄存器
BFAR = (*((volatile unsigned long *)(0xE000ED38))); //总线fault地址寄存器
while (1);
}

根据寄存器值判断出错函数

执行程序后,若发生内核错误,则程序会运行到最后的while(1)处。此时观察相应的堆栈和故障寄存器值
- stacked_lr即为故障发生时进入故障中断前pc的值,可以通过生成的.map文件来查找出错函数