你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

一个地址未对齐引起的 HardFault 异常

[复制链接]
STMCU小助手 发布时间:2023-2-19 17:00
1. 概述* `: `6 \9 \& Q0 z+ _! M! e- j. o% }# e
% p- O2 \- ~. m+ T
客户在使用 STM32G070 的时候,KEIL MDK 为编译工具,当编译优化选项设置为Level0 的时候,程序会出现 Hard Fault 异常,而当编译优化选项设置为 Level1 的时候,则程序运行正常。表面上看,这似乎是 KEIL MDK 的问题,通过分析,导致这个问题的本质原因是内存地址没有对齐引起的,下面章节将详细分析该问题的来龙去脉以及解决方法。% s5 Z, \" r8 r) Y
4 b8 B3 S( B* q* W

( q! I: F# |  w% H2. 问题描述与分析" N( y" e1 m8 S$ \& g$ k8 ~
根据客户的反馈,引起问题的代码很简单,客户定义了几个全局数组,在主程序中访问这几个数组就会出现 Hard Fault 异常,参考代码如下。; R, g( ~# Y$ K2 C1 K" V6 g* ^! \
& E+ o9 d8 y2 W4 A7 |
; E2 k& L' o( `- C+ m! k& d
Q$R@%5MPGE(]@$][)K7@]2Y.png
! X* t: H4 Z( ]5 f$ i  |- T2 g: [$ m0 }- o1 \

8 N  ^4 G, a2 g* Q7 O' P4 E把客户提供的代码片段移植到 NUCLEO-G070RB 开发板上,问题很容易就复现了,代码本身功能简单,写法上也没有错误,所以从代码片段本身上看,无法确定问题出在哪里,通过 KEIL 调试器,在汇编窗口单步调试下,最终发现导致 HardFault 异常的语句为下图所示语句。9 T/ A+ ^- \% X
) ]' [9 |$ x  D, U
9 ~" Y! ^" j, P! P
O)_2L%QRPG7CJ2NHS[`(I(S.png
& g( `2 j6 L* S- w+ E2 o2 p
/ O6 D7 t) A1 [' h, W$ J
. L1 A5 V! l( q
根据单步调试得知出现问题的语句为 LDR 指令,参考 Cortex M0 编程手册 PM0223 得知 LDR 指令的作用是从内存地址中加载一个 WORD 数据到目的寄存器 Rt 中,其中内存地址根据 Rn 或者 SP 寄存器的值以及立即数 imm 得到。- ?* r, c, T% Y4 t4 k; {

5 y$ G& W, m9 U" h+ L
/ Y1 O* d$ Y' P1 Z
5}0S7H12Z4W0TRV9EY7E5PI.png ! Z; G9 I8 Y0 g. D' N+ Y3 E/ M
, I+ [: y8 [1 u! T$ s# }

; I4 c1 r- r6 p! o+ S根据指令的描述,使用 LDR 指令的时候,通过 Rn 和 imm 计算得到的内存地址必须是读取字节数的倍数,LDR 每次读取一个 WORD,所以使用 LDR 指令时,内存地址必须 4字节对齐。如果地址没有对齐,则会导致 HardFault 异常。
( m- B( g( N# n7 H2 w4 i" A结合 LDR 指令的描述,在调试状态下,通过查看寄存器值,图 2 出错语句中根据 Rn和 imm 计算得到的内存地址为 R0=0x2000000B,imm=4 所以内存地址为 0x2000000F,很显然这个地址不是 4 字节对齐的。 $ X& b5 \  w( F3 d6 q/ t6 Q  u% d) {6 g& v0 p
8 f  o$ q; M4 I6 o6 p
% _7 S, E& M/ l! J

% {% Y( n% ]/ p4 a8 N* X! p完整版请查看:附件 一个地址未对齐引起的 HardFault 异常.pdf (673.92 KB, 下载次数: 9)
赞 收藏 评论0 发布时间:2023-2-19 17:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版