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

首先更改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文件来查找出错函数

你可能感兴趣的:(Stm32)