硬汉嵌入式论坛

 找回密码
 立即注册
查看: 70|回复: 8
收起左侧

[STM32H7] 请教一个STM32H7 HardFault_Handler 情况问题

[复制链接]

57

主题

653

回帖

829

积分

金牌会员

积分
829
发表于 9 小时前 | 显示全部楼层 |阅读模式
程序开机时不时卡死,调试也是偶发性的时不时全速运行就进入HardFault_Handler,有的时debug卡死后复位也不行都是卡死无法运行起来,但是好像发现在HAL_Init()处打断点就能正常跑起来,也尝试过添加延时,好像也不太行添加延时后没有那么频繁卡死。现在就是不知道具体什么原因导致的这个问题。HardFault_Handler指向的下个地址程序检查没有发现问题。工程代码是通过BootLoader模式运行在外部qspi flash上,系统用的是freertos+emwin。

图片1,HAL_Init()前添加一个for循环延时。


01.png

图片2,HardFault_Handler系统信息,也网上查了HardFault_Handler通过地址找定位,网上基本都是通过PSP地址查找的,我这个PSP = 0呢
hardFault.png

回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 8 小时前 | 显示全部楼层
把所有OS堆栈放大2倍,再试,
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
发表于 8 小时前 | 显示全部楼层
检查一下 SystemInit 函数?
回复

使用道具 举报

22

主题

182

回帖

248

积分

高级会员

积分
248
QQ
发表于 8 小时前 | 显示全部楼层
yono 发表于 2025-4-25 10:25
检查一下 SystemInit 函数?

我之前刚转gcc编译时,官方示例的 startup.s 进 main 前没有调用 SystemInit 好像出现过和你类似的情况。检查一下 VECT_TAB_BASE_ADDRESS 和 SystemCoreClock 相关内容?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 7 小时前 | 显示全部楼层
使用TOOL的硬件异常黑盒子功能,你的硬件异常中断里面仅仅写入个while1,卡在硬件异常里面。

板子重新上电卡死后,使用TOOL这里读取,方便的话,贴下错误信息

124.png
回复

使用道具 举报

57

主题

653

回帖

829

积分

金牌会员

积分
829
 楼主| 发表于 7 小时前 | 显示全部楼层
eric2013 发表于 2025-4-25 11:03
使用TOOL的硬件异常黑盒子功能,你的硬件异常中断里面仅仅写入个while1,卡在硬件异常里面。

板子重新上 ...

读取这个异常,这还不太会分析,这个黑盒子功能还没玩过,要好好研究一下来

2023-02-23 V1.0   
写内存失败 0xE000EDF0
============================================================   
=========寄存器值读取========================================   
============================================================   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R0 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R1 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R2 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R3 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R4 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R5 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R6 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R7 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R8 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R9 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R10 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R11 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R12 = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R13(SP) = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R14(LR) = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
R15(PC) = 0040bba6   
写内存失败 0xE000EDF4
读内存失败 0xE000EDF0
读内存失败 0xE000EDF8
xPSR = 0040bba6   
写内存失败 0xE000EDF0
读内存失败 0xE000ED24

   
------------------------------------------------------------------   
Read System Handler Control and State Register SHCSR = 0x0040bba6   
------------------------------------------------------------------   
MEMFAULTACT = 0   
BUSFAULTACT = 1, BusFault 异常被触发   
USGFAULTACT = 0   
SVCALLACT = 1, SVC 中断被触发   
MONITORACT = 1, Debug monitor 被触发   
PENDSVACT = 0   
SYSTICKACT = 1, SYSTICK 中断触发   
USGFAULTPENDED = 1, UsageFault 异常挂起bit被设置   
MEMFAULTPENDED = 1, Memory Management Fault 异常挂起bit被设置   
BUSFAULTPENDED = 0   
SVCALLPENDED = 1, SVC 中断挂起bit被设置   
MEMFAULTENA = 0   
BUSFAULTENA = 0   
USGFAULTENA = 0   
读内存失败 0xE000ED2C

   
------------------------------------------------------------------   
Read HardFault Status Register HSFR Register = 0x0040bba6   
------------------------------------------------------------------   
VECTBL = 1, 中断向量表读取有Bus Fault   
            Indicates a Bus Fault on a vector table read during exception processing   
            When this bit is set, the PC value stacked for the exception return points   
            to the instruction that was preempted by the exception. This error is always   
            a Hard Fault   
FORCED = 0, no forced Hard Fault   
读内存失败 0xE000ED28

   
------------------------------------------------------------------   
MemManage Status Register (MMFSR) = 0xa6   
------------------------------------------------------------------   
IACCVIOL = 0, 无指令访问冲突错误   
DACCVIOL = 1, 有数据访问异常   
            the processor attempted a load or store at a location that does not permit the operation.   
            The PC value stacked for the exception return points to the faulting instruction. The processor   
            has loaded the MMFAR with the address of the attempted access   
MUNSTKERR = 0,  出栈正常   
MSTKERR = 0,  入栈正常   
MLSPERR = 1, 浮点lazy stacking特性保存期间生故障   
            fault occurred during floating-point lazy state preservation   
            The PC value stacked for the exception return points to the faulting instruction. The processor   
            MemManage fault during floating point lazy state preservation, only Cortex-M with FPU   
MMARVALID = 1, SCB->MMFAR寄存器记录了有效的异常地址   
            SCB->MMFAR holds a valid fault address   
            If a MemManage fault occurs and is escalated to a HardFault because of priority, the HardFault   
            handler must set this bit to 0. This prevents problems on return to a stacked active MemManage   
            fault handler whose SCB->MMFAR value has been overwritten   
读内存失败 0xE000ED34

   
------------------------------------------------------------------   
MemManage Address Register (MMFAR) = 0x0040bba6   
------------------------------------------------------------------   
Data address for a MemManage fault. This register is updated with the address of a location   
that produced a MemManage fault. The MMFSR shows the cause of the fault. This field is valid   
only when MMFSR.MMARVALID is set. In implementations without unique BFAR and MMFAR   
registers, the value of this register is UNKNOWN if BFSR.BFARVALID is set   
读内存失败 0xE000ED29

   
------------------------------------------------------------------   
BusFault Status Register (BFSR) = 0xa6   
------------------------------------------------------------------   
IBUSERR = 0, 指令总线正常   
PRECISERR = 1, 精确的数据总线访问异常   
            a data bus error has occurred, and the PC value stacked for the exception return points to   
            the instruction that caused the fault.   
            When the processor sets this bit, it writes the faulting address to BFAR.   
IMPRECISERR = 1, 不精确的数据总线访问异常   
            a data bus error has occurred, but the return address in the stack frame is not related to the   
            instruction that caused the error.   
            When the processor sets this bit it does not write a fault address to BFAR. This is an   
            asynchronous fault. Therefore, if it is detected when the priority of the current process is higher   
            than the BusFault priority, the BusFault becomes pending and becomes active only when the   
            processor returns from all higher priority processes. If a precise fault occurs before the   
            processor enters the handler for the imprecise BusFault, the handler detects both IMPRECISERR   
            set to 1 and one of the precise fault status bits set to 1   
UNSTKERR = 0, 中断出栈时正常   
STKERR = 0, 中断入栈时正常   
LSPERR = 1, 浮点lazy stacking特性保存期间生故障   
            fault occurred during floating-point lazy state preservation   
            BusFault during floating point lazy state preservation (only when FPU present)   
BFARVALID = 1, BFAR寄存器记录有效的异常地址   
            The processor sets this bit after a BusFault where the address is known. Other faults can set this   
            bit to 0, such as a MemManage fault occurring later. If a BusFault occurs and is escalated to a   
            HardFault because of priority, the HardFault handler must set this bit to 0. This prevents   
            problems if returning to a stacked active BusFault handler who is BFAR value has been   
            overwritten.   
读内存失败 0xE000ED38

   
------------------------------------------------------------------   
BusFault Address Register (BFAR) = 0x0040bba6   
------------------------------------------------------------------   
Data address for a precise BusFault. This register is updated with the address of a location that   
produced a BusFault. The BFSR shows the reason for the fault. This field is valid only when   
BFSR.BFARVALID is set. In implementations without unique BFAR and MMFAR registers, the   
value of this register is UNKNOWN if MMFSR.MMARVALID is set   
读内存失败 0xE000ED2A

   
------------------------------------------------------------------   
UsageFault Status Register (UFSR) = 0xbba6   
------------------------------------------------------------------   
UNDEFINSTR = 0, 处理器访问指令正常   
INVSTATE = 1,  无效状态   
            the processor has attempted to execute an instruction that makes illegal use of the   
            Execution Program Status Register (EPSR).   
            When this bit is set, the PC value stacked for the exception return points to the instruction that   
            attempted the illegal use of the EPSR. Potential reasons:   
            a) Loading a branch target address to PC with LSB=0.   
            b) Stacked PSR corrupted during exception or interrupt handling   
            c) Vector table contains a vector address with LSB=0.   
INVPC = 1,  无效的PC加载   
            the processor has attempted to load an illegal EXC_RETURN value to the PC as a result of an   
            invalid context switch   
            When this bit is set, the PC value stacked for the exception return points to the instruction that   
            tried to perform the illegal load of the PC. Potential reasons:   
            a) Invalid return due to corrupted stack pointer, link register (LR), or stack content.   
            b) ICI/IT bit in PSR invalid for an instruction.   
NOCP = 0, 访问协处理正常   
UNALIGNED = 1, 内存非对齐访问异常   
           the processor has made an unaligned memory access   
           Enable trapping of unaligned accesses by setting the UNALIGN_TRP bit in the CCR. Unaligned   
           LDM, STM, LDRD, and STRD instructions always fault irrespective of the setting of UNALIGN_TRP bit   
DIVBYZERO = 1, 除数为0时, 支持SDIV或者UDIV异常   
           the processor has executed an SDIV or UDIV instruction with a divisor of 0.   
           When the processor sets this bit to 1, the PC value stacked for the exception return points to the   
           instruction that performed the divide by zero. Enable trapping of divide by zero by setting the   
           DIV_0_TRP bit in the CCR to 1   

   
============================================================   
=========异常进一步分析======================================   
============================================================   
进入硬件异常前, 寄存器数值, 如果出现非精确异常, 这些值是不准确的:   
读内存失败 0x0040BBA6
R0 = 0040bba6   
读内存失败 0x0040BBAA
R1 = 0040bba6   
读内存失败 0x0040BBAE
R2 = 0040bba6   
读内存失败 0x0040BBB2
R3 = 0040bba6   
读内存失败 0x0040BBB6
R12 = 0040bba6   
读内存失败 0x0040BBBA
LR = 0040bba6   
读内存失败 0x0040BBBE
PC = 0040bba6   
读内存失败 0x0040BBC2
PSR = 0040bba6   
回复

使用道具 举报

57

主题

653

回帖

829

积分

金牌会员

积分
829
 楼主| 发表于 6 小时前 | 显示全部楼层
上面是开机卡的时候读到的数据,以下这个是刚刚完成后启动卡死的数据

2023-02-23 V1.0   
============================================================   
=========寄存器值读取========================================   
============================================================   
R0 = 00000000   
R1 = 40001400   
R2 = 00000251   
R3 = 52000000   
R4 = 00000000   
R5 = 00000002   
R6 = 00000026   
R7 = a5a5a5a5   
R8 = a5a5a5a5   
R9 = a5a5a5a5   
R10 = a5a5a5a5   
R11 = a5a5a5a5   
R12 = a5a5a5a5   
R13(SP) = 24048ce8   
R14(LR) = fffffff1   
R15(PC) = 90021bf6   
xPSR = 81000003   

   
------------------------------------------------------------------   
Read System Handler Control and State Register SHCSR = 0x00010000   
------------------------------------------------------------------   
MEMFAULTACT = 0   
BUSFAULTACT = 0   
USGFAULTACT = 0   
SVCALLACT = 0   
MONITORACT = 0   
PENDSVACT = 0   
SYSTICKACT = 0   
USGFAULTPENDED = 0   
MEMFAULTPENDED = 0   
BUSFAULTPENDED = 0   
SVCALLPENDED = 0   
MEMFAULTENA = 1, Memory management fault 异常使能   
BUSFAULTENA = 0   
USGFAULTENA = 0   

   
------------------------------------------------------------------   
Read HardFault Status Register HSFR Register = 0x40000000   
------------------------------------------------------------------   
VECTBL = 0, 中断向量表无Bus Fault   
FORCED = 1, forced Hard Fault   
            Indicates a forced Hard Fault, generated by escalation of a fault with configurable   
            priority that cannot be handled, either because of priority or because it is disabled   
            When this bit is set, the Hard Fault handler must read the other fault status registers   
            to find the cause of the fault   

   
------------------------------------------------------------------   
MemManage Status Register (MMFSR) = 0x00   
------------------------------------------------------------------   
IACCVIOL = 0, 无指令访问冲突错误   
DACCVIOL = 0,  无数据访问异常   
MUNSTKERR = 0,  出栈正常   
MSTKERR = 0,  入栈正常   
MLSPERR = 0,  浮点lazy stacking特性保存期间未发生故障   
MMARVALID = 0,  SCB->MMFAR寄存器没有记录异常地址   

   
------------------------------------------------------------------   
MemManage Address Register (MMFAR) = 0x00000000   
------------------------------------------------------------------   
Data address for a MemManage fault. This register is updated with the address of a location   
that produced a MemManage fault. The MMFSR shows the cause of the fault. This field is valid   
only when MMFSR.MMARVALID is set. In implementations without unique BFAR and MMFAR   
registers, the value of this register is UNKNOWN if BFSR.BFARVALID is set   

   
------------------------------------------------------------------   
BusFault Status Register (BFSR) = 0x00   
------------------------------------------------------------------   
IBUSERR = 0, 指令总线正常   
PRECISERR = 0, 数据总线正常   
IMPRECISERR = 0, 数据总线正常   
UNSTKERR = 0, 中断出栈时正常   
STKERR = 0, 中断入栈时正常   
LSPERR = 0, 浮点lazy stacking特性保存期间未生故障   
BFARVALID = 0, BFAR寄存器未记录有效的异常地址   

   
------------------------------------------------------------------   
BusFault Address Register (BFAR) = 0x00000000   
------------------------------------------------------------------   
Data address for a precise BusFault. This register is updated with the address of a location that   
produced a BusFault. The BFSR shows the reason for the fault. This field is valid only when   
BFSR.BFARVALID is set. In implementations without unique BFAR and MMFAR registers, the   
value of this register is UNKNOWN if MMFSR.MMARVALID is set   

   
------------------------------------------------------------------   
UsageFault Status Register (UFSR) = 0x0002   
------------------------------------------------------------------   
UNDEFINSTR = 0, 处理器访问指令正常   
INVSTATE = 1,  无效状态   
            the processor has attempted to execute an instruction that makes illegal use of the   
            Execution Program Status Register (EPSR).   
            When this bit is set, the PC value stacked for the exception return points to the instruction that   
            attempted the illegal use of the EPSR. Potential reasons:   
            a) Loading a branch target address to PC with LSB=0.   
            b) Stacked PSR corrupted during exception or interrupt handling   
            c) Vector table contains a vector address with LSB=0.   
INVPC = 0, PC加载正常   
NOCP = 0, 访问协处理正常   
UNALIGNED = 0, 内存对齐访问正常   
DIVBYZERO = 0,  无除数为0的异常, 或者没有使能除数为0的异常   

   
============================================================   
=========异常进一步分析======================================   
============================================================   
一直使用MSP, 返回Handler模式, 进入中断前没有使用硬件浮点单元   
进入硬件异常前, 寄存器数值, 如果出现非精确异常, 这些值是不准确的:   
R0 = 00000000   
R1 = 40001400   
R2 = 00000251   
R3 = 52000000   
R12 = a5a5a5a5   
LR = 9001fdd3   
PC = 00000000   
PSR = 80000046   
回复

使用道具 举报

677

主题

3460

回帖

5516

积分

论坛元老

积分
5516
发表于 1 小时前 | 显示全部楼层
ou513 发表于 2025-4-25 11:53
上面是开机卡的时候读到的数据,以下这个是刚刚完成后启动卡死的数据

2023-02-23 V1.0   

delay_ms(10) ;  这个 函数,你的 system_init 都还没有调用 你就优先调用了 delay 感觉有点不对吧 ?

要不你在 main 下面直接使用 for 做延时看看
回复

使用道具 举报

57

主题

653

回帖

829

积分

金牌会员

积分
829
 楼主| 发表于 26 分钟前 | 显示全部楼层
hpdell 发表于 2025-4-25 17:21
delay_ms(10) ;  这个 函数,你的 system_init 都还没有调用 你就优先调用了 delay 感觉有点不对吧 ?

...

跟这个也是无关的,这个就是想尝试一下,其实就是一个for循环而已。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-25 18:52 , Processed in 0.274973 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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