cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F303: Where are __SOFT_FP, __ARM_FP, __GNUC__, __VFP_FP__, __SOFTFP__ defined?

AAnth.1
Senior

Hi

Having generated a blank STM32F303 project in STM32CubeIDE, my main file has the following code

#if !defined(__SOFT_FP__) && defined(__ARM_FP)
  #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif

My compiler flags are among others -mfpu=fpv4-sp-d16 -mfloat-abi=hard

I get the following warning as a compilation output:

../Src/main.c:10:4: warning: #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use." [-Wcpp]

Full compiler invocation:

arm-none-eabi-gcc -mcpu=cortex-m4 -g3 -c -x assembler-with-cpp -MMD -MP -MF"Startup/startup_stm32f303cctx.d" -MT"Startup/startup_stm32f303cctx.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Startup/startup_stm32f303cctx.o" "../Startup/startup_stm32f303cctx.s"
arm-none-eabi-gcc "../Src/main.c" -mcpu=cortex-m4 -std=gnu11 -g3 -DSTM32 -DSTM32F303xC -DSTM32F3 -DSTM32F303CCTx -DDEBUG -c -I../Inc -I../Drivers/CMSIS/Device/ST/STM32F3xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Src/main.d" -MT"Src/main.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Src/main.o"
arm-none-eabi-gcc "../Src/syscalls.c" -mcpu=cortex-m4 -std=gnu11 -g3 -DSTM32 -DSTM32F303xC -DSTM32F3 -DSTM32F303CCTx -DDEBUG -c -I../Inc -I../Drivers/CMSIS/Device/ST/STM32F3xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Src/syscalls.d" -MT"Src/syscalls.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Src/syscalls.o"
arm-none-eabi-gcc "../Src/sysmem.c" -mcpu=cortex-m4 -std=gnu11 -g3 -DSTM32 -DSTM32F303xC -DSTM32F3 -DSTM32F303CCTx -DDEBUG -c -I../Inc -I../Drivers/CMSIS/Device/ST/STM32F3xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Src/sysmem.d" -MT"Src/sysmem.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Src/sysmem.o"
arm-none-eabi-gcc "../Drivers/CMSIS/Device/ST/STM32F3xx/system_stm32f3xx.c" -mcpu=cortex-m4 -std=gnu11 -g3 -DSTM32 -DSTM32F303xC -DSTM32F3 -DSTM32F303CCTx -DDEBUG -c -I../Inc -I../Drivers/CMSIS/Device/ST/STM32F3xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/CMSIS/Device/ST/STM32F3xx/system_stm32f3xx.d" -MT"Drivers/CMSIS/Device/ST/STM32F3xx/system_stm32f3xx.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Drivers/CMSIS/Device/ST/STM32F3xx/system_stm32f3xx.o"
../Src/main.c:10:4: warning: #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use." [-Wcpp]
   10 |   #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
      |    ^~~~~~~

So I am wondering where these defines are hidden, but it seems very difficult to locate them. Digging deeper, I found the CMSIS specific "core_cm4.h" file, which has the following code:

#elif defined ( __GNUC__ )
  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
    #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
      #define __FPU_USED       1U

__FPU_PRESENT is defined in a file called "stm32f303xc.h":

#define __CM4_REV                 0x0001U  /*!< Core revision r0p1                            */
#define __MPU_PRESENT             1U       /*!< STM32F303xC devices provide an MPU */
#define __NVIC_PRIO_BITS          4U       /*!< STM32F303xC devices use 4 Bits for the Priority Levels */
#define __Vendor_SysTickConfig    0U       /*!< Set to 1 if different SysTick Config is used */
#define __FPU_PRESENT             1U       /*!< STM32F303xC devices provide an FPU */

But it leaves me with the unknown __VFP_FP__ and __SOFTFP__ defines, which I cannot seem to find :\

I believe I went through all possible header and CMSIS files, but cannot seem to find the relevant defines. Is there anything magic happening behind the scenes that I am not aware of?

PS: I am using GNU GCC as a compiler/toolchain.

Thank you,

5 REPLIES 5
KnarfB
Principal III

Those are gcc built-in defines which depend on the machine/arch/... options you are using. You can show them by preprocessing an empty file and dumping the output to stdout like:

arm-none-eabi-gcc.exe -mcpu=cortex-m4 -dM -E - < /dev/null

Replace /dev/null by NUL for Windows.

hth

KnarfB

Thank you, that is some very interesting information. I didn't know that before.

That basically leaves me with the two missing defines from the main code:

#if !defined(__SOFT_FP__) && defined(__ARM_FP)
  #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif

__SOFT_FP_ and __ARM_FP

Any idea what's the background story or relevance of that? To me, it appears that __SOFT_FP__ and __ARM_FP are nowhere defined and have little to none relevance in the code. Either just ignoring the warning during compilation, or just deleting the above code from my project.

Would you agree?

Thank you,

Hmm. Just generated STM32CubeMX code for STM32F302RB Nucleo board (the closest match I own). There is not such #if ... block generated in my main.c or anywhere else in the project.

The rationale is, that the FPU needs initialization before the first FPU instruction is executed. This is handled in SystemInit(); in system_stm32f3xx.c:

void SystemInit(void)
{
/* FPU settings --------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
#endif
...

Don't know how that is mapped to the macros. If the FPU init code is present, you could probably ignore that warning.

May I ask, @KnarfB, when you generated the project using STM32CubeMX, did you end up with HAL/LL and a setup of your MCU?

I generated a blank STM32CubeIDE project, see attached figure. When using the pin configuration tool and generating a HAL based project, the #if ... block is not generated, either.

I believe that I am a rare use case for ST, and their implementation of the #if ... block is not fully thought through, but no one has made them aware of it. It would be nice if a ST employee could give a comment on this topic?

Cheers,

0693W00000GZLMqQAP.png

> did you end up with HAL/LL and a setup of your MCU?

Yes, you're right. I'm using "Empty" rarely, but tried it now and got the same code sequences as you did. Note that __SOFTFP__ will be defined when you invoke gcc with  -mfloat-abi=soft and __ARM_FP is defined when specifying -mfloat-abi=hard. So, the generated #if block shall remind you to add a line for FPU initialization because no SystemInit() code is generated in "Empty" projects.

Did you try FPU instructions? When the FPU was not initializied, you will get a fault at runtime (no coprocessor).

hth

KnarfB