cancel
Showing results for 
Search instead for 
Did you mean: 

printf float problem STM32CubeIDE VSCode Clang-Compiler

fe3
Associate III

Extension 3.7.0
st-arm-clang 19.1.6+st.10

Hello,

I am using CubeIDE für VSCode.

I write programs for the STM32F756ZGTx. I have set ST Arm Clang as the compiler in CubeMX. Redirecting the output (printf()) via the serial debug interface is possible without any problems. When I try to output float or double values with printf(), I get some weird results.

printf() with integer float/double yields correct results for integer float/double wrong
printf() with float/double integer always leads to incorrect results


I repeated the experiment for double variables. The same problem occurs here as well.

#include "main.h"
#include <stdio.h>

extern UART_HandleTypeDef huart3;

double floatVar = 1.1f;

void mainThread(void)
{	
	printf("\r\n\nHello from Nucleo F756 - float Test\r\n"
		       "-----------------------------------\r\n");

	for(;;){ 
		printf("Float value: %f - Integer %u\r\n", floatVar, (unsigned int) floatVar);
		printf("Integer      %8u - Float value: %f\r\n",  (unsigned int) floatVar, floatVar);
        HAL_Delay(500);
        floatVar += 1.0f;
	}
}

int __io_putchar(int ch) {
	HAL_UART_Transmit(&huart3, (uint8_t*) &ch, 1, 100);
	return ch;
}

 

 

Variable type float

Hello from Nucleo F756 - float Test
-----------------------------------
Float value: 1.887500 - Integer 2684354560
Integer             1 - Float value: -0.000000
Float value: 2.012500 - Integer 3221225472
Integer             2 - Float value: -2.000000
Float value: 2.137500 - Integer 3221225472
Integer             3 - Float value: -2.000000
Float value: 2.256250 - Integer 1610612736
Integer             4 - Float value: 36893490000000000000.000000
Float value: 2.318750 - Integer 1610612736
Integer             5 - Float value: 36893490000000000000.000000
Float value: 2.381250 - Integer 1610612736
Integer             6 - Float value: 36893490000000000000.000000
Float value: 2.443750 - Integer 1610612736
Integer             7 - Float value: 36893490000000000000.000000


Variable type double

Hello from Nucleo F756 - float Test
-----------------------------------
Float value: 0.000000 - Integer 2684354560
Integer             1 - Float value: -0.000000
Float value: 0.000000 - Integer 3489660928
Integer             2 - Float value: -8589935000.000000
Float value: 0.000000 - Integer 3489660928
Integer             3 - Float value: -8589935000.000000
Float value: 0.000000 - Integer 1744830464
Integer             4 - Float value: 2417851600000000000000000.000000
Float value: 0.000000 - Integer 1744830464
Integer             5 - Float value: 2417851600000000000000000.000000
Float value: 0.000000 - Integer 1744830464
Integer             6 - Float value: 2417851600000000000000000.000000
Float value: 0.000000 - Integer 1744830464
Integer 

Please find enclosed the project.


What am I doing wrong? Is a linker or compiler option missing?

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
fe3
Associate III

I found a solution for the correct output. To do this, I added a line to starm-clang.cmake. 

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--defsym=vfprintf=__d_vfprintf -Wl,--defsym=vfscanf=__d_vfscanf") 

Here again in the context of the file

 

if (STARM_TOOLCHAIN_CONFIG STREQUAL "STARM_HYBRID")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --gcc-specs=nano.specs")
  set(TOOLCHAIN_LINK_LIBRARIES "m")
elseif(STARM_TOOLCHAIN_CONFIG STREQUAL "STARM_NEWLIB")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lcrt0-nosys")
elseif(STARM_TOOLCHAIN_CONFIG STREQUAL "STARM_PICOLIBC")
  # added line to enable float support in printf/scanf
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--defsym=vfprintf=__d_vfprintf -Wl,--defsym=vfscanf=__d_vfscanf") #<<<<
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lcrt0-hosted -z norelro")

 After these changes, I can output both float and double values correctly. The combination with integer and float/double also works.

I would be very grateful if someone could tell me whether this is the approach planned by ST.

Thanks

View solution in original post

4 REPLIES 4
fe3
Associate III

I found a solution for the correct output. To do this, I added a line to starm-clang.cmake. 

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--defsym=vfprintf=__d_vfprintf -Wl,--defsym=vfscanf=__d_vfscanf") 

Here again in the context of the file

 

if (STARM_TOOLCHAIN_CONFIG STREQUAL "STARM_HYBRID")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --gcc-specs=nano.specs")
  set(TOOLCHAIN_LINK_LIBRARIES "m")
elseif(STARM_TOOLCHAIN_CONFIG STREQUAL "STARM_NEWLIB")
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lcrt0-nosys")
elseif(STARM_TOOLCHAIN_CONFIG STREQUAL "STARM_PICOLIBC")
  # added line to enable float support in printf/scanf
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--defsym=vfprintf=__d_vfprintf -Wl,--defsym=vfscanf=__d_vfscanf") #<<<<
  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lcrt0-hosted -z norelro")

 After these changes, I can output both float and double values correctly. The combination with integer and float/double also works.

I would be very grateful if someone could tell me whether this is the approach planned by ST.

Thanks

This is an issue of the newlib nano or pico you are using. The don't support float formats by default. but supply a weak symbol which you may request linking like:

target_link_options(app PRIVATE 
  -specs=nano.specs 
  -Wl,-u,_printf_float 
  -lc 
  -lnosys 
)

or

clang --target=arm-none-eabi -mcpu=cortex-m4 -mthumb \
  -ffreestanding -nostdlib -nostartfiles \
  -I/path/to/picolibc/include \
  main.c \
  -L/path/to/picolibc/lib \
  -lc -lm \
  -Wl,-u,__printf_float \
  -o out.elf

 Haven't used it with clang (yet?), but with gcc. 

fe3
Associate III

Sorry for the late reply. I tested it again. In my test program, -Wl,-u,__printf_float does not work for picolibc.

fe3
Associate III

Alternatively, the following entry can also be made in CMakeLists.txt.

target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
    # Add user defined linker options
    "-Wl,--defsym=vfprintf=__d_vfprintf"
    "-Wl,--defsym=vfscanf=__d_vfscanf"
)