Shrinking mbed binaries

Topics: 

I'm currently working on a 1wire library for mbed, so that 1wire devices can be implemented on mbed compatible microcontrollers (really, just STM32 for now).

One of the things that would be really useful is to be able to update the firmware of these devices over the 1wire bus, so that they don't need to be decomissioned for updates.

In order to do this, I need to write a 1wire bootloader, but at the moment, the binaries are quite large. Poking around in the generated map file (pass -Wl,-Map=output.map to the linker, I'm using Amap to analyse it), it becomes clear that although I have tracing turned off, something is still pulling in the printf library, which is quit large.

It turns out there are 2 things that include printf - mbed asserts, which can be disabled by recompiling the mbed library with the release profile, and the serial library, which pulls it in from the error handling (which is a bit unfortunate). To disable that, you need need to disable the serial library, which you can do by passing -D DEVICE_SERIAL=0 to the build script.

All up, getting rid of printf saved me ~14kB.

I also have some patches which allow the library to be compiled with link-time optimisation, which brings down the size a bit further.

(later) HAL_RCC_OscConfig clocked in at a whopping 888 bytes! The mbed library tries to configure an external oscillator, then a crystal if that fails. Since my project only uses the internal RC oscillator, I can disable the other types which allows the optimiser to remove the unused components of HAL_RCC_OscConfig. To do this, edit system_stm32f0xx.c and update the PLL defines to:

/* Select the clock sources (other than HSI) to start with (0=OFF, 1=ON) */
#ifndef USE_PLL_HSE_EXTC
#define USE_PLL_HSE_EXTC (1) /* Use external clock */
#endif
#ifndef USE_PLL_HSE_XTAL
#define USE_PLL_HSE_XTAL (1) /* Use external xtal */
#endif

 You can then disable these via an external define. This saved me another 1036 bytes.

Next up, there were symbols for flush in the map file, which were not needed. These were disabled by  setting DEVICE_STDIO_MESSAGES=0, saving another 1132 bytes.

My mbed build command looks like this:

python build.py -c -v -m NUCLEO_F030R8 -t GCC_ARM -j 4 --profile release -D DEVICE_SERIAL=0 -D USE_PLL_HSE_EXTC=0 -D USE_PLL_HSE_XTAL=0 -D DEVICE_STDIO_MESSAGES=0