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

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

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

% T! H& _$ w: s; n# A

. F! g0 N0 \$ L1. 前言4 X' H! ~4 O- c1 k$ u
除0操作属于错误操作,在ARM Cortex-M平台上会有相应的报错机制。但这边会涉及到整型数的除0以及浮点数的除0,另外还会涉及错误产生后的报错机制,是中断还是错误位,本文会对这个报错机制加以说明。使用STM32H723做为测试芯片。2 A( P- u1 o7 O; }, [

9 {* H3 T- o, d" j" M& \5 k) r5 M2. 整形数除0操作报错 7 u5 C1 m* V( @' e
默认情况下,STM32H723对整形数的除0操作,会忽略掉错误,原因在于默认情况下 SCB->CCR寄存器默认配置中这个除0操作是非捕获状态,如果想要系统报错,需要把 DIV_0_TRP这个位置1,这样,当执行除0操作的时候会进入hardfault,并且有标志位产生。
12.png
▲ 图1. SCB CCR默认地址和复位初值
13.png
▲ 图2. DIV_0_TRP位于bit4
6 n% b- z' K" ^* @) G- @3 }" a  `: Q
' u3 H& D9 g- C+ \
14.png
▲ 图3. DIV_0_TRP参数说明
% V, V1 ]/ r- o/ I" l" b. `

/ L% ]2 P/ V" I# d2 T# ]测试执行整型数除0操作代码。
; Z* d' J4 a% k' g+ m& t/ F! X. `8 Y
  1. /* Enable System clock */) B* k/ P! P; F8 Q/ M! V" q
  2. __HAL_RCC_SYSCFG_CLK_ENABLE();! b+ l' k, {6 F9 F; f+ C3 l$ c0 z
  3. /* Enable DIV_0_TRP */
    ' Y1 w7 w9 O2 I  U
  4. SCB->CCR |= (1<<4);  K0 K& k# [! M. v) m% I4 ~* A
  5. /* Div value set to 0 */
    ) t8 f0 f& V* M% Z1 h
  6. IDiv = 0;- o& p) y$ m4 h: {! [, a1 F2 O2 i& A2 D
  7. /* Exctue div 0 */
    7 g8 c! z8 ^" e! R+ L0 J
  8. Iout = Iin/IDiv;
复制代码
15.png
▲ 图4. Fault Report-除0错误
16.png
▲ 图5. 查看进入Hardfault的程序位置

! ~/ K, l: b. \+ A7 N- N1 U
5 r. C" c- b7 E2 ]# Q* Q4 W. V$ M
17.png
▲ 图6. 找到因为除0导致的进入Hardfault

- |$ O6 F* K9 D6 [7 v' L( Z" d3. 浮点数除0的报错机制
8 E. M" B/ P  R8 W: c浮点数的除0操作,没有专门的Hardfault触发机制,也就不能产生中断,只能通过对FPU单元的读取进行判别,而且在调试模式下,通过IAR读取寄存器的结果是正确的,而通过Keil的读取会有错误,实际已经发生了浮点除0操作,但Keil的FPU->SCR寄存器DZC没有置位。
# h, W7 z# B3 Y7 X
18.png
▲ 图7. FPSCR寄存器

% C" O' T1 x6 z6 f, O3 n

  y0 J' N7 h1 C% E/ x, ~+ @执行浮点除0的测试代码:
. P8 y4 p  W( j* V* u0 G
  1. static volatile float fin = 0.9f,fout,fdiv;
    4 N$ i' G4 d# S% Z3 W/ ?
  2. static volatile uint16_t Mark;5 s# t# a" L9 J+ B9 `9 O. }
  3. /* Div value set to 0 */
    & F# T1 G& q# n
  4. fdiv = 0.0f;
    4 O+ c3 ^; [& J9 E3 C2 y' b
  5. /* Exctue float div 0 */
      e0 d0 _" y! D4 h
  6. fout  = fin/fdiv;
      _! n+ M6 e% C6 ^
  7. /* Get wrong mask value */5 {, i8 @+ t) f$ L9 ^* B
  8. Mark = __get_FPSCR();
复制代码

- ^! S% }3 {9 s- X) S: d# r! f
19.png
▲ 图8. IAR的浮点除0后DZC标志位置位
7 C' ~7 F3 r; G0 D* T2 ?
! o: L( M( X! T# ?% |( b% I+ P
20.png
▲ 图9. Keil浮点除0后DZC标志位有误

0 g- T$ L' W  c
  ~/ `# j9 n- c0 ~6 ~) C
读取FPSCR寄存器,返回错误码0x02(除0操作)。
; c, P2 u+ s* D8 ~7 l/ }' @) y, R; Y1 L, q

; ~4 {' h/ _% g0 R% p
21.png
▲ 图10. 读取FPSCR
; Z; ^, ]/ a# |# R5 v$ v9 l: L
& P$ g! E% E5 z+ m( r' l4 e# i6 `

7 F( D, s% Z6 }' `/ S1 Z
- z) x. [/ {3 d7 P9 r' q  v8 `
4. 结论   K, c' L; t& A) h2 ]" b+ A4 S3 }, V2 U+ S
本文通过对除0操作的报错机制做细致说明,可以看到整型除0可以有Hardfault的中断产生,而浮点的除0只能通过标志位判别,实际使用过程中尽量避免这种错误的操作。0 ?) Z0 U1 e7 V, [
* z3 j4 N7 D/ [* N2 b
& V1 E. q$ C" U% p% y
▼▼▼
点击按钮下载《Cortex-M核除0操作的报错机制话题》原文档。
3 S; z, s# ~, Y, ~8 Z& 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 手机版