搜索
bottom↓
回复: 50

找到一种查找进入fault死循环原因的方法【恢复】

[复制链接]

出0入16汤圆

发表于 2008-12-25 10:38:33 | 显示全部楼层 |阅读模式
在国外的讨论区找到的,可以定位问题出在哪里



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

然后查看编译后汇编代码,可以知道源程序是哪个函数哪一步出现问题,

配合其它寄存器的内容来分析找出原因

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-4-8 08:55:57 | 显示全部楼层
太感谢了,

大概的思路就是用R0作为堆栈的地址(分清用MSP还是PSP)

然后通过函数调用(R0用作参数传递)

把由于Fault_ISR入栈的堆栈里的东西都给倒出来。

真的挺拓展思路的,我前两天总是碰到这种问题,然后还要一步一步的去找从哪里跳到Fault_Isr()了,老麻烦了。

感谢楼主分享,请问是那个国外的论坛,能提供一下么。

aaa1982

出0入0汤圆

发表于 2009-4-8 10:14:46 | 显示全部楼层
以前ARM7的时候大概就是用这个方法了,不过那时候只观察LR指针就够了

出0入70汤圆

发表于 2009-4-24 23:01:02 | 显示全部楼层

出0入0汤圆

发表于 2009-4-25 20:39:49 | 显示全部楼层
记号,mark

出0入0汤圆

发表于 2009-10-14 13:38:41 | 显示全部楼层
好好好

出0入0汤圆

发表于 2009-10-14 16:08:04 | 显示全部楼层
下载了马老师的Dome2,运行就是进入fault,正在调查原因。借鉴一下。

出0入0汤圆

发表于 2010-5-24 18:50:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-25 00:15:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-25 08:33:15 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-5-25 08:48:44 | 显示全部楼层
标记一下   fault死循环 原因调查

出0入0汤圆

发表于 2010-5-26 23:16:21 | 显示全部楼层
好办法!.在VC 里面调试也可以用这个东西报出行号什么的资料来,很不错的

出0入0汤圆

发表于 2010-7-26 19:21:09 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-9-26 15:15:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-26 19:05:23 | 显示全部楼层
不错啊

出0入0汤圆

发表于 2010-9-26 19:14:17 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-29 15:10:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-10 11:34:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-11 16:09:02 | 显示全部楼层
马克思.....

出0入0汤圆

发表于 2011-7-13 00:48:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-13 08:55:52 | 显示全部楼层
mark,楼主好方法。

但是在rtt的fault_rvds.s代码中也给出了错误调试信息。
    AREA |.text|, CODE, READONLY, ALIGN=2
    THUMB
    REQUIRE8
    PRESERVE8

    IMPORT rt_hw_hard_fault_exception

rt_hw_hard_fault    PROC
    EXPORT rt_hw_hard_fault

    ; get current context
    MRS     r0, psp                 ; get fault thread stack pointer
    PUSH    {lr}
    BL      rt_hw_hard_fault_exception
    POP     {lr}

    ORR     lr, lr, #0x04
    BX      lr
    ENDP

    END
然后
void rt_hw_hard_fault_exception(struct stack_contex* contex)
{
        rt_kprintf("psr: 0x%08x\n", contex->psr);
        rt_kprintf(" pc: 0x%08x\n", contex->pc);
        rt_kprintf(" lr: 0x%08x\n", contex->lr);
        rt_kprintf("r12: 0x%08x\n", contex->r12);
        rt_kprintf("r03: 0x%08x\n", contex->r3);
        rt_kprintf("r02: 0x%08x\n", contex->r2);
        rt_kprintf("r01: 0x%08x\n", contex->r1);
        rt_kprintf("r00: 0x%08x\n", contex->r0);

        rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
#ifdef RT_USING_FINSH
        list_thread();
#endif
        while (1);
}
我看了一下跟你的思路是一样的。

出0入0汤圆

发表于 2011-7-13 09:05:45 | 显示全部楼层
非常感谢,谢谢

出0入0汤圆

发表于 2011-7-13 10:32:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-13 14:01:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-14 11:27:34 | 显示全部楼层
回复【楼主位】Elex 阿甘
-----------------------------------------------------------------------

Mark

出0入0汤圆

发表于 2011-7-14 11:50:39 | 显示全部楼层
牛!实在太好了,以前碰上了总是要慢慢找到。非常感谢啊!

出0入0汤圆

发表于 2011-7-14 13:01:23 | 显示全部楼层
mark!!!!

出0入0汤圆

发表于 2011-7-14 14:40:55 | 显示全部楼层
mark!!!!

出0入0汤圆

发表于 2011-7-14 19:21:31 | 显示全部楼层
学习了!

出0入0汤圆

发表于 2011-7-20 13:01:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-21 23:40:07 | 显示全部楼层
现在还看不懂,收藏

出0入0汤圆

发表于 2011-8-22 09:01:15 | 显示全部楼层
标记一下   fault死循环 原因调查

出0入0汤圆

发表于 2011-8-22 09:33:33 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2011-11-8 18:00:57 | 显示全部楼层
标记一下   fault死循环 原因调查

出0入0汤圆

发表于 2011-12-18 13:42:16 | 显示全部楼层
我按楼主的方法实验了一下 怎么在编译的时候 提示“Libraries\User\stm32f10x_it.c(82): error:  #20: identifier "hardfault_args" is undefined ” 这个错误啊 楼上的 你们都是怎么实验的啊

(原文件名:0X[ICR4GPROY$769P]7Q116.jpg)

出0入0汤圆

发表于 2012-2-19 18:20:36 | 显示全部楼层
mark

出0入16汤圆

 楼主| 发表于 2012-2-25 23:07:29 | 显示全部楼层
回复【34楼】zhongjun 中军
我按楼主的方法实验了一下 怎么在编译的时候 提示“libraries\user\stm32f10x_it.c(82): error:  #20: identifier "hardfault_args" is undefined ” 这个错误啊 楼上的 你们都是怎么实验的啊  


(原文件名:0x[icr4gproy$769p]7q116.jpg)
引用图片

-----------------------------------------------------------------------

那是fault中断处理函数的参数。你的程序把参数都弄成void了。

出0入0汤圆

发表于 2012-2-25 23:34:29 | 显示全部楼层
fault死循环原因的方法

出0入0汤圆

发表于 2012-2-26 00:33:40 | 显示全部楼层
fault原因

出0入0汤圆

发表于 2012-2-26 00:34:35 | 显示全部楼层
fault原因

出0入0汤圆

发表于 2012-4-18 07:53:23 来自手机 | 显示全部楼层
好。标记下。

出0入0汤圆

发表于 2012-4-18 07:58:28 | 显示全部楼层
MARK.谢谢

出0入0汤圆

发表于 2014-3-1 14:57:16 | 显示全部楼层
好东西。

出0入0汤圆

发表于 2014-3-1 22:20:58 | 显示全部楼层
好方法,不错,学习了

出0入0汤圆

发表于 2014-3-3 22:37:54 | 显示全部楼层
Mark一记,CM3 进fault跟踪查找原因

出0入0汤圆

发表于 2014-7-4 14:56:55 | 显示全部楼层
楼主,能重发一下吗,这里乱码多啊

出0入0汤圆

发表于 2014-7-5 16:00:04 | 显示全部楼层
mark。。。。。。。               

出0入0汤圆

发表于 2015-2-3 20:00:18 | 显示全部楼层
good,刚试了下,能够定位到大概的函数,具体原理在慢慢理解下

出0入16汤圆

 楼主| 发表于 2016-6-27 18:31:00 | 显示全部楼层
论坛更换服务器恢复数据的时候把楼主位的程序中的空格替换成网络语言了。
修复如下:
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)

{

        ;;

}



}

出0入0汤圆

发表于 2016-6-28 09:28:31 | 显示全部楼层
这个方法 太好了 谢谢

出250入8汤圆

发表于 2020-9-6 21:11:18 | 显示全部楼层
还没看懂,做个记号。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-15 00:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表