cancel
Showing results for 
Search instead for 
Did you mean: 

printf and float

jagauthier
Associate III

So, I'm having an issue getting the printf() function suite to work with floating point values.

First, understand that I am not using STM32CubeIDE. It's a good tool, but I've had too many issues/complications using it. I use a custom Makefile and VScode for my development environment.

That said: With STM32CubeIDE I *can* go into the options and select "Use float with printf from newlib-nano (-u _printf_float)"

This adds "-u _printf_float" to the linker flags and floating point values work.

In My Makefile, I've added "-u _printf_float" to the linker arguments and floating point values are always "0.0".

I'm not sure what else would be causing this.

STM32's linker line versus mine:

arm-none-eabi-gcc -o "CT_ReadG431.elf" @"objects.list"   
-mcpu=cortex-m4 -TSTM32G431KBTx_FLASH.ld
--specs=nosys.specs -Wl,-Map="CT_ReadG431.map" -Wl,--gc-sections -static --specs=nano.specs
 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -u _printf_float -Wl,--start-group -lc -lm -Wl,--end-group

Mine:

arm-none-eabi-gccm [Object list omitted for brevity] -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard
 -specs=nano.specs -TSTM32G431KBTx_FLASH.ld  -lc -lm -lnosys 
 -Wl,-Map=build/CT_ReadG431.map,--cref -Wl,--gc-sections  -u _printf_float  
 -o build/CT_ReadG431.elf

Could it be something else?

10 REPLIES 10
KnarfB
Principal III

Try to match the order of the flags as close as possible, e.g. put it between nano.specs and the linker script.

hth

KnarfB

jagauthier
Associate III

Thanks for that. I did try that without any added success. What solved it was implying I did not want any form of optimizations (-O0)

I can reliable break and fix it by adding (or removing) compile time optimizations.

> In My Makefile, I've added "-u _printf_float" to the linker arguments and floating point values are always "0.0".

I don't use printf() in microcontrollers, but my understanding is, that it the float printing is off, then it won't print anything, i.e. not even "0.0".

JW

That was also my understanding. I resolved this by enabling -O0. Whenever optimizations are enabled in the compiler all values are 0.0.

@Community member​ is correct.

printf("temperature: %4.2f [C]\n", temperature);
 
temperature: 22.38 [C]   <-- linked with -u _printf_float
temperature: 22.44 [C]
temperature:  [C]        <-- linked without -u _printf_float
temperature:  [C]

The "-O0 is healing" looks more like a missing volatile or issues with using floating point in interrrupt handlers or similar syncronization issues.

hth

KnarfB

Oh, thanks for pointing that out. It appears the issue is within my custom "printf()"

void serprintf(const char *fmt, ...) {
	char *buffer;
	va_list va;
	va_start(va, fmt);
	uint16_t size = vasprintf(&buffer, fmt, va);
	va_end(va);
	HAL_UART_Transmit(&huart1, (uint8_t*) buffer, size, 0xFFFF);
	free(buffer);
}

I'm still digging!

S.Ma
Principal

I try not to use float as it's adding float libary to flash footprint.

You can make your own printf function with your own tags for formatting.

If float is to show something like " 29.375",

uint32_t temp_degC_x1000 = 29375;

MyPrintf("temperature is %M degree Celcius", temp_degC_x1000);

Example of custom printf :

void LCD_16x2_Printf(LCD_16x2_t* pL, const char *str,...)

found in LCD_16x2.c file here

The "buffer" is a pointer to nowhere/anywhere...

Also the Newlib's printf() functions are just terrible. You can read about their problems in thisthis and this topic. And there is a good discussion about the topic on EEVblog forum. A decent solutions are: eyalroz/printfLwPRINTFnanoprintf.

Hi @Piranha​ ,

could you please start a thread with these links, so that a direct link to it can be given in the future?

Thanks,

JW