在编写STM32程序代码时由于自己的粗心会发现有时候程序跑着跑着就进入了

HardFault_Handler中断,按照经验来说进入HardFault_Handler故障的原因主要有两个方面:

1:内存溢出或则访问越界。

2:堆栈溢出。

发生异常后我们可以首先查看LR寄存器的值,确认当前使用的堆栈是MSP还是PSP,然后找到相对应的堆栈指针,并在内存中查看相对应堆栈的内容,内核将R0~R3,R12,LR,PC,XPRS寄存器依次入栈,其中LR即为发生异常前PC将要执行的下一条指令地址。那么Cortex-M3内核HardFault错误调试定位方法有:

解决方法 精确定位出问题代码的所在位置:

①首先更改startup.s的启动文件,把里面的HardFault_Handler代码段换成下面的代码

②然后把HardFault_Handler_c的函数放在c文件的代码中,代码如下:

void hard_fault_handler_c(unsigned int * hardfault_args)

{

static unsigned int stacked_r0;

static unsigned int stacked_r1;

static unsigned int stacked_r2;

static unsigned int stacked_r3;

static unsigned int stacked_r12;

static unsigned int stacked_lr;

static unsigned int stacked_pc;

static unsigned int stacked_psr;

static unsigned int SHCSR;

static unsigned char MFSR;

static unsigned char BFSR;

static unsigned short int UFSR;

static unsigned int HFSR;

static unsigned int DFSR;

static unsigned int MMAR;

static unsigned int BFAR;

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]);

SHCSR = (*((volatile unsigned long *)(0xE000ED24)));

MFSR = (*((volatile unsigned char *)(0xE000ED28)));

BFSR = (*((volatile unsigned char *)(0xE000ED29)));

UFSR = (*((volatile unsigned short int *)(0xE000ED2A)));

HFSR = (*((volatile unsigned long *)(0xE000ED2C)));

DFSR = (*((volatile unsigned long *)(0xE000ED30)));

MMAR = (*((volatile unsigned long *)(0xE000ED34)));

BFAR = (*((volatile unsigned long *)(0xE000ED38)));

printf("nn[Hard fault handler - all numbers in hex]nn");

printf("R0 = %xn",stacked_r0);

printf("R1 = %xn",stacked_r1);

printf("R2 = %xn",stacked_r2);

printf("R3 = %xn",stacked_r3);

printf("R12 = %xn",stacked_r12);

printf("LR[R14] = %x subroutine call return addressn",stacked_lr);

printf("PC[R15] = %x program countern",stacked_pc);

printf("PSR = %xn",stacked_psr);

printf("SHCSR = %xn",(*((volatile unsigned long*)(0xE000ED24))));

printf("BFAR = %xn",(*((volatile unsigned long*)(0xE000ED38))));

printf("CFSR = %xn",(*((volatile unsigned long*)(0xE000ED28))));

printf("HFSR = %xn",(*((volatile unsigned long*)(0xE000ED2C))));

printf("DFSR = %xn",(*((volatile unsigned long*)(0xE000ED30))));

printf("AFSR = %xn",(*((volatile unsigned long*)(0xE000ED3C))));

printf("SCB_SHCSR = %xn",SCB->SHCSR);

while (1);

}

③执行程序后,若发生内核错误,则程序会运行到最后while(1);处。此时观察相应的堆栈和故障寄存器值,stacked_lr即为故障发生时进入故障中断前PC的值,在MDK软件调试状态下,假如stacked_lr的值为0x1a002d08,在左下方的命令窗口输入“PC = 0x1a002d08”回车,即可定位发生错误的代码位置。

④根据内核错误状态寄存器的值,对应下面的说明,可以看出是发生了何种内核错误。同样的在Cortex_M3权威指南中可以找到对应的寄存器

STM32进入HardFault_Handler的调试方法的更多相关文章

  1. stm32进入HardFault_Handler的定位方法

    写程序偶尔会遇到程序死机的现象.这个时候,就需要debug来定位. 通常情况下,程序会进入HardFault_Handler的死循环(针对stm32系列),我遇到过两次. 第一次是使用数组之前,数组的 ...

  2. Cortex-M3/4的Hard Fault调试方法

    1 Cortex-M3/4的Fault简介 Cortex-M3/4的Fault异常是由于非法的存储器访问(比如访问0地址.写只读存储位置等)和非法的程序行为(比如除以0等)等造成的.常见的4种异常及产 ...

  3. STM32进入HardFault_Handler处理办法

    STM32进入HardFault_Handler处理办法 HardFault_Handler出现的情况一般有两种: 一种是:数组越界 一种是:堆栈溢出,程序指针指飞 方法一 在中断HardFault_ ...

  4. FreeRTOS 调试方法(printf---打印任务执行情况)

    以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家介绍 FreeRTOS 的调试方法,这里的调试方法主要是教会大家如何获取任务的执行情况,通过获取 ...

  5. keil结合st-link使用SWO的两种调试方法笔记

    通过strongerHuang的教程,实现了SWO的两种调试方法, 1.在keil调试的过程中,使用debug printf viewer打印信息, 2.在STM32 ST-LINK Utility中 ...

  6. 单片机项目中使用新IC芯片的调试方法

    前两天,一位小伙伴咨询我一款新IC芯片怎么使用,借此机会我顺便把我日常工作中经常用到的一种调试方法介绍给小伙伴们,希望对对大家有所帮助.准备仓促,文中难免有技术性错误,欢迎大家给予指正,并给出好的建议 ...

  7. Linux环境下段错误的产生原因及调试方法小结(转)

    最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且 项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的“段错误”(Segmentation F ...

  8. linux Ubuntu(Segmentation fault)段错误出现原因及调试方法

      在linux下编译了一个程序,尝试运行的时候出现: Segmentation fault (core dumped) 初步确认为...完全不知道是什么玩意. 于是找度娘了. ----------- ...

  9. kernel启动console_init之前console不可用时发生crash的调试方法

    http://code.google.com/p/innosoc/wiki/KernelBootCrashDebug 注: 如在i386_start_kernel中加入:early_printk(&q ...

  10. Linux环境下段错误的产生原因及调试方法小结

    转载自http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之 ...

随机推荐

  1. 从嘉手札<2023-10-25>

    晨辉明灭 启明星低垂的挂在天边 烟霞浅浅的铺满了东方的天幕 赤红中张扬着睥睨的紫光 可惜 不过又是无趣的一天 我百无聊赖的抬起头 从缝隙里看向窗外的天空的一角 只是觉得无趣 一天天的日子如流水般远去 ...

  2. python排序之快速排序

    快速排序 快速排序是比较常用的一种排序方式,通过递归的方法进行排序 首先使用递归方式我们先要解决两个问题:1找到基准条件 2找到递归条件 基线条件为数组为空或只包含一个元素.在这种情况下,只需原样返回 ...

  3. django向数据库更新时间

    1 今天的日期可以用下面的代码: 2 3 import datetime 4 5 today = datetime.date.today() 6 7 8 9 得到昨天的日期可以用: 10 11 yes ...

  4. git基本操作(二)

    分支(git branch) git branch 命令用于列出,创建或删除分支. git branch -a git branch git branch -v # 查看每一个分支上的最后一次comm ...

  5. Swoole从入门到入土(20)——WebSocket服务器[协程版本]

    本篇让我们先用一段示例代码开路: <?php Co\run(function () { $server = new Co\Http\Server('0.0.0.0', 9501, false); ...

  6. Laravel入坑指南(6)——Redis缓存

    写在前面: Redis是常用nosql服务之一,在Redis官网上最新的稳定版本是6.0.6.这里不讨论Redis服务如何编译,如何使用.在Redis官网有很健全的文档. 这里要讨论的是无论在cent ...

  7. MySQL案例-并行复制乱序提交引起的同步异常

    现象描述 Slave在开启并行复制后, 默认会乱序提交事务, 可能会引起同步中断; Slave端表现为同步的SQL线程抛出异常, 为主键重复, 修改的数据行不存在等; GTID信息类似于: 9a2a5 ...

  8. springboot jpa自定义SQL查询

    说明 在使用JPA实现数据持久化过程中经常会遇到这种情况:我有2张表是一对多的关系,需要通过一个外键ID去关联查询到另外一张表的字段.例如,1张商品表food_info其中存有商品分类ID categ ...

  9. Linux上安装和部署git

    本机环境: [git@rhel-server .ssh]$ cat /proc/version Linux version 2.6.32-358.el6.x86_64 1.安装 yum install ...

  10. cf思维题

    1.B. Paranoid String 题意:操作一:01可以变成1,操作二:10可以变成0.给定一个串,判断字串经过若干次操作,能否长度变成1,统计数量. 思路:对01来说,1可以吃掉0,然后前边 ...