HardFault_Handler 输出日志信息

之前文章说了原理,这里把最终实现的代码总结:

IAR

 1 void hard_fault_handler_c (unsigned int * hardfault_args)
 2 {
 3   unsigned int stacked_r0;
 4   unsigned int stacked_r1;
 5   unsigned int stacked_r2;
 6   unsigned int stacked_r3;
 7   unsigned int stacked_r12;
 8   unsigned int stacked_lr;
 9   unsigned int stacked_pc;
10   unsigned int stacked_psr;
11
12   stacked_r0 = ((unsigned long) hardfault_args[0]);
13   stacked_r1 = ((unsigned long) hardfault_args[1]);
14   stacked_r2 = ((unsigned long) hardfault_args[2]);
15   stacked_r3 = ((unsigned long) hardfault_args[3]);
16
17   stacked_r12 = ((unsigned long) hardfault_args[4]);
18   stacked_lr = ((unsigned long) hardfault_args[5]);
19   stacked_pc = ((unsigned long) hardfault_args[6]);
20   stacked_psr = ((unsigned long) hardfault_args[7]);
21
22   printf ("\r\n[Hard fault handler - all numbers in hex]\r\n");
23   printf ("R0=%x\r\n",stacked_r0);
24   printf ("R1=%x\r\n",stacked_r1);
25   printf ("R2=%x\r\n",stacked_r2);
26   printf ("R3=%x\r\n",stacked_r3);
27   printf ("R12=%x\r\n",stacked_r12);
28   printf ("LR[R14]=%x subroutine call return address\r\n",stacked_lr);
29   printf ("PC[R15]=%x program counter\r\n",stacked_pc);
30   printf ("PSR=%x\r\n",stacked_psr);
31   printf ("BFAR=%x\r\n",(*((volatile unsigned long *)(0xE000ED38))));
32   printf ("CFSR=%x\r\n",(*((volatile unsigned long *)(0xE000ED28))));
33   printf ("HFSR=%x\r\n",(*((volatile unsigned long *)(0xE000ED2C))));
34   printf ("DFSR=%x\r\n",(*((volatile unsigned long *)(0xE000ED30))));
35   printf ("AFSR=%x\r\n",(*((volatile unsigned long *)(0xE000ED3C))));
36   printf ("SCB_SHCSR=%x\r\n", SCB->SHCSR);
37
38
39   while (1);
40 }

hard_fault_handler_c

1 void HardFault_Handler( void )
2 {
3 __ASM("TST LR, #4");
4 __ASM("ITE EQ");
5 __ASM("MRSEQ R0, MSP");
6 __ASM("MRSNE R0, PSP");
7 __ASM("B hard_fault_handler_c");
8 }

HardFault_Handler

这里的HardFault_Handler里是内联汇编

MDK不能使用内联汇编

1 __ASM void HardFault_Handler(void)
2 {
3       TST lr, #4     // Test for MSP or PSP
4       ITE EQ
5       MRSEQ r0, MSP
6       MRSNE r0, PSP
7       IMPORT HardFault_Handler_C
8       B HardFault_Handler_C
9 }

HardFault_Handler

 1 void HardFault_Handler_C (unsigned int * hardfault_args)
 2 {
 3   unsigned int stacked_r0;
 4   unsigned int stacked_r1;
 5   unsigned int stacked_r2;
 6   unsigned int stacked_r3;
 7   unsigned int stacked_r12;
 8   unsigned int stacked_lr;
 9   unsigned int stacked_pc;
10   unsigned int stacked_psr;
11
12   stacked_r0 = ((unsigned long) hardfault_args[0]);
13   stacked_r1 = ((unsigned long) hardfault_args[1]);
14   stacked_r2 = ((unsigned long) hardfault_args[2]);
15   stacked_r3 = ((unsigned long) hardfault_args[3]);
16
17   stacked_r12 = ((unsigned long) hardfault_args[4]);
18   stacked_lr = ((unsigned long) hardfault_args[5]);
19   stacked_pc = ((unsigned long) hardfault_args[6]);
20   stacked_psr = ((unsigned long) hardfault_args[7]);
21
22   printf ("\n\n[Hard fault handler - all numbers in hex]\r\n");
23   printf ("R0 = %x\r\n", stacked_r0);
24   printf ("R1 = %x\r\n", stacked_r1);
25   printf ("R2 = %x\r\n", stacked_r2);
26   printf ("R3 = %x\r\n", stacked_r3);
27   printf ("R12 = %x\r\n", stacked_r12);
28   printf ("LR [R14] = %x  subroutine call return address\r\n", stacked_lr);
29   printf ("PC [R15] = %x  program counter\r\n", stacked_pc);
30   printf ("PSR = %x\r\n", stacked_psr);
31   printf ("BFAR = %x\r\n", (*((volatile unsigned long *)(0xE000ED38))));
32   printf ("CFSR = %x\r\n", (*((volatile unsigned long *)(0xE000ED28))));
33   printf ("HFSR = %x\r\n", (*((volatile unsigned long *)(0xE000ED2C))));
34   printf ("DFSR = %x\r\n", (*((volatile unsigned long *)(0xE000ED30))));
35   printf ("AFSR = %x\r\n", (*((volatile unsigned long *)(0xE000ED3C))));
36   printf ("SCB_SHCSR = %x\r\n", SCB->SHCSR);
37
38   while (1);
39 } 

HardFault_Handler_C

 1 [Hard fault handler - all numbers in hex]
 2 R0 = 11111000
 3 R1 = 8000378
 4 R2 = 8000379
 5 R3 = c0
 6 R12 = 400
 7 LR [R14] = 8001759  subroutine call return address
 8 PC [R15] = 8000340  program counter
 9 PSR = 1000000
10 BFAR = 11111111
11 CFSR = 8200
12 HFSR = 40000000
13 DFSR = 1
14 AFSR = 0
15 SCB_SHCSR = 0

对于调试很有帮助的,注意PC[R15]的数值是我们需要的

HardFault_Handler 输出日志信息

时间: 2024-10-12 11:59:46

HardFault_Handler 输出日志信息的相关文章

查看与输出日志信息

查看与输出日志信息: 1.优先级级别从高到低: Error > Warning > Info > Debug > Verbose 2.日志输出的3种方式: (1)       Log.i (2)       System.out.println (3)       System.err.println 3.实践: 1 package com.example.test; 2 3 import android.test.AndroidTestCase; 4 import android

如何正确地在SOE中输出日志信息

ArcGIS for Server提供完善的日志管理机制,用于日志的记录.查询和自动清除.开发人员在开发编写SOE代码时,应该采用该机制进行日志记录的输出.如果不采用该机制,输出的日志消息会写到ArcGIS Server内置的标准输出文件(C:\Program Files\ArcGIS\Server\framework\etc\service\logs)中,该位置文件是没有自动清除机制的,运行一段时间后,有可能导致该文件太大而导致服务性能下降. 具体指引如下: 1.在SOE的工程中创建Serve

nohup 配置不输出日志信息的方法及linux重定向学习

起因 最近使用nohup创建了一个后台进程,默认日志输出到了nohup.out文件中,程序跑起来也就没再管, 过了大约一周,发现硬盘空间不够了,于是查找原因,发现这个nohup.out文件已经到了70G了,导致硬 盘空间不足了. 解决方案 只输出错误信息到日志文件 nohup ./program >/dev/null 2>log & 什么信息也不要 nohup ./program >/dev/null 2>&1 & 知识补充,关于Linux的重定向 Linu

log4j(四)——如何控制不同风格的日志信息的输出?

一.测试环境 与log4j(一)--为什么要使用log4j?一样,这里不再重述 二.老规矩,先来个例子,然后再聊聊感受 package com.sc.log4j; import org.apache.log4j.Appender; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Layout; import org.apache.

【记录】SpringBoot 2.X整合Log4j没有输出INFO、DEBUG等日志信息解决方案

由于批量更新的时候一直无法定位问题出处,就去服务器定位日志,奈何日志一直无法输出,为了能够更好的定位问题,痛定思痛后逐步排查最终解决问题.如有客官看到此处,请不要盲目对号入座,我的项目环境或许与你有区别所以解决方案不一定适合,此贴只作为工作记录,并对出现相同问题,且项目环境相同的朋友作为借鉴而已,如没有帮到,也请嘴下留情. 首先贴出日志文件:log4j2.yml # 共有8个级别,按照从低到高为:ALL < TRACE < DEBUG < INFO < WARN < ERRO

log4j 日志信息的引入(通用版)——解决项目运行过程中的日志信息

定义 log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件,甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进程等:我们也可以控制每一条日志的输出格式:通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程.最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码. 一.log4j.properties 的使用详解 1.输出级别的种类 ERROR.WARN.INFO.D

输出日志实例改成用Spring的AOP来实现

1.采用Interception Around通知的形式实现 Interception Around通知会在Join Point的前后执行,实现Interception Around通知的类需要实现接口MethodInterceptor.其实现思路是: 1)首先实现接口MethodInterceptor,在Invoke()方法里编写负责输出日志信息的代码,具体业务逻辑还使用前面的接口TimeBookInterface和它的实现类TimeBook 2)然后在Spring的配置文档中定义PointC

Log4J日志配置详解和自定义log4j日志级别及输出日志到不同文件实现方法

Log4J日志配置详解 一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders(输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使用这三个组件可以轻松地记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置. 1.Loggers Loggers组件在此系统中被分为五个级别:DEBUG.INFO.WARN.ERROR和FATAL.这五个级别是有顺序的,DEBUG < INFO < WARN <

配置log4j日志信息

一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使用这三个组件可以轻松地记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置. 1.Loggers Loggers组件在此系统中被分为五个级别:DEBUG.INFO.WARN.ERROR和FATAL.这五个级别是有顺序的,DEBUG < INFO < WARN < ERROR <