首页 > 其他分享 >stm32 出现 hard fault 的排查记录

stm32 出现 hard fault 的排查记录

时间:2024-05-09 21:55:53浏览次数:14  
标签:压入 int fault hard stm32 先验 寄存器

参考链接:https://blog.csdn.net/qq_43118572/article/details/132759626

1、先验知识

先验知识1: cortex m3 在中断/异常时,会把 8 个寄存器(xPSR、PC、LR、R12 以及R3-R0)的值压入栈。入栈顺序以及入栈后堆栈中的内容如下(CM4 是从低地址到搞地质):

地址 寄存器 被保存的顺序
旧 ISP(N-0) 原先已压入栈的内容 -
(N-4) xPSR 2
(N-8) PC 1
(N-12) LR 8
(N-16) R12 7
(N-20) R3 6
(N-24) R2 5
(N-28) R1 4
新 SP(N-32) R0 3

先验知识2: 在 Keil 项目的 Options for Target 'Target 1' 的Target 选项,将 Floating Port Hardware 选项设置为 Not Use,这样的好处是在后续查看堆栈寄存器信息时,不会看到其他浮点寄存器,好根据地址推断存储的是哪个寄存器的值。
> 参考链接:https://blog.csdn.net/qq_20553613/article/details/80118444

在这里插入图片描述

先验知识3: map 文件可以查看符号表(Symbol Table)。符号表可用于确定变量或函数在内存中的位置。

2、正文

由于 arm/cortex 仅支持对齐访问,否则会出现 hard fault。我们以下述访问不对齐的代码为例,产生 Hard Fault 并进行逐一排查:(假设我们不知道是哪里出现 hard fault)

int main(void)
{
  int a = 1;
  int b = 1;
  int c = a + b;
  int *p = (int *)0xF000 0000;
  int d = *p;
  while (*p) {  // line 11
    (*p)++;  // 将在此处陷入 Hard Fault  line12
  }
  return 0;
}

Step 1:查看 map 我们可以发现栈顶位置为 0x2000 0660

Step 2:当程序陷入异常时,我们能发现当前使用的是 MSP,SP 对应的地址为 0x2000 0640,所以压入了 32/4 = 8 个寄存器(一个寄存器 32 位,即 4 个字节)。根据物理地址,发现上次压入的 PC 值为 0x0800 0336。换而言之,陷入异常的上一条指令地址为 0x0800 0336

Step 3:点击导航栏的 “Disasembly Window”,打开反汇编界面。右键并选择 “Disassembly at Address” 选项,输入 0x0800 0336 并输入 “go to”,就会跳转到该条指令。

备注: Call Stack 跟 Memory 窗口可以查看很多信息

在这里插入图片描述

标签:压入,int,fault,hard,stm32,先验,寄存器
From: https://www.cnblogs.com/MasterBean/p/18183150

相关文章

  • stm32 将外部 Flash挂载在 SPI 出现数据传输时好时不好的排查过程
    现象:将外部Flash挂载在SPI,在hardware_init()->read_jedec_id()里的result=spi->wr(spi,cmd_data,sizeof(cmd_data),recv_data,sizeof(recv_data))中,recv_data的值经常不一致,result的值偶尔为SFUD_SUCCESS,大部分会Error。备注:正常情况下,recv_data的值为......
  • STM32堆和栈(Heap & Stack)及SRAM存储使用
    编译一个程序,出现下面的信息:明明程序没有什么内容,为什么变量大小就有RW+ZI=52+1836=1888字节大小了呢,就已经使用了1888字节的SRAM空间。让我们打开map文件:可以看到每个文件所使用的SRAM大小,比如delay文件使用了4个字节,地址从0x20000014到0x20000017。其中可以看到HEAP和STACK......
  • Richard 林旅强:说说社区的故事和对 RTE 社区的畅想
    各位RTE开发者社区的小伙伴们,大家好: 我是Richard林旅强,今年起开始担任我们RTE社区联合主理人,很荣幸能在这里跟杜金房老师和陈靖老师一起做点事情,为社区的大家服务:) 今天想跟各位分享,我参与社区的几个故事,也希望对各位RTE的小伙伴能有启发和收获。第一个故事:从玩......
  • stm32-arduino压力薄膜传感器读取
     https://item.taobao.com/item.htm?id=674959275850&skuId=5150222163940&spm=a1z0d.6639537/tb2.1997196601.3.43b97484vSZsIQ      #include<Arduino.h>#defineDEBUGSerialSerialintsensorPin=A0; //定义传感器的引脚//下面4项内容需要根据实......
  • STM32F1和STM32F4系列DMA的不同之处——对STM32的DMA的工作机制的一些理解
    喜欢用STM32的DMA功能。一方面STM32的DMA和MPU的DMA一样,可以提高数据传输效率。另一方面,作为一种MCU上的DMA,它可以提高针对外设(peripheral)的数据传输的实时性,改变了传统MCU只能用定时中断实现实时控制的方法。比较STM32F4和STM32F1系列的DMA控制器,可以发现区别主要有三:1)增加了DMA......
  • 【专题STM32F03】 使用 STM32Cube\Repository\STM32Cube_FW_F1_V1.8.5 中例程由ST77
    1)修改Project\STM32Cube_FW_F1_V1.8.5\Projects\STM32F103RB-Nucleo\Demonstrations\Adafruit_LCD_1_8_SD_Joystick2)接线(见stm32f1xx_nucleo.h)LCD_LED_PIN接高电平LCD_CS_PIN  接PB6LCD_DC_PIN  接PA9LCD_SPI_CLK  接SPI1,PA5LCD_SPI_SDA  接SPI1,PA73)修......
  • stm32f103c8t6的freemodbus移植
    注意:demo.c不要加入到程序中来。1在main.h文件中加入#include"stm32f1xx_hal.h"文件也可以不加a:每次重新生成程序时在主程序main.c中注释掉//MX_USART2_UART_Init();函数,因为在freemodbus中已经调用了该函......
  • stm32开发笔记
    GPIO全名为GeneralPurposeInputOutput,即通用输入输出。有时候简称为“IO口”。通用,说明它是常见的。输入输出,就是说既能当输入口使用,又能当输出口使用。端口,就是元器件上的一个引脚。输入模式和输出模式是GPIO的基本特性,当然GPIO还有其它模式可选。(一)模式汇总输入模式:l......
  • G2. Division + LCP (hard version)
    G2.Division+LCP(hardversion)Thisisthehardversionoftheproblem.Inthisversion$l\ler$.Youaregivenastring$s$.Forafixed$k$,consideradivisionof$s$intoexactly$k$continuoussubstrings$w_1,\dots,w_k$.Let$f_k$bethemaximal......
  • 关于stm32F103ZET6移植到stm32F103C8T6的步骤
    在一次代码移植过程中,突然发现代码移植后不可以使用,代码是stm32f103zet6的代码,刚好当时我使用的是C8T6的芯片我进行移植到C8T6芯片时,代码报错"Error:FlashDownloadfailed-"Cortex_M3"这种报错。当时直接懵逼了。想了半天没有想到原因,我就在想不都是F103系列的代码吗为啥子不可......