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

cathy的头像
cathy 发布于:周四, 01/16/2025 - 10:51 ,关键词:

1. 前言

除0操作属于错误操作,在ARM Cortex-M平台上会有相应的报错机制。但这边会涉及到整型数的除0以及浮点数的除0,另外还会涉及错误产生后的报错机制,是中断还是错误位,本文会对这个报错机制加以说明。使用STM32H723做为测试芯片。

2. 整形数除0操作报错 
默认情况下,STM32H723对整形数的除0操作,会忽略掉错误,原因在于默认情况下 SCB->CCR寄存器默认配置中这个除0操作是非捕获状态,如果想要系统报错,需要把 DIV_0_TRP这个位置1,这样,当执行除0操作的时候会进入hardfault,并且有标志位产生。

1.png

▲ 图1. SCB CCR默认地址和复位初值 

2.png

▲ 图2. DIV_0_TRP位于bit4

3.png

▲ 图3. DIV_0_TRP参数说明 

测试执行整型数除0操作代码。

/* Enable System clock */  __HAL_RCC_SYSCFG_CLK_ENABLE();
/* Enable DIV_0_TRP */  SCB->CCR |= (1<<4);
/* Div value set to 0 */  IDiv = 0;
/* Exctue div 0 */  Iout = Iin/IDiv;

4.png

▲ 图4. Fault Report-除0错误

5.png

▲ 图5. 查看进入Hardfault的程序位置 

6.png

▲ 图6. 找到因为除0导致的进入Hardfault 

3. 浮点数除0的报错机制 

浮点数的除0操作,没有专门的Hardfault触发机制,也就不能产生中断,只能通过对FPU单元的读取进行判别,而且在调试模式下,通过IAR读取寄存器的结果是正确的,而通过Keil的读取会有错误,实际已经发生了浮点除0操作,但Keil的FPU->SCR寄存器DZC没有置位。

7.png

▲ 图7. FPSCR寄存器 

执行浮点除0的测试代码:

static volatile float fin = 0.9f,fout,fdiv;
static volatile uint16_t Mark;
/* Div value set to 0 */ fdiv = 0.0f;
/* Exctue float div 0 */ fout  = fin/fdiv;
/* Get wrong mask value */ Mark = __get_FPSCR();

8.png

▲ 图8. IAR的浮点除0后DZC标志位置位 

9.png

▲ 图9. Keil浮点除0后DZC标志位有误

读取FPSCR寄存器,返回错误码0x02(除0操作)。

10.png

▲ 图10. 读取FPSCR 

4. 结论 

本文通过对除0操作的报错机制做细致说明,可以看到整型除0可以有Hardfault的中断产生,而浮点的除0只能通过标志位判别,实际使用过程中尽量避免这种错误的操作。

来源:STM32

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 8