cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeMX incorrectly generates different .ld files depending on selected Toolchain / IDE

thernstig
Associate II

STM32CubeMX generates a different .ld file depending on the selection under Project Manager -> Toolchain/IDE, when it should not.

Here are two examples, the first for CMake, and the second for STM32CubeIDE. I added them both to a .zip file.

STM32C071RBTX_FLASH.ld was generated when selecting STM32CubeIDE.

STM32C071RBTx_FLASH.ld was generated when selecting CMake.

Problem

The files should not have been regenerated. IT should have been the same name, with the same content. That two different files are generated shows for a bad implementation in STM32CubeMX for how it generates the .ld file.

6 REPLIES 6
thernstig
Associate II

Adding a git diff for reference, see below. I also noticed that the STM32C071RBTx_FLASH.ld file generated by CMake does not work, see e.g. https://community.st.com/t5/stm32cubemx-mcus/f303-generated-ld-missing-ram-symbol-won-t-compile-includes-fix/m-p/722915.

@STTwo-32  How can this not have been fixed yet? It was 3 months ago it was reported, and it completely breaks building for CMake.

 

 

> git diff --no-index STM32C071RBTX_FLASH.ld STM32C071RBTx_FLASH.ld
warning: in the working copy of 'STM32C071RBTx_FLASH.ld', CRLF will be replaced by LF the next time Git touches it
diff --git a/STM32C071RBTX_FLASH.ld b/STM32C071RBTx_FLASH.ld
index ecbb0cd..0fbbf95 100644
--- a/STM32C071RBTX_FLASH.ld
+++ b/STM32C071RBTx_FLASH.ld
@@ -1,57 +1,74 @@
 /*
 ******************************************************************************
 **
-** @file        : LinkerScript.ld
+
+**  File        : LinkerScript.ld
 **
-** @author      : Auto-generated by STM32CubeIDE
+**  Author             : STM32CubeMX
 **
-** @brief       : Linker script for STM32C071RBTx Device from STM32C0 series
-**                      128KBytes FLASH
-**                      24KBytes RAM
+**  Abstract    : Linker script for STM32C071RBTx series
+**                128Kbytes FLASH and 24Kbytes RAM
 **
 **                Set heap size, stack size and stack location according
 **                to application requirements.
 **
-**                Set memory bank area and size if external memory is used
+**                Set memory bank area and size if external memory is used.
 **
 **  Target      : STMicroelectronics STM32
 **
-**  Distribution: The file is distributed as is, without any warranty
+**  Distribution: The file is distributed “as is,” without any warranty
 **                of any kind.
 **
-******************************************************************************
+*****************************************************************************
 ** @attention
 **
-** Copyright (c) 2024 STMicroelectronics.
-** All rights reserved.
+** <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
 **
-** 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.
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+**   1. Redistributions of source code must retain the above copyright notice,
+**      this list of conditions and the following disclaimer.
+**   2. Redistributions in binary form must reproduce the above copyright notice,
+**      this list of conditions and the following disclaimer in the documentation
+**      and/or other materials provided with the distribution.
+**   3. Neither the name of STMicroelectronics nor the names of its contributors
+**      may be used to endorse or promote products derived from this software
+**      without specific prior written permission.
 **
-******************************************************************************
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*****************************************************************************
 */

 /* 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 */
+_estack = ORIGIN() + LENGTH();    /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200;      /* required amount of heap  */
 _Min_Stack_Size = 0x400; /* required amount of stack */

-/* Memories definition */
+/* Specify the memory areas */
 MEMORY
 {
-  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 24K
-  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 128K
+RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 24K
+FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 128K
 }

-/* Sections */
+/* Define output sections */
 SECTIONS
 {
-  /* The startup code into "FLASH" Rom type memory */
+  /* The startup code goes first into FLASH */
   .isr_vector :
   {
     . = ALIGN(4);
@@ -59,7 +76,7 @@ SECTIONS
     . = ALIGN(4);
   } >FLASH

-  /* The program code and other data into "FLASH" Rom type memory */
+  /* The program code and other data goes into FLASH */
   .text :
   {
     . = ALIGN(4);
@@ -76,7 +93,7 @@ SECTIONS
     _etext = .;        /* define a global symbols at end of code */
   } >FLASH

-  /* Constant data into "FLASH" Rom type memory */
+  /* Constant data goes into FLASH */
   .rodata :
   {
     . = ALIGN(4);
@@ -85,74 +102,55 @@ SECTIONS
     . = ALIGN(4);
   } >FLASH

-  .ARM.extab (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
-  {
-    . = ALIGN(4);
-    *(.ARM.extab* .gnu.linkonce.armextab.*)
-    . = ALIGN(4);
-  } >FLASH
-
-  .ARM (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
-  {
-    . = ALIGN(4);
+  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+  .ARM : {
     __exidx_start = .;
     *(.ARM.exidx*)
     __exidx_end = .;
-    . = ALIGN(4);
   } >FLASH

-  .preinit_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+  .preinit_array     :
   {
-    . = ALIGN(4);
     PROVIDE_HIDDEN (__preinit_array_start = .);
     KEEP (*(.preinit_array*))
     PROVIDE_HIDDEN (__preinit_array_end = .);
-    . = ALIGN(4);
   } >FLASH
-
-  .init_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+  .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 (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+  .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 */
+  /* used by the startup to initialize data */
   _sidata = LOADADDR(.data);

-  /* Initialized data sections into "RAM" Ram type memory */
-  .data :
+  /* Initialized data sections goes into RAM, load LMA copy after code */
+  .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 */
+  } > AT> FLASH

-  } >RAM AT> FLASH
-
-  /* Uninitialized data section into "RAM" Ram type memory */
+
+  /* Uninitialized data section */
   . = ALIGN(4);
   .bss :
   {
-    /* This is used by the startup in order to initialize the .bss section */
+    /* This is used by the startup in order to initialize the .bss secion */
     _sbss = .;         /* define a global symbol at bss start */
     __bss_start__ = _sbss;
     *(.bss)
@@ -162,9 +160,9 @@ SECTIONS
     . = 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 section, used to check that there is enough RAM left */
   ._user_heap_stack :
   {
     . = ALIGN(8);
@@ -173,9 +171,11 @@ SECTIONS
     . = . + _Min_Heap_Size;
     . = . + _Min_Stack_Size;
     . = ALIGN(8);
-  } >RAM
+  } >

-  /* Remove information from the compiler libraries */
+
+
+  /* Remove information from the standard libraries */
   /DISCARD/ :
   {
     libc.a ( * )
@@ -183,5 +183,6 @@ SECTIONS
     libgcc.a ( * )
   }

-  .ARM.attributes 0 : { *(.ARM.attributes) }
 }
+
+

 

This is a known issue. For new Cmake build system they use a different way to generate .ld files. This is intentional unless new files are too broken or buggy. like missing  RAM  in "> RAM" and 

ORIGIN() + LENGTH()

 

 

 

 

 

@Pavel A. I cannot see how that is true. If you diff the files properly you can see the are identical for the most part, but the one for CMake does not build due to bugs. Even simpler parts like the @brief description, and many other parts contain white space differences etc. The copyright dates are very different (the CMake one even says a date far before CMake support was added etc). I thus think your statement is incorrect. This is not intentional.

Do you have references showing this is intentional, and why some differences are there?

The reason I think it is not intential is because because the .ld file generated for STM32CubeIDE works great to use when building with CMake,

I don't have references, just seen someone from ST commented earlier on CMake and VS Code support.  IIRC the difference is that the "legacy" way is just to copy a pre-made .ld file from library of templates. The new way is to generate the ld script from a database of STM32 models (where it gets sizes of flash and RAM blocks). This process still is a bit buggy. That's how I understood from that explanation.  The bug in Cmake .ld files has been reported here several times, should be in work.

Now to the point whether the [good] .ld file should not be clobbered when user switches to/from CMAKE build system... A good question. Generally, every time the Cube re-generates the project, it can cause damage and user should make backups and review changes in generated stuff.

Then I think we all wish for ST to solve this soon, if it is known since far back. It is very strange to me the way this has been implemented, and a very large oversight to not even have it build. I am unsure how it got past code review/QA internally at ST.

CMake is paramount to enable developers to work in their own IDE of choice, which in 2024 is far from a big ask. It is the norm to let users use their own toolchain, be that a Jetbrains IDE, VS Code, VS, Eclipse (as-is), STM32CubeMX etc.

Note that even STM32CubeIDE supports CMake. So using CMake as the output Toolchain/IDE is always best.

Hello @thernstig 

This issue has been fixed in the latest CubeMX 6.13.0 , please download it from this LINK  

THX

Ghofrane