Overview
I'm having a weird issue with my STM32F407ZGT6 when attemting any operation with float
variables. The Infinite_Loop
Default Handler gets called and I get stuck. I'm using the STM32CubeIDE. The following is enough to make the STM32CubeIDE crash:
int main(void)
{
float my_float = 2.5;
for(;;)
{
my_float = 1; //Crashes here
}
}
Details
At failure, the debugging stack shows:
Thread #1 [main] 1 [core: 0] (Suspended : Step)
WWDG_IRQHandler() at C:\~\Documents\stm32\LM_STM32\Startup\startup_stm32f407zgtx.s:115 0x8000f80
<signal handler called>() at 0xfffffff9
main() at C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Src\main.c:60 0x8000d8e
arm-none-eabi-gdb (10.2.90.20210621)
ST-LINK (ST-LINK GDB server)
and the disassembly error message appears to accuse stack overflow (?):
fffffff9: Failed to execute MI command:
-data-disassemble -s 4294967289 -e 4294967437 -- 3
Error message from debugger back end:
Cannot access memory at address 0xfffffffe
I tried looking at the STM Floating point demonstration, but the examples don't do anything particular before using float
variables... At first, I thought it was only when attempting to printf
like others have experienced [2][3][4][5][6][7][8], but now it's evident the problem is with float
itself.
What am I not doing properly? Do I need a library or something???
Settings
MCU Settings:
Floating-point uinit: FPv4-SP-D16
Floating-point ABI: Hardware implementation (-mfloat-abi=hard)
Instruction set: Thumb2
Runtime library: Reduced C (--specs=nano.specs)
[x] -u_printf_float
[x] -u_scanf_float
GCC Assembler options:
-mcpu=cortex-m4 -g3 -DDEBUG -c -x assembler-with-cpp --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
GCC Compiler options:
--mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DSTM32 -DSTM32F4 -DSTM32F407ZGTx -c -I"C:\Users\Pesquisa2\STM32Cube\Repository\STM32Cube_FW_F4_V1.27.0\Drivers\CMSIS\Include" -I"C:\Users\Pesquisa2\STM32Cube\Repository\STM32Cube_FW_F4_V1.27.0\Drivers\CMSIS\Device\ST\STM32F4xx\Include" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Inc\App" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Inc\HAL" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Inc\Midware" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Src\App" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Src\HAL" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Src\Midware" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Inc" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\FATFS" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\mma845x_inc" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
GCC Linker options:
-mcpu=cortex-m4 -T"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\STM32F407ZGTX_FLASH.ld" --specs=nosys.specs -Wl,-Map="${BuildArtifactFileBaseName}.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -u _printf_float -u _scanf_float -Wl,--start-group -lc -lm -Wl,--end-group
CodePudding user response:
It is very simple. You need to enable the FPU before doing any FP operations. Otherwise you will rise the HardFault and you will end up in the empty exception handler. As you probably did not write distinct handlers you will have only one handler (identical will be discarded by the compiler and the name of the handler will be misleading).
If you use Cube set __FPU_PRESENT
nad __FPU_USED
macros to 1
or simply enable the FPU
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
BTW your code executes only because you have not enabled any optimizations. I would advise for debugging -Og
.
int main(void)
{
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
volatile float my_float;
my_float = 2.5f;
for(;;)
{
my_float = 1; //Crashes here
}
}
Also remember that 2.5
is not float only double. You need to use 'f' suffix, otherwise the compiler will call the conversion code.
float my_float = 2.5f;