
1. 前言4 X' H! ~4 O- c1 k$ u 除0操作属于错误操作,在ARM Cortex-M平台上会有相应的报错机制。但这边会涉及到整型数的除0以及浮点数的除0,另外还会涉及错误产生后的报错机制,是中断还是错误位,本文会对这个报错机制加以说明。使用STM32H723做为测试芯片。2 A( P- u1 o7 O; }, [ 2. 整形数除0操作报错 7 u5 C1 m* V( @' e 默认情况下,STM32H723对整形数的除0操作,会忽略掉错误,原因在于默认情况下 SCB->CCR寄存器默认配置中这个除0操作是非捕获状态,如果想要系统报错,需要把 DIV_0_TRP这个位置1,这样,当执行除0操作的时候会进入hardfault,并且有标志位产生。 ![]() ▲ 图1. SCB CCR默认地址和复位初值 ![]() ▲ 图2. DIV_0_TRP位于bit4 6 n% b- z' K" ^* @) G- @3 }" a `: Q' u3 H& D9 g- C+ \ ![]() ▲ 图3. DIV_0_TRP参数说明 % V, V1 ]/ r- o/ I" l" b. `测试执行整型数除0操作代码。
![]() ▲ 图4. Fault Report-除0错误 ![]() ▲ 图5. 查看进入Hardfault的程序位置 5 r. C" c- b7 E2 ]# Q* Q4 W. V$ M ![]() ▲ 图6. 找到因为除0导致的进入Hardfault 3. 浮点数除0的报错机制 浮点数的除0操作,没有专门的Hardfault触发机制,也就不能产生中断,只能通过对FPU单元的读取进行判别,而且在调试模式下,通过IAR读取寄存器的结果是正确的,而通过Keil的读取会有错误,实际已经发生了浮点除0操作,但Keil的FPU->SCR寄存器DZC没有置位。 ![]() ▲ 图7. FPSCR寄存器 执行浮点除0的测试代码:
![]() ▲ 图8. IAR的浮点除0后DZC标志位置位 7 C' ~7 F3 r; G0 D* T2 ?! o: L( M( X! T# ?% |( b% I+ P ![]() ▲ 图9. Keil浮点除0后DZC标志位有误 ~/ `# j9 n- c0 ~6 ~) C 读取FPSCR寄存器,返回错误码0x02(除0操作)。 ) y, R; Y1 L, q ![]() ▲ 图10. 读取FPSCR ; Z; ^, ]/ a# |# R5 v$ v9 l: L& P$ g! E% E5 z+ m( r' l4 e# i6 ` - 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操作的报错机制话题》原文档。![]() |
实战经验 | AFCI上位机用户手册
刘氓兔的杂谈【001】-片上USB 高速PHY
实战经验 | STM32G474 FPU 性能优化与测量
【STM32U083测评】GPIO使用点亮LED和按键操作
【我在论坛打嵌赛】01-嵌赛是个什么东东
STM32的CAN FD位定时设置注意事项
【庆元旦】基于NUCLEO_U5A5ZJ-Q的TobudOS移植
STM32CubeMX STM32F4 HAL库 工程建立
STM32 VS Code Extension (在Ubuntu上开发STM32,ST官方vscode插件使用指南)
【我的STM32U5 项目秀】+03-STM32U5-Coremark移植