良许Linux教程网 干货合集 单片机中除以0会发生什么?

单片机中除以0会发生什么?

有人在使用STM32G4系列芯片开发产品时发现,在程序中进行除以零的操作时会引发出错异常中断,影响程序的运行。他想知道是否可以通过设置,在发生除以零操作时不让程序跳转到异常中断,并希望此时的除法运算结果(商)直接等于当前变量类型所支持的最大值。例如,如果被除数是16位变量,则经过除以零操作后直接将商的值赋为0xffff。实际应用中,客户的需求通常是多种多样的。

那么问题来了,是否可以满足这位STM32用户的要求呢?让我们一起来探讨一下。

首先,这个问题与STM32芯片的外设并不直接相关,而是与内核有关。用户选择了带有Cortex-M4内核的STM32芯片,因此我们需要从M4内核的手册中寻找相关内容。

通过查阅ARM Cortex-M4内核的手册,我们发现除以零的操作会导致用法异常(UsageFault)。同时,手册还提到,该操作以及非对齐访问操作是否触发异常是可以配置的。具体信息请参考下方绿色方框内的文字。

(请注意,手册的文档内容无法进行深度伪原创,请直接参考原文。)

通过配置相应的寄存器,我们可以控制除以零操作的行为。但是需要注意的是,除以零是一种错误的操作,可能会导致不可预测的结果和不稳定的系统行为。因此,在进行此类配置时,我们需要谨慎考虑,并确保其符合实际应用的需求和可靠性要求。

总之,我们可以根据M4内核手册中的配置信息,来满足这位STM32用户的需求。

image-20231013220836126
image-20231013220836126

那么对该用法异常的监测控制是通过哪个寄存器进行配置的呢?经浏览手册得知它是通过配置控制寄存器[SCB->CCR]进行配置的。

image-20231013220839267
image-20231013220839267
image-20231013220842451
image-20231013220842451

根据上面描述可知,当CCR寄存器的DIV_0_TRP位被配置0时,即使发生除以0操作也不会触发异常,只有当该位被置1前提下,当发生除以0操作时才触发异常事件并产生相应中断。

下面我们具体验证下。我找了块M4内核的STM32芯片的开发板。我们先使用ARM MDK来验证。

测试代码很简单,就是下面截图中的几行,简单的闪灯操作,里面夹了一句除法操作。SCB->CCR被赋值0x00000210即置位了DIV_0_TRP,当被赋值0x00000200时对其进行清零。

image-20231013220845049
image-20231013220845049

经过测试,当我们置位上面CCR寄存器的DIV_0_TRP位,在发生除以0操作时就会进入HardFault中断,同时被除数的结果【Result】即商变为0.

image-20231013220847588
image-20231013220847588

而当我们对DIV_0_TRP位清零,即SCB->CCR被赋值0x00000200时发生除以0操作不会触发Hardfault中断,但被除数除以0后其结果依然保持为0。整个程序运行起来感觉不到任何阻滞。

上面是基于ARM MDK环境测试的,我们换为IAR IDE测试看看。

我们依然先验证CCR寄存器的DIV_0_TRP位被置1的情况。经测试,结果跟ARM MDK环境下的测试结果完全一致。

image-20231013220851826
image-20231013220851826

当我们对CCR寄存器的DIV_0_TRP位清零时,测试结果也跟ARM MDK环境下的一致。

显然,结合Cortex M4内核手册的描述和实际验证,当发生除以0操作时是否触发异常事件是可以配置的,至于发生除以0操作后的商,它始终是0,这个结果其实在上面截图有明确提及,这里再单独截图出来。

image-20231013220854882
image-20231013220854882

不过,这个结果跟开篇客户所期望的不一致,这是由硬件决定的,不同的硬件在这个地方处理不尽相同。其实,其它Cortex M内核芯片这个地方约定是一样的。

聊到这里,或许有人发现了一个问题。从手册上看,这个除以0操作触发的应该是用法异常【UsageFault】,而我们在实际测试时进入的中断却是HardFault异常,这两个异常并不一样啊?

image-20231013220857830
image-20231013220857830

这是怎么回事呢?在此抛砖引玉吧,有兴趣的话不妨查找相关资料继续寻找相关答案。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部