How should I use the floating-point unit (FPU) on Cortex-M4 ?

The STM32F4xx series is based on a Cortex-M4 core. This includes a floating-point unit (FPU) which offers hardware support for single-precision IEEE-754 floats. It can improve your application's performance if you are performing floating-point operations.

Here are some useful points to consider before using the FPU of your processor:

  1. The "float" type is fully supported in hardware, but the "double" type is supported through software emulation (veeery slow).
    All the functions available from <math.h> such as sin(), expf() and the like, use double by default, so if you use them your code will be be big and slow!
    Using the float versions of these functions (with a "f" suffix) such as sinf() or cosf() will make good use of the FPU capabilities.
  2. If you use multiple independent tasks that use floats, such as if you use floating-point in the foreground of your application as well as in interrutps; or if you use an RTOS with several tasks that perform floating-point arithmetic, you will be in trouble: The FPU state has to be preserved between its different uses, as it is not reentrant! This may lead to complex code or inefficiencies.
  3. The GCC toolchain offers 3 methods to handle floating-point on STM32F4xx. The correct method depends on your application and its requirements:
  • Emulated float (-mfloat-abi=soft option) which disables the FPU
  • Hardware FPU (-mfloat-abi=softfp option) with standard EABI parameter passing
  • Hardware FPU (-mfloat-abi=hard option) with specific parameter passing

Floating-point computing on embedded systems requires care, so you should only use it if necessary.
In particular, be wary of float comparisons, which are not absolute (an "epsilon" difference may exist), also some operations may generate exceptions, infinities, Not-a-Number...