首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >log2在C中引起STM32F4单片机故障

log2在C中引起STM32F4单片机故障
EN

Stack Overflow用户
提问于 2019-09-28 00:22:26
回答 4查看 631关注 0票数 1

为什么这段代码会导致硬错误并跳入无限循环?

代码语言:javascript
复制
#include <stdint.h>
#include <math.h>

void myfunc()
{  
    const double val = 1;
    double log_res = log2(val); // <----- THIS CAUSES A FAULT
    //double log_res = log2(1); // This works
}

当我用硬编码的1替换邪恶行中的val时,代码可以工作。因此,只有当我将val传递给log2 (如代码所示)时,问题才会发生。为什么会发生这种情况?

我正在使用STM32CubeIDE (基于eclipse),与STM32F429ZI单片机。

更新:

在反汇编窗口中检查异常显示发生了以下异常:

fffffff9:执行MI命令失败:-数据-反汇编-s 4294967289 -e 4294967429 -- 3调试器后端的错误消息:无法访问地址0 0xfffffffe的内存

有人知道为什么会这样吗?

更新2:

程序集说明中的调试:

代码语言:javascript
复制
54            const double val = 1;
08000e0a:   mov.w   r3, #0
08000e0e:   ldr     r4, [pc, #64]   ; (0x8000e50 <myfunc+88>)
08000e10:   strd    r3, r4, [r7, #16]
55            double log_res = log2(val);
08000e14:   vldr    d0, [r7, #16] // <------ X THIS LINE CAUSES THE PROBLEM X
08000e18:   bl      0x8002a9c <log>
08000e1c:   vmov    r0, r1, d0
08000e20:   add     r3, pc, #36     ; (adr r3, 0x8000e48 <myfunc+80>)
08000e22:   ldrd    r2, r3, [r3]
08000e26:   bl      0x800085c <__divdf3>

空行有d0=0,r7=0x2002ffcc

执行这一行之后,反汇编程序跳转到WWDG_IRQHandler

更新3:

GCC汇编程序选项(不确定这是做什么的):

代码语言:javascript
复制
-mcpu=cortex-m4 -g3 -c -x assembler-with-cpp --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb

GCC编译器选项:

代码语言:javascript
复制
-mcpu=cortex-m4 -std=gnu11 -g3 -DSTM32F429I_DISC1 -DSTM32 -DSTM32F429ZITx -DSTM32F4 -DDEBUG -DSTM32F429xx -c -I..\Inc -I../Inc/CMSIS/Include -I../Inc/CMSIS/Device/ST/STM32F4xx/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb

GCC链接器选项:

代码语言:javascript
复制
-mcpu=cortex-m4 -T"C:\Users\mne\STM32CubeIDE\workspace_1.0.0\MyUSB\STM32F429ZITX_FLASH.ld" --specs=nosys.specs -Wl,-Map="${ProjName}.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group

Udpate 4:

这个问题似乎发生在math.h的许多功能中,例如fmin

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-09-30 09:38:10

问题在于:

08000e14: vldr d0,r7,#16 // <

"d0“是64位VFP寄存器。然而,Cortex-M4F只有32位FPU (寄存器s0、s1等).皮质-m7F有64位FPU,但这不是你要用的。

因此,该指令对引起故障的Cortex-M4F核是无效的。我可以复制GCC 2018-Q4的版本。如果您移除-mfloat-abi=hard,问题就会消失,因为它随后使用ARM核心CPU寄存器传递参数。所以这就是我推荐的解决办法。

至于根本原因,我需要做更多的调查。

票数 2
EN

Stack Overflow用户

发布于 2019-09-30 07:13:12

您似乎忽略了编译器选项中的标志-mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb,并且只将它们包含在汇编程序选项中。(您可以用-march=armv7-m -mtune=cortex-m4代替-mcpu=cortex-m4。)因此,您的编译器正在为错误的浮点ABI生成代码.您指定了硬ABI,但是正在生成对软库函数的调用,而不是内联程序集指令。

编辑:--如果编译器正在生成FPU不支持的指令,正如ImageCraft观察到的那样,您可以尝试将标志更改为--mcpu=cortex-m4 --mfpu=auto

请注意,任何级别的优化,甚至-O1,都足以让GCC折叠常量并优化对double position = 0.0;的调用。您可能需要使用函数return position;来使其发出具有优化功能的代码。(我假设这是一个简化的MCVE,因为您根本不需要在运行时计算log2(1)。)

票数 3
EN

Stack Overflow用户

发布于 2019-09-29 22:50:47

关于你的问题:

当我用硬编码1代替邪恶行中的val时,代码就能工作了。因此,只有当我将val传递给log2 (如代码所示)时,问题才会发生。为什么会发生这种情况?

声明如下:

代码语言:javascript
复制
double position = log2(first_set);

不是将变量val传递给函数:log2()

我希望这样的编码错误(因为没有定义first_set )会导致代码不编译。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58142460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档