zoukankan      html  css  js  c++  java
  • 转载:定位ARM Hard Fault 的方法

    转载自:http://www.openedv.com/posts/list/25030.htm

    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]
    ");  
    printf ("R0 = %x
    ", stacked_r0);  
    printf ("R1 = %x
    ", stacked_r1);  
    printf ("R2 = %x
    ", stacked_r2);  
    printf ("R3 = %x
    ", stacked_r3);  
    printf ("R12 = %x
    ", stacked_r12);  
    printf ("LR = %x
    ", stacked_lr);  
    printf ("PC = %x
    ", stacked_pc);  
    printf ("PSR = %x
    ", stacked_psr);  
    printf ("BFAR = %x
    ", (*((volatile unsigned long *)(0xE000ED38))));  
    printf ("CFSR = %x
    ", (*((volatile unsigned long *)(0xE000ED28))));  
    printf ("HFSR = %x
    ", (*((volatile unsigned long *)(0xE000ED2C))));  
    printf ("DFSR = %x
    ", (*((volatile unsigned long *)(0xE000ED30))));  
    printf ("AFSR = %x
    ", (*((volatile unsigned long *)(0xE000ED3C))));  
       
    while(1)
    {
            ;;
    } 
    }  
     
    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]
    ");  
    printf ("R0 = %x
    ", stacked_r0);  
    printf ("R1 = %x
    ", stacked_r1);  
    printf ("R2 = %x
    ", stacked_r2);  
    printf ("R3 = %x
    ", stacked_r3);  
    printf ("R12 = %x
    ", stacked_r12);  
    printf ("LR = %x
    ", stacked_lr);  
    printf ("PC = %x
    ", stacked_pc);  
    printf ("PSR = %x
    ", stacked_psr);  
    printf ("BFAR = %x
    ", (*((volatile unsigned long *)(0xE000ED38))));  
    printf ("CFSR = %x
    ", (*((volatile unsigned long *)(0xE000ED28))));  
    printf ("HFSR = %x
    ", (*((volatile unsigned long *)(0xE000ED2C))));  
    printf ("DFSR = %x
    ", (*((volatile unsigned long *)(0xE000ED30))));  
    printf ("AFSR = %x
    ", (*((volatile unsigned long *)(0xE000ED3C))));  
      
      while(1)
      {
              ;;
      }
    

    如果使用调试器,则可以在第一个printf处设置断点。

    没有的话看串口打印结果通过查看stacked_lr的内容可以知道程序运行到哪个位置出现fault,然后查看编译后汇编代码,可以知道源程序是哪个函数哪一步出现问题,配合其它寄存器的内容来分析找出原因。

  • 相关阅读:
    POJ 2251 Dungeon Master
    HDU 3085 Nightmare Ⅱ
    CodeForces 1060 B Maximum Sum of Digits
    HDU 1166 敌兵布阵(树状数组)
    HDOJ 2050 折线分割平面
    HDU 5879 Cure
    HDU 1878 欧拉回路
    HDU 6225 Little Boxes
    ZOJ 2971 Give Me the Number
    HDU 2680 Choose the best route
  • 原文地址:https://www.cnblogs.com/pukaifei/p/5717675.html
Copyright © 2011-2022 走看看