log2导致C中的STM32F4 MCU出现故障

log2导致C中的STM32F4 MCU出现故障,c,arm,stm32,stm32f4,stm32cubeide,C,Arm,Stm32,Stm32f4,Stm32cubeide,为什么这段代码会导致硬故障并跳入无限循环 #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 } 特许生产线的d0=0,r7=0x2002

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

#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
}
特许生产线的d0=0,r7=0x2002Fcc

执行此行后,反汇编程序跳转到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
-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
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
-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。

关于你的问题:

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

声明如下:

double position = log2(first_set);
未将变量val传递给函数:log2


我预计会出现这样的编码错误,因为没有定义第一个集合会导致代码无法编译。

关于您的问题:

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

声明如下:

double position = log2(first_set);
未将变量val传递给函数:log2


我预计会出现这样的编码错误,因为没有定义first_set会导致代码无法编译。

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

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


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

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

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

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

问题在于:

08000e14:vldr d0,[r7,16]/问题在这里:


08000e14:vldr d0,[r7,16]/STMF4系列不支持双精度浮点。将双精度浮点更改为浮点以使用单精度浮点。

STMF4系列不支持双精度浮点。将双精度浮点更改为单精度浮点。

注释不用于扩展讨论;这段对话已经结束了。你的MCU到底是什么?你的编译器选项是什么?看起来您使用的是双精度指令,而MCU不支持。@bumsikim我使用的是STM32F429ZI,我不确定如何与您准确共享我的编译器选项。我在问题中添加了gcc命令行选项,希望这就是您需要的。如果您使用优化,编译器可能会为您折叠常量,甚至可能是log2调用。constexpr double first_set或static const也可以工作。您肯定希望在生产代码中使用它。是否有理由将-mfpu=fpv4-sp-d16-mfloat abi=hard-mthumb作为汇编程序而不是编译器选项?注释不用于扩展讨论;这段对话已经结束了。你的MCU到底是什么?你的编译器选项是什么?看起来您使用的是双精度指令,而MCU不支持。@bumsikim我使用的是STM32F429ZI,我不确定如何与您准确共享我的编译器选项。我在问题中添加了gcc命令行选项,希望这就是您需要的。如果您使用优化,编译器可能会为您折叠常量,甚至可能是log2调用。constexpr double first_set或static const也可以工作。您肯定希望在生产代码中使用它。是否有理由使用-mfpu=fpv4-sp-d1

6-mfloat abi=hard-mthumb作为汇编程序而不是编译器选项?很抱歉让您感到困惑。我编辑了一些变量名以使代码更简单,但忘记了修改文本。我再次修正了代码和问题。很抱歉让你困惑。我编辑了一些变量名以使代码更简单,但忘记了修改文本。我再次修复了代码和问题。我更新了问题中的编译器参数。不幸的是,这个问题仍然存在。@MohammedNoureldin不幸的是,我没有办法重现这个问题。定义多个声明目标体系结构的选项对我来说很可疑,我会确保你包含并链接了正确的库,并且只包含这些库。参数是由IDE定义的。实际上,链接math.h时有什么特别的需要注意的吗?在这里我也没做什么特别的事情,IDE添加了整个链接器参数,我没有在这里做任何更改。我在问题中更新了我的编译器参数。不幸的是,这个问题仍然存在。@MohammedNoureldin不幸的是,我没有办法重现这个问题。定义多个声明目标体系结构的选项对我来说很可疑,我会确保你包含并链接了正确的库,并且只包含这些库。参数是由IDE定义的。实际上,链接math.h时有什么特别的需要注意的吗?在这里我也没做什么特别的事情,IDE添加了整个链接器参数,我没有在这里做任何更改。我在问题中更新了我的编译器参数。不幸的是,问题仍然存在。@MohammedNoureldin Hmmm.-mcpu=cortex-m4-mfpu=auto work吗?您删除了-mfloat abi=hard吗?您不必显式地说-mfloat abi=soft,但请继续尝试。如果仍然失败,请再次仔细检查asm输出,它不应生成vldr d0,。。使用软FP ABI,除非您的GCC严重损坏。另外,您使用的GCC版本是什么?感谢您的努力和尝试重现错误!现在可以了!我明白了为什么这在以前没有帮助,现在也有了帮助。我对项目进行了清理,然后使用新设置重新构建了它-mfloat abi=软而无硬件FPU。清洁很重要,因为我以前没有清洁过,这就是为什么这不起作用的原因。@MohammedNoureldin根本不使用硬件FPU是你应该做的事情,只是作为一种极端的最后手段。实际的FPU是什么?你应该给出正确的编译器标志来使用它。我在问题中更新了我的编译器参数。不幸的是,问题仍然存在。@MohammedNoureldin Hmmm.-mcpu=cortex-m4-mfpu=auto work吗?您删除了-mfloat abi=hard吗?您不必显式地说-mfloat abi=soft,但请继续尝试。如果仍然失败,请再次仔细检查asm输出,它不应生成vldr d0,。。使用软FP ABI,除非您的GCC严重损坏。另外,您使用的GCC版本是什么?感谢您的努力和尝试重现错误!现在可以了!我明白了为什么这在以前没有帮助,现在也有了帮助。我对项目进行了清理,然后使用新设置重新构建了它-mfloat abi=软而无硬件FPU。清洁很重要,因为我以前没有清洁过,这就是为什么这不起作用的原因。@MohammedNoureldin根本不使用硬件FPU是你应该做的事情,只是作为一种极端的最后手段。实际的FPU是什么?您应该提供正确的编译器标志来使用它。