Skip to main content
NPham.2
Associate
December 11, 2021
Question

Problem with optimal code size

  • December 11, 2021
  • 7 replies
  • 7030 views

Hello,

I use STM32IDE to programmer for STM32F030K6, when i call the function in the main function or interrupt function, it consumes a lot of Flash.0693W00000HoFjnQAF.png0693W00000HoFjxQAF.pngI have already changed the optimization option. But it doesn't work.

0693W00000HoFkCQAV.pngI try again with Keil C and this error does not occur, the code size is well optimized.

0693W00000HoFkMQAV.pngCan you guys tell me what I did wrong? Thanks you all!

This topic has been closed for replies.

7 replies

waclawek.jan
Super User
December 11, 2021

I don't see any striking difference in FLASH consumption (17kB vs 13kB), nor in RAM consumption (3kB vs 2.5kB). Keil is simply better in optimization, that's all.

JW

NPham.2
NPham.2Author
Associate
December 11, 2021

Thank for your answer. Sorry for misleading you. With STM32Cube I have many function calls disabled so it only consume 17KB flash, if I enable them all it consumes 31KB of flash. Here is the result when i build full project with STM32IDE

0693W00000HoGEWQA3.pngAnd here is the result when i build full project with Keil C:

0693W00000HoGElQAN.png

S.Ma
Principal
December 11, 2021

You have SSD1306, probably a bitmap screen, with bitmap font, strings, menu, etc.. lots of flash data.

If you want to see the details generate the MAP file from the linker. You will see how much code, rom data, ram data you consume PER function

Some compilers/linker will try to smartly factorize share some of the ROM data if used by pointers.

Ideally, use something simple like RLE compression for your strings or bitmap as I suspect it's the #1 memory hungry contributor.

NPham.2
NPham.2Author
Associate
December 12, 2021

The problem is not from SSD1306, i realized that when i call the function it consumes flash a lot.

TDK
Super User
December 11, 2021

There are other options besides -O3 to optimize code size. Change the build configuration to Release and try.

I'm unfamiliar with Keil, but wouldn't all of "code", "ro-data", and "rw-data" sections be put into FLASH? Wouldn't that make the total ~20kB?

Here's a random project compiled with different options. Release is less than Debug with -O3:

Debug:
 text	 data	 bss	 dec	 hex	filename
 11440	 10260	 1844	 23544	 5bf8	***.elf
 
Debug with -O3:
 text	 data	 bss	 dec	 hex	filename
 7184	 10260	 1844	 19288	 4b58	***.elf
 
Release:
 text	 data	 bss	 dec	 hex	filename
 6664	 10260	 1844	 18768	 4950	***.elf

 Examining usage per-function or per-variable would likely yield more informative results.

"If you feel a post has answered your question, please click ""Accept as Solution""."
NPham.2
NPham.2Author
Associate
December 12, 2021

Hello, do you mean i choose this option? The results do not change.

0693W00000HoI5lQAF.png

TDK
Super User
January 10, 2022

Your screenshot shows the memory usage is still from the Debug build. You need to rebuild the project for it to update.

0693W00000Hr2GFQAZ.png

"If you feel a post has answered your question, please click ""Accept as Solution""."
Piranha
Principal III
January 9, 2022

Only the Os optimizes code for size. All other options optimize for speed. O2 is a good compromise and O3 and Ofast are the fastest and biggest ones.

Probably the real problem is using printf() functions from the Newlib library. Those take several KB and adding float support adds another 10+ KB. Also those pull in malloc() and add 2 KB of initialized data to the FLASH memory.

NPham.2
NPham.2Author
Associate
January 10, 2022

Thanks a lot for your answer, but how can i fix it? I do not know what to do.

Piranha
Principal III
January 10, 2022

If you are serious, the best solution is to eliminate those functions and use, for example, nanoprintf. It's small, configurable, reentrant and it uses single (32-bit) float for floating point arithmetic. LwPRINTF is another decent alternative. It's also configurable and reentrant, but, compared to nanoprintf, is slightly bigger, better tailored for RTOS (integrated mutex support) and uses double (64-bit) float for floating point arithmetic.

And about those 2 KB of initialization data... Basically you specify a -nostartfiles option for the linker and comment out a __libc_init_array call from your startup file. But, before doing that, read this discussion.

S.Ma
Principal
January 10, 2022

To investigate in less than 1 hour, compare keil map file with gcc map file. You will find out the biggest object file size difference.and zoom in. When you call a function from main, the linker will recursively find thr function tree and add them to memory. If you use function pointerd, linkers are less guessing hence optimizing. Keil and IAR are morr efficient than gcc. Dig and compare map file. Also check the project compile option or global tags in the project config, maybe assert options, etc...

S.Ma
Principal
January 10, 2022

Check also if using float or double that if the fpu is present, it uses it instead of a sw lib that emulates it.