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
}
出错后,程序打印:
看到,是比较直观了