cancel
Showing results for 
Search instead for 
Did you mean: 

Generated Binary file size is too large(~2.3GB)

Nikunj Patel
Associate III

Hello Community,

  1. I am working with "STM32F746G-DISCO" Board, "STM32CubeMX", "STM32CubeIDE", and "TouchGFX Designer" .
  2. I would like to program GRAPHICS Data in to "QUADSPI Flash".
  3. When i compile firmware in "DEBUG" mode,
    1. ".bin" file size = 2.3GB
    2. ".elf " file size = 5.5MB,
    3. But, It works fine for me. GRAPHICS Data are program in QUAD SPI Flash.
  4. When i compile firmware in "Release" mode.
    1. ".bin" file size = 2.3GB
    2. ".hex" file size = 3.3MB.
  5. I made below modification in "Linker Script" file to store data in "QUAD SPI FLASH"
    1. QUADSPI (rx)  : ORIGIN = 0x90000000, LENGTH = 16M

 ExtFlashSection :

 {

*(ExtFlashSection ExtFlashSection.*)

*(.gnu.linkonce.r.*)

  . = ALIGN(0x4);

 } >QUADSPI

6. Here, I also attached liker script file.

7. Is there any configuration missed by me or make some wrong implementation.

8. I required ".bin" file in "STLINK" utility while program the external flash because In STLink select the "External Loader" >>"N25Q128A_STM32F746G_DISCO">>"Program".

9. It opens the "Download" window.

10. It display "start address" as "0x08000000" and that "text box" is disabled when i choose the ".hex" file

11. When i choose the ".bin" binary file that "textbox" is enable. But Binary file size is too large(~2.3GB).

Can you please suggest me how can i reduce the binary file size.

My aim is to program the GRAPHICS Data in to External Flash(QUAD SPI FLASH)

Regards,

Nikunj Patel

1 ACCEPTED SOLUTION

Accepted Solutions

Hello @Community member​ 

Thanks for great support.

As you suggested i have used the following command to split binaries in multiple section,

Here is below command.

arm-none-eabi-objcopy.exe -O binary --only-section=ExtFlashSection "${BuildArtifactFileBaseName}.elf" ExtFlash.bin;arm-none-eabi-objcopy.exe -O binary --remove-section=ExtFlashSection "${BuildArtifactFileBaseName}.elf" STM32F746.bin

Use Above command in

Project >> Properties >> c/c++ build >> Setting >> Build Steps >> Post-Build Steps >> Command.

Regards,

Nikunj Patel

View solution in original post

16 REPLIES 16

Split it into multiple sections?

Use a .HEX, these can represent sparse files better. The .BIN is trying to be a linear representation of memory, and the two regions have a lot of distance between them.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
John Adriaan
Associate III

Normally, an ELF file is a lot smaller than a bin file, since the ELF avoids huge amounts of zeroes that are usually in the bin. The fact that in your DEBUG case it's the opposite means that you have a huge ELF, with a lot of debug information (not uploaded to the target) added. Which implies to me that the ELF has a LOT of zeroes in it (although I don't know that).

Normally, variables with starting values (like addresses, or counters, or other values) are assigned to the `.data` linker section, stored in the code (thus the ELF), and copied to RAM at system startup. These are notably all non-zero, so the only possible way they can be initialised is by copying them from Flash.

All other variables don't need to be stored in Flash, since their value is usually set at runtime by putting them in the `.bss` section. These are variables that start at zero, so the linker doesn't allocate them in Flash (thus they take no space in Flash), but in RAM--and at startup they are zeroed by the "Zero the BSS RAM section now" function in the C runtime library.

If you write the following code, the results for `begin` and `end` MUST be stored in the `.data` (and therefore Flash) section, since it otherwise has no way of knowing the values. But note that `buffer` does NOT have any initialisation data, so it just needs to be zeroed, so can be stored in the `.bss` section. (C and C++ both guarantee that a variable starts with the value zero unless it's initialised to something different).

char buffer[0x2000];
 
char *begin = buffer;
char *end = buffer + sizeof(buffer);

Thus the `.data` section has two pointers (2x four bytes, which need to be in Flash), while the RAM section has 8192+4+4=8200 bytes: 4 bytes each for `start` and `end` (originally copied from Flash), plus 8192 bytes for the actual buffer (which is zeroed, so not stored in Flash).

Even if you write the following code, `buffer` will not take any extra Flash: the compiler realises that all the values are zero, so still puts them in the `.bss` section:

char buffer[0x2000] = { 0, 0, 0, 0, 0, 0, 0 };

However, if somehow your code is the following, you've got a problem:

char buffer[0x2000] = { 0x08, 0x18, 0x7C, 0xFF, 0x7C, 0x18, 0x08 };

This is an initialised array, so needs to be stored in Flash before it can be copied to RAM. (Note that there are better ways of doing this: for example, if the bitmap is fixed, it should be declared as `const`, so (usually) won't be copied from Flash to RAM at all.)

If your code has bitmaps or other graphic elements stored in Flash, then no amount of improving the code will fix the sheer amount of space in Flash that they're taking. One mechanism to improve this is not to store the raw graphics in Flash, but to store compressed versions of the data in Flash, and during boot to decompress them into RAM (this assumes there's more RAM than Flash - not always the case). Please look at your linker compression options to decide if this will help.

Personally, I think that your environment has declared huge amounts of zeroed buffers, but somehow told the linker that they need to be copied from Flash rather than initialised at startup.

>>Personally, I think that your environment has declared huge amounts of zeroed buffers, but somehow told the linker that they need to be copied from Flash rather than initialised at startup.

No, he has TWO ROM regions, one at 0x08000000 (code) and another at 0x90000000 (graphic data)

0x90000000-0x08000000 = 2,281,701,376

There is a large void which has no representation

Keil's FromELF tool would split the output into multiple binaries describing the individual regions, not try to output a single monolithic binary.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
John Adriaan
Associate III

I completely missed that! Thank you! That explains why the executable is so large.

@Community member​ You need to understand that the resulting binary will include everything that you've defined. Therefore it will include everything: more than the code that you're trying to burn into Flash. You need to separate what goes into (code) Flash versus what goes into (data) Flash, and organise to burn the data Flash separately. Or use @Community member​'s solution.

Hi @Community member​ ,

I understand your description, but how can we reduce the binary size to KB.

when we try program the 2.3GB of binary file in to external flash using STlink, It gives error like "memory could not allocated".

Can you please, suggest the workaround that we reduce the binary file size.

Regards,

Nikunj Patel

So use tools that split the .ELF into multiple binaries, or generate a packaged binary like a .DFU file designed to hold objects/sections describing different memory regions.

As previously stated, FromELF will generate multiple binaries, and I suspect objcopy or srecord tools could be driven in a similar way, but you'll need to own the task of reading the manuals/instructions for those tools.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi @Community member​ ,

Thanks for fast reply.

Should i install the keil and compile in it?

Do u have some "ELF" Tool guide?

Should i used "DFU" File Manager for generating "a.dfu" file.

I have "DFU" File Manager.

Regards,

Nikunj Patel

The path you choose is up to you.

The simplest would be to have the tools generate a .HEX as that has the broadest application.

As I recall the DFU Manager can take .ELF or .HEX input forms.

I have familiarity with manipulating object files, I've written my own firmware packaging tools. Seem to recall posting a HEX2DFU command line tool to the forum.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi @Community member​ ,

As per your suggestion, i converted my .hex to .dfu file having size of "1.10 MB".

But For External Loader Option in STLink does not support ".dfu" file as input.

Do we requires some another option.

Regards,

Nikunj Patel