为了定位ARM Hard Fault 可以说是愁的不行,看书、上网搜、论坛求助、群里询问。。。能想到的办法都做了,就是有点地方被绊住,就结了好几天了,一个偶然的机会看到了这个,心理说不出的激动。
大家一起看看吧,相信对大家也会有很大的帮助。
1, 用Keil的话,可以这样: 先将fault中断函数的内容改为:
HardFault_Handler\ PROC ;EXPORT HardFault_Handler [WEAK] ;B . IMPORT hard_fault_handler_c TST LR, #4 ITE EQ MRSEQ R0, MSP MRSNE R0, PSP B hard_fault_handler_c ENDP
然后在源程序里添加下面的函数代码: // 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;
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]);
printf ("[Hard fault handler]\n"); printf ("R0 = %x\n", stacked_r0); printf ("R1 = %x\n", stacked_r1); printf ("R2 = %x\n", stacked_r2); printf ("R3 = %x\n", stacked_r3); printf ("R12 = %x\n", stacked_r12); printf ("LR = %x\n", stacked_lr); printf ("PC = %x\n", stacked_pc); printf ("PSR = %x\n", stacked_psr); printf ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38)))); printf ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28)))); printf ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C)))); printf ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30)))); printf ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
while(1) { ;; }
}
如果使用调试器,则可以在第一个printf处设置断点.没有的话看串口打印结果 通过查看stacked_lr的内容可以知道程序运行到哪个位置出现fault 然后查看编译后汇编代码,可以知道源程序是哪个函数哪一步出现问题, 配合其它寄存器的内容来分析找出原因
2.用IAR的话,把startup_ewarm.c文件中的FaultISR()函数的内容改为: volatile unsigned int stacked_r0; volatile unsigned int stacked_r1; volatile unsigned int stacked_r2; volatile unsigned int stacked_r3; volatile unsigned int stacked_r12; volatile unsigned int stacked_lr; volatile unsigned int stacked_pc; volatile unsigned int stacked_psr;
//unsigned long cc;
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]);
printf ("[Hard fault handler]\n"); printf ("R0 = %x\n", stacked_r0); printf ("R1 = %x\n", stacked_r1); printf ("R2 = %x\n", stacked_r2); printf ("R3 = %x\n", stacked_r3); printf ("R12 = %x\n", stacked_r12); printf ("LR = %x\n", stacked_lr); printf ("PC = %x\n", stacked_pc); printf ("PSR = %x\n", stacked_psr); printf ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38)))); printf ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28)))); printf ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C)))); printf ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30)))); printf ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
while(1) { ;; } 如果使用调试器,则可以在第一个printf处设置断点.没有的话看串口打印结果 通过查看stacked_lr的内容可以知道程序运行到哪个位置出现fault 然后查看编译后汇编代码,可以知道源程序是哪个函数哪一步出现问题, 配合其它寄存器的内容来分析找出原因
|