0
0
Cnc-programmingHow-ToBeginner · 4 min read

How to Use FPU on ARM Cortex-M4: Setup and Example

To use the FPU on an ARM Cortex-M4, you must enable it by setting the CPACR register bits for coprocessors 10 and 11. Then, compile your code with floating-point support enabled and use floating-point instructions or operations directly in C or assembly.
📐

Syntax

To enable the FPU on ARM Cortex-M4, write to the CPACR (Coprocessor Access Control Register) in the System Control Block (SCB). Set bits 20-23 to enable full access to coprocessors 10 and 11, which control the FPU.

Example syntax in C to enable FPU:

  • SCB->CPACR |= (0xF << 20); — Enables full access to FPU coprocessors.
  • Use floating-point operations in your code after enabling.
c
/* Enable FPU on Cortex-M4 */
#include "core_cm4.h"  // CMSIS header for SCB

void enable_fpu(void) {
    SCB->CPACR |= (0xF << 20);  // Set bits 20-23 to enable CP10 and CP11
    __DSB();  // Data Synchronization Barrier
    __ISB();  // Instruction Synchronization Barrier
}
💻

Example

This example shows how to enable the FPU and perform a simple floating-point calculation on Cortex-M4.

c
#include "core_cm4.h"
#include <stdio.h>

void enable_fpu(void) {
    SCB->CPACR |= (0xF << 20);  // Enable FPU
    __DSB();
    __ISB();
}

int main(void) {
    enable_fpu();
    float a = 3.14f;
    float b = 2.0f;
    float c = a * b + 1.0f;  // Floating-point operation

    // Normally you would output via debugger or UART; here we simulate output
    printf("Result of floating-point calculation: %f\n", c);
    return 0;
}
Output
Result of floating-point calculation: 7.280000
⚠️

Common Pitfalls

Common mistakes when using the FPU on Cortex-M4 include:

  • Not enabling the FPU in the CPACR register before using floating-point instructions.
  • Forgetting to include the __DSB() and __ISB() instructions after enabling the FPU, which ensure proper synchronization.
  • Compiling without floating-point support enabled in the compiler settings, causing software floating-point emulation instead of hardware FPU usage.
  • Using floating-point operations before the FPU is enabled, which can cause faults.

Example of wrong and right way:

c
/* Wrong: Using float before enabling FPU */
float wrong_calc(float x) {
    return x * 2.0f;  // May cause fault if FPU not enabled
}

/* Right: Enable FPU first */
void enable_fpu(void) {
    SCB->CPACR |= (0xF << 20);
    __DSB();
    __ISB();
}

float right_calc(float x) {
    enable_fpu();
    return x * 2.0f;
}
📊

Quick Reference

StepActionDescription
1Enable FPUSet bits 20-23 in SCB->CPACR to enable CP10 and CP11.
2SynchronizeCall __DSB() and __ISB() to ensure changes take effect.
3Compile with FPU supportUse compiler flags like -mfpu=fpv4-sp-d16 and -mfloat-abi=hard.
4Use floating-point operationsWrite code using float/double types or FPU instructions.
5Avoid early useDo not use floating-point before enabling FPU to prevent faults.

Key Takeaways

Always enable the FPU by setting bits 20-23 in SCB->CPACR before using floating-point instructions.
Use __DSB() and __ISB() after enabling the FPU to ensure proper synchronization.
Compile your code with hardware floating-point support enabled to use the FPU effectively.
Avoid using floating-point operations before the FPU is enabled to prevent faults.
Check your compiler and linker settings to confirm FPU support is active.