Yeah I always lifted my eyebrows when seeing the memory used by HAL_RCC_OscConfig.
Anyways those 1.6KB are too much, clearly you're compiling with optimization disabled.
But the issue is clear:
- HAL code includes every possible scenario
- Most HAL functions use pointers to non-constant data (Thus treated as volatile)
- So the compiler only optimizes the code, but can't stripe unused code because it expects any possible scenario.
For example, your clock initialization probably only uses HSE or HSI oscillator and never changes, but all HSE, HSI, LSE, LSI "ifs" will still be there after compiling.
Actually there's no such "bloat". The library is capable of changing the clock source at any time, on every condition, that's all.
If they removed those capabilities, people would complain anyways, "I can't change to low power oscillator! CUBEMX crap blah blah"
Once you delete these sections (Modify for your current setup), HAL_RCC_OscConfig memory usage reduces to almost 1/3:
/*----------------------------- HSI Configuration --------------------------*/
/*------------------------------ LSI Configuration -------------------------*/
/*------------------------------ LSE Configuration -------------------------*/
Giving the following results:
No optimizations: 1.25KB -> 588 bytes
Optimized for size: 824 bytes -> 360 bytes
And that probably applies to every other HAL function using pointers.
So if you know you requirements, you can strip a lot of code.
Interestingly, compiling the same tests on emBitz produces no difference, not a single byte! So emBitz is actually removing those unused parts.
Searching the differences, found that emBitz has Linker Time Optimization (-flto flag) enabled by default.
It not only reduced the overall code size by half, it also somehow causes absolutely no difference in code size when removing those code sections.
When disabling LTO, yeah, those code sections made a difference and the final size was very close to CubeIDE's.
Last time I tried LTO on CubeIDE the stm32 just booted right away into HardFault.
I didn't spend more time researching, but might worth reading, specially on that starving 16KB mcu:
https://www.disk91.com/2020/technology/programming/code-optimization-with-stm32-cube-ide/Here it explains what probably was my issue:
When using LTO optimization, you need to make some change in the startup file.
It seems that’s a bug with weak function in the GCC version used by ST Cube IDE, so it may be fixed later.
The current problem is: when weak interrupt functions are declared in the Core/Startup/startup_stm32xxxxx.S file the irq handler in the Core/Src/stm32lOxx_it.c file are ignored and removed.
The consequence is the device is not booting.
In the comments:
James Wilson on 11 July 2020 at 23:06 said:
After some experimentation, I found that argument order matters with the linker.
The generated Makefile orders the assembler objects after the C sources (OBJECTS=main.o startup_xxx.o).
By putting the objects with weak symbols first (OBJECTS=startup_xxx.o main.o), the linker correctly processes the weak symbols with LTO, and modification to startup_xxx.s is unnecessary.
Paulon 12 July 2020 at 11:11 said:
I’ve seen that also but I did not found how to change this in a convenient way in a CubeMx / Eclipse generated project.
If you have a tips it is welcome to share it.
About the display lcd library:
The problem with those simple libraries is the memory usage by the font, if you only need the letters 'a' and 'z', the whole range a-z needs to be there, and you're stuck with the default fonts unless you try with different programs and formats until finally find the correct one if you get lucky, spending a lot of precious time in the way.
Won't say it again: U8g2 greatly enhances the font memory usage and comes with its own font generator!
UGUI is also a nice library, mainy for touch screens and windows-like interfaces, although it supports the basics too.
But had the same issue, every font had chars 0-255, eating a lot of space, so I modified it with a matching font generator program which allowed any char, any range.
Although mainly intended for color screens, works fine with monochrome screen too, and the library initialization is extremely easy.
You can check it
here, some examples
here