cancel
Showing results for 
Search instead for 
Did you mean: 

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

umut373
Associate

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.

4 REPLIES 4
Andrew Neil
Super User

@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

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
manolo_embedded
Associate

@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);



Pavel A.
Super User

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 */

 

vincent_grenet
ST Employee

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