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

实战经验 | Cortex-M核除0操作的报错机制话题

[复制链接]
STMCU-管管 发布时间:2025-2-6 09:10

' p3 e2 n' q9 C+ N# Q# E! c& w

& ]' M9 q3 v- d6 Y) t1. 前言
/ ^$ B8 `) H9 _; [除0操作属于错误操作,在ARM Cortex-M平台上会有相应的报错机制。但这边会涉及到整型数的除0以及浮点数的除0,另外还会涉及错误产生后的报错机制,是中断还是错误位,本文会对这个报错机制加以说明。使用STM32H723做为测试芯片。  ^& ]+ G0 c/ |5 [. W
4 F9 W, m- f; Z0 q" {1 A9 m
2. 整形数除0操作报错 ; A# u4 P0 O- p: d  C, j
默认情况下,STM32H723对整形数的除0操作,会忽略掉错误,原因在于默认情况下 SCB->CCR寄存器默认配置中这个除0操作是非捕获状态,如果想要系统报错,需要把 DIV_0_TRP这个位置1,这样,当执行除0操作的时候会进入hardfault,并且有标志位产生。
12.png
▲ 图1. SCB CCR默认地址和复位初值
13.png
▲ 图2. DIV_0_TRP位于bit4

0 f7 t' J& e7 a# p7 r! G
8 J, M( J! A1 |. v4 Y; H7 a( S# \
14.png
▲ 图3. DIV_0_TRP参数说明
, H: Y. ^, b; J/ A* h, O+ }

: U* _0 f3 X5 C( {/ i+ R测试执行整型数除0操作代码。3 {$ l1 H, q# U
  1. /* Enable System clock */2 _$ R. ?( x. h6 g. }" q8 g
  2. __HAL_RCC_SYSCFG_CLK_ENABLE();  O' L) u" O9 n  U- K: }& S
  3. /* Enable DIV_0_TRP */
    , s: J/ k# Z. B5 l4 J
  4. SCB->CCR |= (1<<4);% X8 H8 C/ m0 P7 j( O- g' E  y3 a" Y
  5. /* Div value set to 0 */
    # H) Z8 A$ i- T) e$ G
  6. IDiv = 0;
    2 N& K. G; \2 Z4 O9 y
  7. /* Exctue div 0 */2 D! d6 S; N' l, {# h7 `+ N
  8. Iout = Iin/IDiv;
复制代码
15.png
▲ 图4. Fault Report-除0错误
16.png
▲ 图5. 查看进入Hardfault的程序位置
# H: A% x/ T& S, l. w

& t+ P( G! {0 t" W
17.png
▲ 图6. 找到因为除0导致的进入Hardfault

. E$ o) B) O" N* x+ ?3. 浮点数除0的报错机制
1 m& ^2 U+ t( Q5 h' [3 ~' Y5 d浮点数的除0操作,没有专门的Hardfault触发机制,也就不能产生中断,只能通过对FPU单元的读取进行判别,而且在调试模式下,通过IAR读取寄存器的结果是正确的,而通过Keil的读取会有错误,实际已经发生了浮点除0操作,但Keil的FPU->SCR寄存器DZC没有置位。
- Y" s) k% ~5 C" c! C
18.png
▲ 图7. FPSCR寄存器
8 I$ a& D, I# |. l. M
  B# d! z4 O) c
执行浮点除0的测试代码:% B6 x8 m3 D' G
  1. static volatile float fin = 0.9f,fout,fdiv;- D8 D  P) p- Q9 j5 ]. ]" |" z1 e* L
  2. static volatile uint16_t Mark;, S; `4 h& R1 U: C( m' h+ \
  3. /* Div value set to 0 */8 @1 m9 o5 H8 g; ]( H0 ?1 J& I9 ?
  4. fdiv = 0.0f;: p. M  B' M1 e- ?* d5 E% |( h6 a9 L
  5. /* Exctue float div 0 */
    + a+ \+ k* H# `+ N7 F4 v/ p6 D1 M
  6. fout  = fin/fdiv;# n  Z, L1 H" Z7 r  y
  7. /* Get wrong mask value */
    9 u8 d: V5 v; u3 P  k1 |$ p
  8. Mark = __get_FPSCR();
复制代码
( O' Q8 m% M- T% n0 I
19.png
▲ 图8. IAR的浮点除0后DZC标志位置位
: R) @: A9 _& h% t  ]/ f8 b6 K
5 D8 e/ l; E/ \; E- `: \
20.png
▲ 图9. Keil浮点除0后DZC标志位有误
2 K3 ^1 a+ L! `' E

. M# u$ a1 }: Y0 e读取FPSCR寄存器,返回错误码0x02(除0操作)。
( K: y5 k( Z+ ~+ l! w
" H) _8 y1 ]5 S/ J

. v7 a% E+ ^9 I1 X+ }$ {
21.png
▲ 图10. 读取FPSCR
, _5 J* h* o( u" w; a
5 U3 r) y2 s2 F3 H6 l
% H7 e* P. l& |2 z) T5 _" s% t# y7 k

: R3 I3 A/ Q6 d  w" q4. 结论
5 Q  c$ ~7 d$ t: c. K本文通过对除0操作的报错机制做细致说明,可以看到整型除0可以有Hardfault的中断产生,而浮点的除0只能通过标志位判别,实际使用过程中尽量避免这种错误的操作。
6 n1 o: w6 b+ A
% s/ ]% d/ T# D2 O9 b% g

2 V0 U5 {5 m, T+ C
▼▼▼
点击按钮下载《Cortex-M核除0操作的报错机制话题》原文档。
9 A( _! L' T: R LAT1423_Cortex-M核除0操作的报错机制话题_v1.0.pdf (515.22 KB, 下载次数: 0)
赞 收藏 评论0 发布时间:2025-2-6 09:10

举报

0个回答

所属标签

相似技术帖

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