FPU inststructions freertos

Hello,

I would like to use the CMSIS lib with FPU instructions. Freertos is running on the cortex-m4. I use the GCC compiler. When I compile I got this message.

In file included from /home/arnaud/Projects/freertos-toradex/examples/imx7_colibri_m4/demo_apps/pbus/armgcc/../../../../../platform/CMSIS/Include/arm_math.h:291:0,
                 from /home/arnaud/Projects/freertos-toradex/platform/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q15.c:40:
/home/arnaud/Projects/freertos-toradex/examples/imx7_colibri_m4/demo_apps/pbus/armgcc/../../../../../platform/CMSIS/Include/core_cm4.h:131:8: warning: #warning "Compiler generates FPU instELructions for a device without an FPU (check __FPU_PRESENT)" [-Wcpp]
       #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"

Am I using FPU hardware instructions ? Or the soft one ?

CMake file

Hi @arnaud_infoteam

Could you provide the version of the hardware and software of your module?
Which carrier board are you using?

Regarding your issue, what is your application?
If possible could you provide a sample code?

Thanks and best regards,
Jaski

Hi @jaski.tx

Colibri IMX7D 1G emmc with the Colibri evaluation board rev.3.
To produce this warning you have to include the arm_math lib. Below a sample code. I need this lib for those functions in the CMSIS lib:

You don’t need to understand the code. Including files in CMakelist.txt is enough to produce the warning.

Thanks in advance !

main.c code:

///////////////////////////////////////////////////////////////////////////////
//  Includes
///////////////////////////////////////////////////////////////////////////////
#include "FreeRTOS.h"
#include "task.h"
#include "board.h"
#include "debug_console_imx.h"
#include "rdc_semaphore.h"
#include "gpio_pins.h"
#include "arm_math.h"
#include "arm_common_tables.h"
#include "string.h"
#include "stdbool.h"
#include "inttypes.h"
#include "stdarg.h"
#include "stdio.h"

///////////////////////////////////////////////////////////////////////////////
//  Global constants
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//  Global variables
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////

int alcorLog(const char *format, ...)
{
    va_list vargs;

    va_start(vargs, format);

    uint32_t timestamp_us = xTaskGetTickCount() * 1e6 / configTICK_RATE_HZ;
    
    printf("\n\r[%12d] ",timestamp_us);

    vprintf(format, vargs);

    va_end(vargs);
}

int println(const char *format, ...)
{
    va_list vargs;

    va_start(vargs, format);
    
    vprintf(format, vargs);
    
    printf("\n\r");

    va_end(vargs);
}


void IirTask(void *pvParameters)
{
    const uint32_t size = 512;
    uint32_t i;
    float32_t x[size];
    float32_t sinus[size];
    float32_t sinus_filtered[size];
    float32_t coeffs[] = {0.00554271721028068171, 0.0110854344205613634, 0.00554271721028068171,
    1.77863177782458481 , -0.800802646665707662};
    float32_t state[] = {0.0,0.0};

    arm_biquad_cascade_df2T_instance_f32 instance = {
        .numStages = 1,
        .pCoeffs = coeffs,
        .pState = state,
    };

    uint32_t start;
    uint32_t end;
    uint32_t duration;

    alcorLog("IIR Task started");

    println("");

    for(i = 0;i<size;i++)
    {
        x[i] = 2*PI/4000 * i * 100;
        sinus[i] = arm_sin_f32(x[i]);
    }

    println("Biquad init");
    arm_biquad_cascade_df2T_init_f32(&instance,1,&coeffs,&state);
    start = xTaskGetTickCount();
    for(i = 0;i<8;i++)
        arm_biquad_cascade_df2T_f32(&instance,sinus,sinus_filtered,size);
    end = xTaskGetTickCount();

    duration = (end - start)*1e6 / configTICK_RATE_HZ;
    for(i = 0;i<size;i++)
    {
        println("%" PRIu32 ";%f;%f",i,sinus[i],sinus_filtered[i]);
    }
    println("Biquad duration %" PRIu32 "us !",duration);
    alcorLog("FINISH !");



    while(true);
}


/*!
 * @brief Main function
 */
int main(void)
{
    // Initialize demo application pins setting and clock setting.
    hardware_init();
 
    // Create a demo task which will print Hello world and echo user's input.
    xTaskCreate(IirTask, "IIR Task", 2*1024,
                NULL,tskIDLE_PRIORITY+1, NULL);
    
    alcorLog("Welcome to Alcor !");

    // Start FreeRTOS scheduler.
    vTaskStartScheduler();

    // Should never reach this point.
    alcorLog("ERROR !");
    while (true);
}

/*******************************************************************************
 * EOF
 ******************************************************************************/

Add the mfloat hardware option to the compiler:

# DEFAULT ASM FLAGS
SET(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -mcpu=cortex-m4  -mfloat-abi=hard  -mfpu=fpv4-sp-d16  -mthumb  -Wall  -fno-common  -ffunction-sections  -fdata-sections  -ffreestanding  -fno-builtin  -mapcs  -std=gnu99")

# DEFAULT C FLAGS
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=cortex-m4  -mfloat-abi=hard  -mfpu=fpv4-sp-d16  -mthumb  -MMD  -MP  -Wall  -fno-common  -ffunction-sections  -fdata-sections  -ffreestanding  -fno-builtin  -mapcs  -std=gnu99")

# DEFAULT LD FLAGS
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mcpu=cortex-m4 -mfloat-abi=hard  -mfpu=fpv4-sp-d16  --specs=nano.specs  -Wall  -fno-common -ffunction-sections  -fdata-sections  -ffreestanding  -fno-builtin  -mthumb -mapcs  -Xlinker --gc-sections  -Xlinker -static  -Xlinker -z -z max-page-size=4096 -Xlinker muldefs -u _printf_float")

Add files in CMakeList.txt

# ADD_EXECUTABLE
ADD_EXECUTABLE(${ProjectName}
// Other entries
// ...
// ...
    "${BspRootDirPath}/platform/CMSIS/Include/arm_math.h"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q15.c"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/FastMathFunctions/arm_sin_f32.c"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_f32.c"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c"
    "${BspRootDirPath}/platform/CMSIS/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f32.c"
    "${BspRootDirPath}/platform/CMSIS/Include/arm_common_tables.h"
//...
//...

Dear @arnaud_infoteam

Look at the logic in ./platform/CMSIS/Include/core_cm4.h around line 131, and the the description in the header of this file:
To create the library using floating point, you need to define the compiler macro __FPU_PRESENT.

Try to add the following line to your CMakeList.txt.

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__FPU_PRESENT=1")

One way to verify that your code contains floating point intstructions is to disassemble it, e.g. using the online disassembler:
Upload your .elf file and force to THUMB disassembly, then navigate to one of the CMSIS math functions.

Regards, Andy

Thanks a lot !