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

本文介绍了一种ARM架构下处理硬故障的方法。通过修改启动文件startup.s中的HardFault_Handler,并将其对应的处理逻辑转移到C语言实现的hard_fault_handler_c函数中。此函数收集了故障时的关键寄存器值及状态寄存器信息,有助于定位故障原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值