Skip to main content
Explorer II
June 21, 2025
Solved

Trouble with printf and sprintf with float in STM32Cube + VS Code (CMake)

  • June 21, 2025
  • 4 replies
  • 1208 views

Hi everyone,

I'm working on an STM32 (Nucleo-F446RE to be spesific) project using the STM32Cube extension for VS Code, not CubeIDE. I'm using CMake for building the project.

I encountered a few issues:

  1. printf doesn't print anything to the serial monitor, so I switched to using HAL_UART_Transmit.

  2. When I try to print a float using sprintf(msg, "value: %f\n", var);, it doesn’t work. The output just skips the float value (e.g., "value: \n").

  3. After some research, I found out I need to add "-u _printf_float" to the linker flags to enable float formatting support with printf and sprintf.
    However, I'm new to CMake and I couldn’t figure out which CMake file I need to modify in the project folder to add this flag.

I'd really appreciate it if someone could guide me:

  • Where exactly should I add the "-u _printf_float" flag?

  • Is there anything else I should do to make printf work properly over UART?

Thanks in advance for your help.

    This topic has been closed for replies.
    Best answer by manolo_embedded

    @umut373 wrote:
    • Where exactly should I add the "-u _printf_float" flag?


    As a beginner, I faced the same problem.

    I also use CMake, but I generate the project with STM32CubeMX, so I don't know what your configuration is. I use a NUCLEO-F439ZI board, so things might also be different on that side.

    On my end, I have a toolchain configuration file ./cmake/gcc-arm-none-eabi.cmake and I added the following line to be able to use snprintf with floats (however, i'm not sure if it's the best way to do it) :

    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u _printf_float")

     


    @umut373 wrote
    • Is there anything else I should do to make printf work properly over UART?

    For printf, I chose not to use it and instead created a custom function that resembles it and uses UART as you did.

    void print_to_uart(UART_HandleTypeDef huart, const char *format, ...)
    {
     char buffer[256];
     int cx;
    
     va_list args;
     va_start(args, format);
     cx = vsnprintf(buffer, sizeof(buffer), format, args);
     va_end(args); 
    
     if (cx >= 0 && cx < static_cast<int>(sizeof(buffer)))
     {
     HAL_UART_Transmit(&huart, (uint8_t*) buffer, cx, 1000);
     }
    }

    And I use it like this :

    print_to_uart(huart3 ,"This is PI value : %f \n", 3.141592);



    4 replies

    Super User
    June 25, 2025

    @umut373 wrote:
    1. printf doesn't print anything to the serial monitor


    Have you followed the instructions:

    https://community.st.com/t5/stm32-mcus/how-to-redirect-the-printf-function-to-a-uart-for-debug-messages/ta-p/49865

     

    Visitor II
    September 22, 2025

    @umut373 wrote:
    • Where exactly should I add the "-u _printf_float" flag?


    As a beginner, I faced the same problem.

    I also use CMake, but I generate the project with STM32CubeMX, so I don't know what your configuration is. I use a NUCLEO-F439ZI board, so things might also be different on that side.

    On my end, I have a toolchain configuration file ./cmake/gcc-arm-none-eabi.cmake and I added the following line to be able to use snprintf with floats (however, i'm not sure if it's the best way to do it) :

    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u _printf_float")

     


    @umut373 wrote
    • Is there anything else I should do to make printf work properly over UART?

    For printf, I chose not to use it and instead created a custom function that resembles it and uses UART as you did.

    void print_to_uart(UART_HandleTypeDef huart, const char *format, ...)
    {
     char buffer[256];
     int cx;
    
     va_list args;
     va_start(args, format);
     cx = vsnprintf(buffer, sizeof(buffer), format, args);
     va_end(args); 
    
     if (cx >= 0 && cx < static_cast<int>(sizeof(buffer)))
     {
     HAL_UART_Transmit(&huart, (uint8_t*) buffer, cx, 1000);
     }
    }

    And I use it like this :

    print_to_uart(huart3 ,"This is PI value : %f \n", 3.141592);



    Super User
    September 23, 2025

    Instead of adding options to the linker command line (can be tricky with cmake) you can do this in your linker script (.ld file): add

    EXTERN(_printf_float);

     

    /* or even reference _printf_float in your C source file, but make sure it won't be discarded as unreferenced */

     

    ST Employee
    September 30, 2025

    Be aware latest update is promoting some semihosting feature !
    Let's have a try enriching your launch.json relying on serverSemihosting parameter.