程序进入错误时调试,如hardfault

1、如果不是在仿真情况下,出现进入了死机程序,可以通过R0~R15大概判断下程序出问题的地方

2、暂停程序,读取R0-R15如下:

通过xPSR程序可以判定当前的异常服务是啥:

3、读出PSP地址值存储PC,LR值:这里存的是,进入异常前,压入堆栈的PC和link信息

从PC值看到值为00000007,基本是系统开始的地方啊,说明异常退出?

4、addline可以查询对应的目标函数

异常中断3:hardfault是对应上的

---------------------------------------------------------------------------------------------------------------------

实际的程序记录

1、确定是SP是PSP指针

2、得到PSP地址

3、查看PSP的地址指向的内容,查出LR,PC的值

4、通过addr2line查询到LR PC的位置

        LR-4是出错前调用的位置,得到gettime,所以查看调用该函数的代码附近,查找前后错误;

        PC=0,说明他的PC指针要复位到0了,所以此时出错了,进而跳到了HardFault,说明退出程序了;

原来从错误在这里:给他屏蔽掉,加个调试信息

addr2line.exe:可以在这个里面找到

CmBacktrace-1.4.1\tools\addr2line\win64,CmBacktrace工具里面

iar下

指令:addr2line.exe -e XXX.out -a -f 80130d7

附:

----------------------------------------我是分割线-------------------------------------------------------------------------

一、我们可以将LR和PC打印出来,添加到程序里

代码如下:IAR下,GD32H7的M7核的,重新定义HardFault_Handler中断函数,在此时打印LR和PC值,用了2种方式打印PC和LR

/* Exception frame without floating-point storage
* hard fault handler in C,
* with stack frame location as input parameter
*/
void
hard_fault_handler_c(unsigned int * hardfault_args)
{
    unsigned int stacked_r0;
    unsigned int stacked_r1;
    unsigned int stacked_r2;
    unsigned int stacked_r3;
    unsigned int stacked_r12;
    unsigned int stacked_lr;
    unsigned int stacked_pc;
    unsigned int stacked_psr;
    
     volatile uint32_t *fault_stack_addr;
    uint32_t pc, lr;
 
    // 获取当前堆栈指针(SP)
    __asm volatile("mrs %0, psp" : "=r"(fault_stack_addr));
 
    // 打印出PC和LR的值
    pc = *(fault_stack_addr + 6); // 6是因为堆栈结构,PC寄存器在堆栈上的偏移量
    lr = *(fault_stack_addr + 5); // LR寄存器偏移量为5
    
    
    //Exception stack frame
    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]);
    stacked_lr = ((unsigned long) hardfault_args[5]);
    stacked_pc = ((unsigned long) hardfault_args[6]);
    stacked_psr = ((unsigned long) hardfault_args[7]);
   
    Str_PrintfISR ("[Hard fault handler]\n");
    Str_PrintfISR ("R0 = %x\n", stacked_r0);
    Str_PrintfISR ("R1 = %x\n", stacked_r1);
    Str_PrintfISR ("R2 = %x\n", stacked_r2);
    Str_PrintfISR ("R3 = %x\n", stacked_r3);
    Str_PrintfISR ("R12 = %x\n", stacked_r12);
    Str_PrintfISR ("LR = %x\n", stacked_lr);
    Str_PrintfISR ("PC = %x\n", stacked_pc);
    Str_PrintfISR ("PSR = %x\n", stacked_psr);
#ifndef CW
    Str_PrintfISR ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38))));
    Str_PrintfISR ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28))));
    Str_PrintfISR ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C))));
    Str_PrintfISR ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30))));
    Str_PrintfISR ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
#else
    Str_PrintfISR ("BFAR = %x\n", (*((volatile unsigned int *)(0xE000ED38))));
    Str_PrintfISR ("CFSR = %x\n", (*((volatile unsigned int *)(0xE000ED28))));
    Str_PrintfISR ("HFSR = %x\n", (*((volatile unsigned int *)(0xE000ED2C))));
    Str_PrintfISR ("DFSR = %x\n", (*((volatile unsigned int *)(0xE000ED30))));
    Str_PrintfISR ("AFSR = %x\n", (*((volatile unsigned int *)(0xE000ED3C))));
#endif
    
 
    Str_PrintfISR("HardFault_Handler: PC = %08X, LR = %08X\n", pc, lr);

    
    for(;;)
    {}
}
/* The prototype shows it is a naked function - in effect this is just an
assembly function. */
void HardFault_Handler( void ) __attribute__( ( naked ) );

/*!
    \brief      this function handles HardFault exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void HardFault_Handler(void)        //0x805'9a1f ,错误在这里
{
  #if   1       //def CORTEX_M3_M4_M7
    __asm volatile(
        " tst lr, #4                        \n" /* Check EXC_RETURN[2] */
        " ite eq                            \n"
        " mrseq r0, msp                     \n"
        " mrsne r0, psp                     \n"
        "b hard_fault_handler_c             \n"
        : /* no output */
        : /* no input */
        : "r0" /* clobber */
    );
  #else
    __asm volatile(
        "movs r0, #4                        \n"
        "mov  r1, lr                        \n"
        "tst  r0, r1                        \n" /* Check EXC_RETURN[2] */
        "beq 1f                             \n"
        "mrs r0, psp                        \n"
        "ldr r1,=hard_fault_handler_c       \n"
        "bx r1                              \n"
        "1:mrs r0,msp                       \n"
        "ldr r1,=hard_fault_handler_c       \n"
        : /* no output */
        : /* no input */
        : "r0" /* clobber */
    );
  #endif
}

出错后,程序打印:

看到,是比较直观了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值