Loading...
 

Zephyr project on STM32

   Zephyr Workbench, a VSCode extension to manage Zephyr on STM32.
It enables users to easily create, develop, and debug Zephyr applications.
Main features:
  • Install host dependencies.
  • Import toolchain and SDK.
  • Create, configure, build and manage apps.
  • Debug STM32.
You can directly download it from the VSCode marketplace
For more details, visit the Zephyr Workbench

System Workbench for STM32


[SOLVED] Linker Error "section `._user_heap_stack' will not fit in region `FLASH'"

I am developing with SW4STM32 since its very first release.
Now I am working with OpenSTM32 IDE v2.4.0 and ARM Compiler for MCU v1.15.0 on a STM32F401 mcu with 256K flash and 64K ram.
For a bootloader purpose, my application has to be relocated at 0x08010000. So, I use my attached modified linker script, where I re-define the available memory areas for my application:

/* Specify the memory areas */
MEMORY
{
RAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 64K
FLASH (rx)  : ORIGIN = 0x08010000, LENGTH = 192K /* with bootloader */
}

Because I use FreeRTOS heap4 heap handler, I add my HEAP4 heap section to the default .user_heap_stack section:

/* Generate a link error if heap and stack don’t fit into RAM */
_Min_Heap_Size = 0x0; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);

*(HEAP4) /* FreeRTOS heap4 */

PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM

I know my application size is about 0x273E8 bytes: I know this, because I have a different build configuration where the application start is the default address 0x08000000.

Compiling my application with the attached linker script I get the linker error:
section `._user_heap_stack’ will not fit in region `FLASH’
region `FLASH’ overflowed by 5096 bytes

Why .user_heap_stack section is considered to belong to the FLASH area, when in the linker script is specified to belong to RAM area?

Looking to the attached linker map output file, I see the following lines:

._user_heap_stack
0x20001910 0xa000 load address 0x080373e8
0x20001910 . = ALIGN (0x8)
*(HEAP4)
HEAP4 0x20001910 0x9c00 Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.o
0x20001910 ucHeap
!provide PROVIDE (end, .)
!provide PROVIDE (_end, .)
0x2000b510 . = (. + _Min_Heap_Size)
0x2000b910 . = (. + _Min_Stack_Size)
*fill* 0x2000b510 0x400
0x2000b910 . = ALIGN (0x8)

So it looks like:

  • the FLASH location counter (load address, LMA) comes to the 0x080373e8 value;
  • the ._user_heap_stack section starts at 0x20001910 (RAM) and its size is 0xA000 bytes.
  • for the sections in RAM the linker seems to consider the same location counter for FLASH: in fact, 0x080373e8 + 0xA000 = 0x080413E8 and so the region `FLASH’ is overflowed by 5096 (0x13E8) bytes.


How should I tell to the linker to consider a different location counter for all the sections in RAM?
This is a critical issue for my application development. Could you please help me to fix it?

I solved the issue.
It looks like the linker increments the FLASH location counter (load address, LMA) with the size of every section different from the canonical ones, i.e. .text, .data and .bss, even if they are to be located in RAM region.
The solution is to declare with NOLOAD mark type every section located in RAM region:

/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack (NOLOAD) :
{
. = ALIGN(8);

*(HEAP4) /* FreeRTOS heap4 */

PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM

With the NOLOAD mark type the section will not be loaded into FLASH memory and my application linking is successful.

France

Hi,

Sorry to have missed this question. In fact the linker allocates for every section some space in FLASH to hold the initialization data for the RAM... The only sections that have no initializatio data in FLASH are:

  • Sections marked a NOLOAD (as you did)
  • Sections that load in the .bss region (which is NOLOAD by default)


What I don’t understand is why your heap is not placed in .bss by the default allocation done by FREErtos’ heap_4.c file, but is in an HEAP4 file, where it is not placed in .bss but some other section... Do you use configAPPLICATION_ALLOCATED_HEAP and allocate it explicitly?

Best regards,

Bernard (Ac6)


 

Newest Forum Posts

  1. reservation car service Seattle by Jamesprede, 2025-05-01 10:06
  2. Last day: drone bonus by Danielrug, 2025-04-19 16:55
  3. SPI on Nucleo_STMH533RE by higginsa1, 2025-03-25 07:37
  4. SPI on Nucleo_STMH533RE by royjamil, 2025-03-23 11:31
  5. SPI on Nucleo_STMH533RE by higginsa1, 2025-03-23 09:33
  6. Configuring DMA for ADC in SW? by sam.hodgson, 2025-03-04 12:58
  7. Insightful Perspectives on This Subject by davidsycle, 2025-03-04 05:45
  8. Build a project in "release" mode by info@creosrl.it, 2025-02-20 18:12
  9. Build a project in "release" mode by info@creosrl.it, 2025-02-20 17:05
  10. Build a project in "release" mode by tang, 2025-02-20 10:36

Last-Modified Blogs