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  
 
然后查看编译后汇编代码,可以知道源程序是哪个函数哪一步出现问题,  
 
配合其它寄存器的内容来分析找出原因 |   
     
  
 |