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

【经验分享】使用指针调用函数产生 Hard Fault

[复制链接]
STMCU小助手 发布时间:2022-2-26 15:38
问题:+ t. D) f+ X1 y2 G
该问题由某用户提出,发生在 STM32F2xx 器件上。据其工程师讲述:在其产品设计中,使用了第三方的软件库。出于某种原因,第三方不能提供软件库的源代码,只能以二进制映像的形式供其使用。在软件工程中,通过相关设置将该映像定位到某一固定的地址上,用户程序则是通过各个库函数的入口地址来调用相关的库函数。在软件调试过程中,其工程师发现,将库函数的入口地址赋给函数指针,再用函数指针进行函数调用会导致程序跑飞。使用调试器中止程序运行后,发现程序停留在 Hard Fault 中断服务程序内。
! o' z6 p& S$ X' s6 L% E3 W6 P* S6 g; A) o4 x
+ x( X* z! f( ]5 u
  U% E: I0 D( P$ p0 F1 _0 D
调研:; C: S( E. b9 {( Z, ~) n" [  F6 g5 F
通过其工程师演示整个过程,确认问题现象的确如其所述。使用调试器单步跟踪,发现其程序在执行完调用指令后,被调用函数指令未及执行即跳转到 Hard Fault 服务程序。由此可断定与被调用函数无关。核对函数调用所使用的入口地址,属于 Flash 存贮器地址范围,且 4 字节边界对齐。检查软件中进行该函数调用的代码,如下:
* G; W* c+ m7 X" B7 h+ x/ n/ f1 b  a. U$ A2 _5 W1 L
@PEDAR]8)C(FH@USKQ}2NCG.png
: m" Z* c1 z) q. x% E* q1 Q
. _5 H3 h. O& t9 p2 U将代码修改如下:; Z: ?/ L" A3 e  O

5 X" T2 ~1 o. D+ e: | [QAFHOQH8DY0LMXECK8OE.png
. q$ u8 B. K! d" g" I- ~
& [0 L6 P4 B* V9 B, a; w: _' A运行该程序,库函数被成功调用并返回正确结果。) G8 m% G5 V3 q4 n5 w/ k, j

4 q1 P: P7 z+ V% Y2 b8 |结论:, v$ p3 a4 J/ n, f
函数指针取值非法而触发 Cortex-M 的出错保护机制,从而产生 Hard Fault 中断。
9 w5 A+ Z; |+ G3 m* S& p3 i1 J# S1 o. a/ X2 S0 [  I
处理:2 N5 M  F- S9 M6 ?
修改软件代码,如表(二)。
* E% Y% [% |/ t3 J* e, A
) {, K! i5 T, H$ M3 M) O, U建议:2 J4 J; U' q$ N7 W* F
Cortex-M 并非一款全新设计的处理器,它属于 ARM 处理器家族中的一员,在其前辈的基上发展而来。在继承了前几代处理器的若干优越性能之余,它也顺便继承了一些历史遗留问题。早在 ARM7 处理器时期,ARM 公司为了兼顾代码的执行效率和存贮效率,为其设计了两套指令集,即传说中的 ARM指令集和 Thumb 指令集。这两种指令集都可以在同一款处理器上执行,但又被区别对待,处理器不能同时识别这两种指令集。由此,ARM7 的运行模式被划分为 ARM 模式和 Thumb 模式,在每种模式下,只能识别一种指令集。然而,ARM7 处理器允许在运行中进行两种指令集模式的切换,以便能够对不同段落的代码分别用 ARM 指令集和 Thumb 指令集进行优化。通常,这种切换是通过调用指令 BX 实现的。在 BX 指令中,如果地址码为奇数,则切换到 Thumb 指令集,如果是偶数,则切换到 ARM 指令集。如表(三)的调用会切换到 Thumb 指令集,而表(四)的调用则换到 ARM 指令集。不过,这两个调用最终跳转的目的地址是一样的,因为 ARM7 的执令存贮一定是半字对齐的,所在实际取指时会忽略地址的最低位。
# D  e5 [7 o/ Q+ A3 a6 o
) v" g" \6 K. t" x& `. {/ N 36R(ZS{SQS`O5_M_9W050RI.png 3 P  [$ W2 f* S0 C& Q# T
' e2 V2 _7 L6 e6 J( o: E# H
处理器发展到 Cortex-M 这一代时,ARM 公司认识到了在两种指令集之间进行切换所带来的诸多不便与弊端,进而对这两套指令集做了整合,并扩展出了 Thumb2 指令集。这一指令中既有 32 位的指令,又有 16 位的指令。两种指令可以混合使用,而不必进行模式切换。所以,这一指令集兼顾了执行效率和存贮效率,同时也为软件编写提供了方便,实在是 ARM 公司良心发现之举。但是,作为ARM7 的继承者,Cortex-M 上有着其前代的深刻的印记。比如,Thumb2 指令集从概念上讲,还属于Thumb 指令集的一种,尽管 Cortex-M 已经不识别 ARM 指令了。同时,在 Cortex-M 的架构中,还保留有模式切换机制。而且,向 Thumb 指令集切换是被认可的,而向 ARM 指令集切换则被认为是一种错误,会被出错保护机制拦截,也就是进入了 Hard Fault 中断服务程序。或许,这是 ARM 公司从软件兼容性方面有所考虑,才保留下来的一个机制。但在实际的应用中,这不折不扣的给软件设计者挖了个大坑……* b5 |. N, K1 \  [" r! z4 n
3 D$ R3 I( e* {8 o1 I9 l
# g: s) S( j* a: o1 Z9 l! n
赞 收藏 评论0 发布时间:2022-2-26 15:38

举报

0个回答

所属标签

相似技术帖

官网相关资源

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