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

  • 相关阅读:
    MySQL 数据类型
    MySQL的相关概念介绍
    遍历Map的四种方法
    Hadoop在win7下部署的问题
    Hbase之shell操作
    问题-"Record not found or changed by another user"
    问题-Delphi编译到最后Linking时总是出现与ntdll.dll有关的错误还有Fatal Error Out of memory错误
    教程-CXGRID之cxDropDownEdit密密
    问题-delphi在某电脑(win7)上是界面超乱 DPL
    教程-Delphi调用C# WEBSERVICE(二)
  • 原文地址:https://www.cnblogs.com/pukaifei/p/5717675.html
Copyright © 2011-2022 走看看