Firmware size increased more than twice after adding _printf_float flag

Hi everyone! I think that there is something that i don’t understand but why my firmware size is increased more than twice after adding this build flag to my platform.ini file:

-Wl,--undefined,_printf_float

My platform.ini file is presented below:

[env]
upload_protocol = stlink
lib_extra_dirs = 
	lib/CanFestival
	lib/Ring-Buffer-master
platform_packages = 
	framework-stm32cube @ https://github.com/rocknitive/framework-stm32cube.git
build_flags = 
	 -Wl,--undefined,_printf_float

[env:test_module]
platform = ststm32
board = bluepill_f103c8
framework = stm32cube
monitor_speed = 115200

I use this flag for correct work of the function snprintf with floats for my stm32 board.
If i don’t use _printf_float flag the firmware size is 5392 bytes, but after addition - 13996 bytes (which is sufficient).
Thanks in advance!

Floating point operations and code are known to be costly in runtime and heavy-weight in flash. Same goes for printing formatted floating point stuff. Otherwise they can’t implement all the what’s specified for floating point maths, like NaNs, infinities, etc. Adding printf() alone as opposed to leaving it out is a huge flash impact. So this is expected.

Especially since your Bluepill with its STM32F103C8 is a Cortex-M3 chip with no Floating-Point-Unit (FPU) hardware to help do stuff. Software implementations must compute everything, like add, subtract, multiply, divide,… (see related blogpost)

To see exactly which exact functions and code is added, you can have GCC generate a .map file (Generate a .map file - #8 by Krishna_Chaitanya) and look at the differences between a non-floating point printf and floating point printf versions with tools like Amap | Sergey Sikorskiy.

Of course, smaller versions than those included by standard with the GCC standard libraries exist.

4 Likes

Thank you for your fast and comprehensive answer! (and also for these links).

Or someone can emulate float printing with a similar oneliner:

//print angle using fixed point
float max_error_deg = ANGLERAW_T0_DEGREES(max_error);
(void) printf("Max deviation was %01u.%02u deg\n", (uint16_t)max_error_deg, (uint16_t)((uint32_t)(max_error_deg*100.0)%100U));