Skip to main content
Lucky Dog
Associate II
September 27, 2022
Solved

I want to use stm32CubeIDE's GCC compiler to compile my project, but the program takes up too much Flash space

  • September 27, 2022
  • 3 replies
  • 5607 views

The optimization options for GCC compilation are: Optimize for size(-Os),The compiled result is as follows:

0693W00000SwIogQAF.png The size of MCU Flash resources occupied is: text+data = 47264 Byte

The.ld link script is shown below:

0693W00000SwIpoQAF.png Question: In my program, the.data segment data (initialized variable) can not be 15K, in theory only 0x44 bytes size, this can be seen from the map file, as shown below:

0693W00000SwIq3QAF.png I compiled the same project program using Keil and everything worked fine. What is the problem with me, or the GCC compiler?

Thanks.

Below is the complete linked script file.

/*
******************************************************************************
**
** @file : LinkerScript.ld
**
** @author : Auto-generated by STM32CubeIDE
**
** @brief : Linker script for STM32L451CEUx Device from STM32L4 series
** 512Kbytes FLASH
** 160Kbytes RAM
** 32Kbytes RAM2
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
**
******************************************************************************
** @attention
**
** Copyright (c) 2022 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
******************************************************************************
*/
 
/* Entry Point */
ENTRY(Reset_Handler)
 
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
 
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
 
 
_RAM2_START_ADDR = 0x10000000; 
_RAM2_Size = 32K - 4; 
_RAM2_BOOT_START_ADDR = 0x10000000 + _RAM2_Size;
/* Memories definition */
MEMORY
{
 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
 RAM2 (xrw) : ORIGIN = _RAM2_START_ADDR, LENGTH = _RAM2_Size
 RAM2_BOOT (xrw) : ORIGIN = _RAM2_BOOT_START_ADDR, LENGTH = 4 
 FLASH (rx) : ORIGIN = 0x8008000, LENGTH = 80K
}
 
/* Sections */
SECTIONS
{
 /* The startup code into "FLASH" Rom type memory */
 .isr_vector :
 {
 . = ALIGN(4);
 KEEP(*(.isr_vector)) /* Startup code */
 . = ALIGN(4);
 } >FLASH
 
 /* The program code and other data into "FLASH" Rom type memory */
 .text :
 {
 . = ALIGN(4);
 *(.text) /* .text sections (code) */
 *(.text*) /* .text* sections (code) */
 *(.glue_7) /* glue arm to thumb code */
 *(.glue_7t) /* glue thumb to arm code */
 *(.eh_frame)
 
 KEEP (*(.init))
 KEEP (*(.fini))
 
 . = ALIGN(4);
 _etext = .; /* define a global symbols at end of code */
 } >FLASH
 
 /* Constant data into "FLASH" Rom type memory */
 .rodata :
 {
 . = ALIGN(4);
 *(.rodata) /* .rodata sections (constants, strings, etc.) */
 *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
 . = ALIGN(4);
 } >FLASH
 
 .ARM.extab : {
 . = ALIGN(4);
 *(.ARM.extab* .gnu.linkonce.armextab.*)
 . = ALIGN(4);
 } >FLASH
 
 .ARM : {
 . = ALIGN(4);
 __exidx_start = .;
 *(.ARM.exidx*)
 __exidx_end = .;
 . = ALIGN(4);
 } >FLASH
 
 .preinit_array :
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__preinit_array_start = .);
 KEEP (*(.preinit_array*))
 PROVIDE_HIDDEN (__preinit_array_end = .);
 . = ALIGN(4);
 } >FLASH
 
 .init_array :
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__init_array_start = .);
 KEEP (*(SORT(.init_array.*)))
 KEEP (*(.init_array*))
 PROVIDE_HIDDEN (__init_array_end = .);
 . = ALIGN(4);
 } >FLASH
 
 .fini_array :
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__fini_array_start = .);
 KEEP (*(SORT(.fini_array.*)))
 KEEP (*(.fini_array*))
 PROVIDE_HIDDEN (__fini_array_end = .);
 . = ALIGN(4);
 } >FLASH
 
 /* Used by the startup to initialize data */
 _sidata = LOADADDR(.data);
 
 /* Initialized data sections into "RAM" Ram type memory */
 .data :
 {
 . = ALIGN(4);
 _sdata = .; /* create a global symbol at data start */
 *(.data) /* .data sections */
 *(.data*) /* .data* sections */
 *(.RamFunc) /* .RamFunc sections */
 *(.RamFunc*) /* .RamFunc* sections */
 
 . = ALIGN(4);
 _edata = .; /* define a global symbol at data end */
 
 } >RAM AT> FLASH
 
 /* Uninitialized data section into "RAM" Ram type memory */
 . = ALIGN(4);
 .bss :
 {
 /* This is used by the startup in order to initialize the .bss section */
 _sbss = .; /* define a global symbol at bss start */
 __bss_start__ = _sbss;
 *(.bss)
 *(.bss*)
 *(COMMON)
 
 . = ALIGN(4);
 _ebss = .; /* define a global symbol at bss end */
 __bss_end__ = _ebss;
 } >RAM
 
 /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
 ._user_heap_stack :
 {
 . = ALIGN(8);
 PROVIDE ( end = . );
 PROVIDE ( _end = . );
 . = . + _Min_Heap_Size;
 . = . + _Min_Stack_Size;
 . = ALIGN(8);
 } >RAM
 
 .ram2_data :
 {
 . = ALIGN(4);
 _sram2 = .;
 *(.ram2_data)
 *(.ram2_data*)
 . = ALIGN(4);
 _eram2 = .; 
 } >RAM2 AT> FLASH
 
 .ram2_boot :
 {
 . = ALIGN(4);
 _sram2_boot = .;
 *(.ram2_boot)
 *(.ram2_boot*)
 . = ALIGN(4);
 _eram2_boot = .; 
 } >RAM2_BOOT AT> FLASH
 
 /* Remove information from the compiler libraries */
 /DISCARD/ :
 {
 libc.a ( * )
 libm.a ( * )
 libgcc.a ( * )
 }
 
 .ARM.attributes 0 : { *(.ARM.attributes) }
}

This topic has been closed for replies.
Best answer by Lucky Dog

I have just modified the link script, the NOLOAD keyword was added,as follows:

.ram2_data (NOLOAD):
 {
 . = ALIGN(4);
 _sram2 = .;
 *(.ram2_data)
 *(.ram2_data*)
 . = ALIGN(4);
 _eram2 = .; 
 } >RAM2 AT> FLASH
 
 .ram2_boot (NOLOAD):
 {
 . = ALIGN(4);
 _sram2_boot = .;
 *(.ram2_boot)
 *(.ram2_boot*)
 . = ALIGN(4);
 _eram2_boot = .; 
 } >RAM2_BOOT AT> FLASH

The compiled result is as follows:

0693W00000SwKeEQAV.png​ The compiled results are now almost identical to KEIL.

​ Thank you for your reply.

3 replies

TDK
Super User
September 27, 2022

What is the actual error message?

Even if your text+data is 48k, that's still plenty less than the 128k of RAM, or 80k of FLASH.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Lucky Dog
Lucky DogAuthor
Associate II
September 27, 2022

It is true that the current program size will not exceed the MCU Flash limit, but I want to reduce the Bin file size as much as possible and reduce the time required for firmware upgrade.

Thank you for your reply

waclawek.jan
Super User
September 27, 2022

} >RAM2 AT> FLASH

} >RAM2_BOOT AT> FLASH

JW

Lucky Dog
Lucky DogAuthor
Associate II
September 27, 2022

Sorry,I don't quite understand what you mean.

I forgot to mention that I defined a bunch of global variables into RAM2, about 15k in size, but I didn't initialize them, and they shouldn't be in the .data segment, they should be in the .bss segment. as shown below:

0693W00000SwK6bQAF.png

waclawek.jan
Super User
September 27, 2022

>RAM2 AT> FLASH means, they are both in RAM2 and in FLASH.

The attribute mechanism of gcc places those data unconditionally into a given section. The implicit magic of splitting to .data and .bss based on explicit initialization applies only to those variables which are not explicitnly assigned to a given section.

.ram2_datas says, size 15.2kB, does that ring a bell?

JW

Lucky Dog
Lucky DogAuthorAnswer
Associate II
September 27, 2022

I have just modified the link script, the NOLOAD keyword was added,as follows:

.ram2_data (NOLOAD):
 {
 . = ALIGN(4);
 _sram2 = .;
 *(.ram2_data)
 *(.ram2_data*)
 . = ALIGN(4);
 _eram2 = .; 
 } >RAM2 AT> FLASH
 
 .ram2_boot (NOLOAD):
 {
 . = ALIGN(4);
 _sram2_boot = .;
 *(.ram2_boot)
 *(.ram2_boot*)
 . = ALIGN(4);
 _eram2_boot = .; 
 } >RAM2_BOOT AT> FLASH

The compiled result is as follows:

0693W00000SwKeEQAV.png​ The compiled results are now almost identical to KEIL.

​ Thank you for your reply.