log2在C中的STM32F4 MCU中导致故障

问题描述 投票:1回答:3

为什么此代码会导致硬故障并跳入无限循环?

#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 MCU一起使用。

UPDATE:

在反汇编窗口中检查异常显示这是发生的异常:

fffffff9:无法执行MI命令:-数据拆卸-s 4294967289 -e 4294967429-3来自调试器后端的错误消息:无法访问地址0xfffffffe的内存

任何人都知道为什么会这样吗?

更新2:

调试汇编说明:

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汇编器选项(不确定该怎么做):

-mcpu=cortex-m4 -g3 -c -x assembler-with-cpp --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb

GCC编译器选项:

-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链接器选项:

-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
c arm stm32 stm32f4 stm32cubeide
3个回答
2
投票

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

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

请注意,即使是-O1,任何级别的优化也足以使GCC折叠常数并优化对double position = 0.0;的调用。您可能需要具有函数return position;才能在优化启用的情况下发出此代码。 (我假设这是简化的MCVE,因为您实际上不需要在运行时计算log2(1)。)


0
投票

关于您的问题:

当我用硬编码1替换邪恶行中的val时,代码起作用。因此,仅当我将val传递给log2时,问题才会发生(如代码所示)。为什么会这样?

以下语句:

double position = log2(first_set);

没有将变量val传递给函数:log2()

我希望这样的编码错误(因为未定义first_set导致代码无法编译。


0
投票

问题在这里:

08000e14:vldr d0,[r7,#16] //

“ d0”是64位VFP寄存器。但是,Cortex-M4F仅具有32位FPU(寄存器s0,s1等)。 Cortex-M7F具有64位FPU,但这不是您正在使用的。

因此,该指令对于导致故障的Cortex-M4F内核无效。我可以在GCC 2018-Q4版本中复制它。如果删除了-mfloat-abi = hard,该问题将消失,因为它随后使用ARM核心CPU寄存器来传递参数。所以这就是我建议的解决方法。

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

© www.soinside.com 2019 - 2024. All rights reserved.