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

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

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

# y. f( j8 o1 N: c

0 x1 `0 g4 [; A1. 前言& s2 \7 L' q$ n7 r! ?/ D  S- w# Q1 u
除0操作属于错误操作,在ARM Cortex-M平台上会有相应的报错机制。但这边会涉及到整型数的除0以及浮点数的除0,另外还会涉及错误产生后的报错机制,是中断还是错误位,本文会对这个报错机制加以说明。使用STM32H723做为测试芯片。0 z0 L; W; F# x) b9 i' I

0 H& i4 v! z' \9 \2. 整形数除0操作报错
( r0 `% E9 N5 |- Z1 u+ C
默认情况下,STM32H723对整形数的除0操作,会忽略掉错误,原因在于默认情况下 SCB->CCR寄存器默认配置中这个除0操作是非捕获状态,如果想要系统报错,需要把 DIV_0_TRP这个位置1,这样,当执行除0操作的时候会进入hardfault,并且有标志位产生。
12.png
▲ 图1. SCB CCR默认地址和复位初值
13.png
▲ 图2. DIV_0_TRP位于bit4
  B" a) I% W" S& U8 N; E

5 m8 r9 Q( s' {$ z9 ?' _
14.png
▲ 图3. DIV_0_TRP参数说明
# H6 m( \$ ~6 D, \

- v- R/ M4 e* Q6 e& S6 i8 }4 i, B. O5 v测试执行整型数除0操作代码。
. n& N0 A" b" y+ r
  1. /* Enable System clock */
    ( V* Y0 N/ s5 \' ^9 T% `9 a
  2. __HAL_RCC_SYSCFG_CLK_ENABLE();, c5 e1 q1 E% w$ p/ y
  3. /* Enable DIV_0_TRP */
    " A7 P; P% }, y' P$ v
  4. SCB->CCR |= (1<<4);! m5 ^9 U1 \2 ?+ N; }; G
  5. /* Div value set to 0 */! ?* n- W+ h/ `4 Y* |1 |) E
  6. IDiv = 0;
    $ @! ?/ x, p! }
  7. /* Exctue div 0 */
    $ h! r$ z4 e; g4 p) @) U+ A
  8. Iout = Iin/IDiv;
复制代码
15.png
▲ 图4. Fault Report-除0错误
16.png
▲ 图5. 查看进入Hardfault的程序位置

4 W* [5 j; }  x0 m. ?# g+ K
6 M+ |* h) T) L! {5 K2 I1 @
17.png
▲ 图6. 找到因为除0导致的进入Hardfault
9 E2 H9 k& @$ W3 G' Y. w; T: I1 V
3. 浮点数除0的报错机制 % N/ ]' U! n" ]' Z, S2 A! I/ ?
浮点数的除0操作,没有专门的Hardfault触发机制,也就不能产生中断,只能通过对FPU单元的读取进行判别,而且在调试模式下,通过IAR读取寄存器的结果是正确的,而通过Keil的读取会有错误,实际已经发生了浮点除0操作,但Keil的FPU->SCR寄存器DZC没有置位。
: }  ~# I' E( j3 C, C% A) X) ^, v
18.png
▲ 图7. FPSCR寄存器
; t' _& I& t7 n

# J' R3 h) Z0 E8 N5 D$ x执行浮点除0的测试代码:* V! B; B( W1 i! n+ o3 f! H; {% n
  1. static volatile float fin = 0.9f,fout,fdiv;1 k, h% f: p1 E$ U5 H8 f' E
  2. static volatile uint16_t Mark;; v/ z* Q; z- ?% V7 i$ X
  3. /* Div value set to 0 */) \4 {  \& u! H2 g1 _
  4. fdiv = 0.0f;
    6 t: B" g/ G; p8 S" {0 s+ X( b
  5. /* Exctue float div 0 */; \1 T: z& }2 f; |
  6. fout  = fin/fdiv;
    % W: m2 L4 ^6 ?% ]) R! s
  7. /* Get wrong mask value */4 q6 W/ Q; J4 m1 }
  8. Mark = __get_FPSCR();
复制代码

2 e- H1 w% x1 z
19.png
▲ 图8. IAR的浮点除0后DZC标志位置位
7 |$ M% j3 J& V; z2 F0 ]

) {. r/ `4 G! W* \0 h- R  @/ J
20.png
▲ 图9. Keil浮点除0后DZC标志位有误

6 l. S: A. A. A% h

0 ~, }. M. `5 x' z  e. }读取FPSCR寄存器,返回错误码0x02(除0操作)。
" q. g% n0 P0 f( X; t+ l) y
9 {( D% f+ c, f6 S

! @% B- V; V7 H# Q& `6 X
21.png
▲ 图10. 读取FPSCR

- f2 v& U: x( B! a! |( b, y+ ^+ F

# b$ ]# ]  a& ?6 [3 w& P$ A5 T
3 K9 w6 `6 h& f3 `

4 y' d! y1 k! v4. 结论
9 x; f( P% Z2 w本文通过对除0操作的报错机制做细致说明,可以看到整型除0可以有Hardfault的中断产生,而浮点的除0只能通过标志位判别,实际使用过程中尽量避免这种错误的操作。
) q" ?" [* v( i; g5 ~- v4 M, P# n2 {/ x1 x

0 F( o* k6 y+ `. g
▼▼▼
点击按钮下载《Cortex-M核除0操作的报错机制话题》原文档。
- O0 h1 D) g8 z+ z; H, X 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 手机版