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

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

[复制链接]
STMCU-管管 发布时间:2025-2-6 09:10
4 c% Z+ D" u$ t9 h6 W9 D' X: A
! D, `7 o7 S3 }$ j+ ~1 d
1. 前言
0 O) L" Z# G1 l8 |& H& R) \除0操作属于错误操作,在ARM Cortex-M平台上会有相应的报错机制。但这边会涉及到整型数的除0以及浮点数的除0,另外还会涉及错误产生后的报错机制,是中断还是错误位,本文会对这个报错机制加以说明。使用STM32H723做为测试芯片。9 ~% ?  n% v8 U: I9 c; V
2 `+ [, k& U5 ~
2. 整形数除0操作报错
( w' }$ o* w- T0 t8 O& m
默认情况下,STM32H723对整形数的除0操作,会忽略掉错误,原因在于默认情况下 SCB->CCR寄存器默认配置中这个除0操作是非捕获状态,如果想要系统报错,需要把 DIV_0_TRP这个位置1,这样,当执行除0操作的时候会进入hardfault,并且有标志位产生。
12.png
▲ 图1. SCB CCR默认地址和复位初值
13.png
▲ 图2. DIV_0_TRP位于bit4
0 a8 h) @/ B1 f- i8 F2 ~. t1 h
' z9 V; \: K# M
14.png
▲ 图3. DIV_0_TRP参数说明
; ~5 U4 Y% G" s4 u/ j( e2 a
; p. H6 A% _: p. `8 v
测试执行整型数除0操作代码。7 L, A- v/ l! y
  1. /* Enable System clock */; R- F, Y+ t0 |0 n" S4 l
  2. __HAL_RCC_SYSCFG_CLK_ENABLE();, [4 b, \9 |) d9 H/ Y6 i4 {: ?
  3. /* Enable DIV_0_TRP */
    9 B% v2 _* J1 ?  z% b1 M
  4. SCB->CCR |= (1<<4);
    & H6 g- [, i# n. b5 M7 J/ c
  5. /* Div value set to 0 */
    - N% h- }: F! f  r0 [5 Q
  6. IDiv = 0;
    * Q) T& y& H6 X* I" d+ X2 A) M
  7. /* Exctue div 0 */
    $ I( J& F5 h% M+ j
  8. Iout = Iin/IDiv;
复制代码
15.png
▲ 图4. Fault Report-除0错误
16.png
▲ 图5. 查看进入Hardfault的程序位置
9 t4 D' l; f7 Q! a- N( l0 i- I! ?3 l
; @0 A. y% L. d5 [; V/ c' f& O0 {
17.png
▲ 图6. 找到因为除0导致的进入Hardfault

& P4 K8 Q3 @/ J  _) ]3. 浮点数除0的报错机制
3 ]7 z; H. h9 y. d9 l+ F: Q浮点数的除0操作,没有专门的Hardfault触发机制,也就不能产生中断,只能通过对FPU单元的读取进行判别,而且在调试模式下,通过IAR读取寄存器的结果是正确的,而通过Keil的读取会有错误,实际已经发生了浮点除0操作,但Keil的FPU->SCR寄存器DZC没有置位。
/ {6 Z- K% S4 s3 n7 m5 B) M
18.png
▲ 图7. FPSCR寄存器
1 R/ A! N$ p( |! P  s" I4 j$ J
6 }1 u9 |, M& o0 s4 t; y6 l
执行浮点除0的测试代码:4 p! v6 Z" n% m) q% m5 r: K
  1. static volatile float fin = 0.9f,fout,fdiv;
    5 B+ j2 c2 Q( v; A0 G
  2. static volatile uint16_t Mark;# I. ~; R, d! A( |
  3. /* Div value set to 0 */9 I' Q3 k, c! p0 J
  4. fdiv = 0.0f;
    * m9 G; W* W1 B. E8 j& r
  5. /* Exctue float div 0 */
    0 R1 J  X/ T( B$ T: g- [& v
  6. fout  = fin/fdiv;' s, t0 |. ~6 [4 ?5 c
  7. /* Get wrong mask value */6 z! p+ \5 x! P1 V3 G; s* ?/ E
  8. Mark = __get_FPSCR();
复制代码
% R/ w4 U1 T& ~! V7 {
19.png
▲ 图8. IAR的浮点除0后DZC标志位置位

! k0 c! Q- C' I" z7 F, N& C

$ d% e- l. s8 F# F' d
20.png
▲ 图9. Keil浮点除0后DZC标志位有误
$ B, n8 N( V. s& D# o
+ [" t& F& A. o: q
读取FPSCR寄存器,返回错误码0x02(除0操作)。
0 o6 N0 I# K& q: n* Q& c
( b* p0 f; f+ R- R
' k4 p4 }2 Z1 p1 ]2 R" Y0 x. y
21.png
▲ 图10. 读取FPSCR
) Y8 F: ^, m" s- Q! p' n/ Z
- W9 R* h$ ]7 T
- q+ Q" D& o; l

" }* k9 M! S7 N0 j4. 结论 0 x3 ^: u4 n/ y3 `
本文通过对除0操作的报错机制做细致说明,可以看到整型除0可以有Hardfault的中断产生,而浮点的除0只能通过标志位判别,实际使用过程中尽量避免这种错误的操作。! k( G) w4 D& w: q3 O) O' U

0 V8 w: {) \6 w8 @7 e8 i. i; Z1 X

; ?/ c. p+ |; @- G( Q6 f6 n4 Z6 @; E$ g$ K
▼▼▼
点击按钮下载《Cortex-M核除0操作的报错机制话题》原文档。
: u2 ]8 u, K/ j' B7 o' z! @ LAT1423_Cortex-M核除0操作的报错机制话题_v1.0.pdf (515.22 KB, 下载次数: 0)
收藏 评论0 发布时间:2025-2-6 09:10

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版