Does Memory Sections in Flash.ld file require a particular sequence? And other Linker stuff
1. I have modified the STMxxx_Flash.ld linker file by adding some memory sections. Does the sequence of SECTIONS definition matters? LinkerScript.ld and MPU Config Added.
Layout:
ITCM -> Has some functions
DTCM-> non DMA Global Variables
D1 RAM (First 256KB)-> DMA Buffers with Cacheable and Bufferable Disabled in MPU Region
D1 RAM(Last 64KB)-> Data benefitted from caching with Cacheable and Bufferable Enabled in MPU Region

2. Vector Table and ITCM have the same start address (0x0000 0000). I have to do anything or its handled already?
3. Did i modified the heap-stack section correctly for it to work from DTCM.
LinkerScript.ld
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x4000; /* required amount of heap */
_Min_Stack_Size = 0x8000; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 256K /* First 128KB of D1, uncached */
RAM_D1_CACHED (xrw) : ORIGIN = 0x24040000, LENGTH = 64K /* Remaining D1 RAM, cached */
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
BKPSRAM (xrw) : ORIGIN = 0x38800000, LENGTH = 4K /* Backup SRAM */
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* itcm section start--------------------------------------------------------------------------*/
.itcmram :
{
. = ALIGN(4);
_sitcmram = .;
KEEP(*(.itcmram))
_eitcmram = .;
} >ITCMRAM AT> FLASH
_sitcmram_init = LOADADDR(.itcmram);
/* itcm section end--------------------------------------------------------------------------*/
/* DTCM RAM section start--------------------------------------------------------------------------*/
.dtcmram :
{
. = ALIGN(4);
_sdtcmram = .;
KEEP(*(.dtcmram))
_edtcmram = .;
} >DTCMRAM AT> FLASH
_sdtcmram_init = LOADADDR(.dtcmram);
/* DTCM RAM section end--------------------------------------------------------------------------*/
/* User_heap_stack section, used to check that there is enough RAM left------------------------- */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >DTCMRAM
/* RAM_D1_CACHED RAM section start--------------------------------------------------------------------------*/
/* Cached data section in D1 RAM (last 64KB) */
.ram_d1_cached :
{
. = ALIGN(8);
_sram_d1_cached_start = .;
*(.ram_d1_cached) /* Place your cached data here */
. = ALIGN(8);
_sram_d1_cached_end = .;
} >RAM_D1_CACHED AT> FLASH
_sram_d1_cached_init = LOADADDR(.ram_d1_cached);
/* RAM_D1_CACHED RAM section end--------------------------------------------------------------------------*/
/* BKPSRAM RAM section start--------------------------------------------------------------------------*/
.bkp_data (NOLOAD) :
{
. = ALIGN(4);
*(.bkp_data)
. = ALIGN(4);
} >BKPSRAM
/* BKPSRAM RAM section end--------------------------------------------------------------------------*/
/* The program code and other data goes into FLASH */
.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 goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >FLASH
.ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.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 */
} >DTCMRAM AT> FLASH
/* Uninitialized data section */
. = 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;
} >DTCMRAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
Edit: Added startup file
.syntax unified
.cpu cortex-m7
.fpu fpv5-d16 // Enable hardware FPU
.thumb
.global g_pfnVectors
.global Default_Handler
/* Start address for the initialization values of the .data section. Defined in the linker script */
.word _sidata
/* Start address for the .data section. Defined in the linker script */
.word _sdata
/* End address for the .data section. Defined in the linker script */
.word _edata
/* Start address for the .bss section. Defined in the linker script */
.word _sbss
/* End address for the .bss section. Defined in the linker script */
.word _ebss
/* Start address for the .itcmram section. Defined in the linker script */
.word _sitcmram
/* End address for the .itcmram section. Defined in the linker script */
.word _eitcmram
/* Start address for the initialization values of the .itcmram section. Defined in the linker script */
.word _sitcmram_init
/* Start address for the .dtcmram section. Defined in the linker script */
.word _sdtcmram
/* End address for the .dtcmram section. Defined in the linker script */
.word _edtcmram
/* Start address for the initialization values of the .dtcmram section. Defined in the linker script */
.word _sdtcmram_init
/* Start address for the initialization values of the .ram_d1_cached section. Defined in the linker script */
.word _sram_d1_cached_init
/* Start address for the .ram_d1_cached section. Defined in the linker script */
.word _sram_d1_cached_start
/* End address for the .ram_d1_cached section. Defined in the linker script */
.word _sram_d1_cached_end
/* Stack used for SystemInit_ExtMemCtl; always internal RAM used */
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary setup is performed, after which the application
* supplied main() routine is called.
* @PAram None
* @retval None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr sp, =_estack /* Set stack pointer */
/* Call the clock system initialization function. */
bl SystemInit
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
/* Copy the itcmram segment initializers from flash to ITCMRAM */
ldr r0, =_sitcmram /* Start address in ITCMRAM */
ldr r1, =_eitcmram /* End address in ITCMRAM */
ldr r2, =_sitcmram_init/* Start address of initialization values in Flash */
movs r3, #0
b LoopCopyItcmramInit
CopyItcmramInit:
ldr r4, [r2, r3] /* Load word from Flash (_sitcmram_init) */
str r4, [r0, r3] /* Store word to ITCMRAM (_sitcmram) */
adds r3, r3, #4 /* Increment offset */
LoopCopyItcmramInit:
adds r4, r0, r3 /* Check if all data is copied */
cmp r4, r1 /* Compare with end of ITCMRAM (_eitcmram) */
bcc CopyItcmramInit /* If not finished, continue copying */
/* Copy the dtcmram segment initializers from flash to DTCMRAM */
ldr r0, =_sdtcmram /* Start address in DTCMRAM */
ldr r1, =_edtcmram /* End address in DTCMRAM */
ldr r2, =_sdtcmram_init/* Start address of initialization values in Flash */
movs r3, #0
b LoopCopyDtcmramInit
CopyDtcmramInit:
ldr r4, [r2, r3] /* Load word from Flash (_sdtcmram_init) */
str r4, [r0, r3] /* Store word to DTCMRAM (_sdtcmram) */
adds r3, r3, #4 /* Increment offset */
LoopCopyDtcmramInit:
adds r4, r0, r3 /* Check if all data is copied */
cmp r4, r1 /* Compare with end of DTCMRAM (_edtcmram) */
bcc CopyDtcmramInit /* If not finished, continue copying */
/* Copy the ram_d1_cached segment initializers from flash to RAM_D1_CACHED */
ldr r0, =_sram_d1_cached_start /* Start address in RAM_D1_CACHED */
ldr r1, =_sram_d1_cached_end /* End address in RAM_D1_CACHED */
ldr r2, =_sram_d1_cached_init /* Start address of initialization values in Flash */
movs r3, #0
b LoopCopyRamD1CachedInit
CopyRamD1CachedInit:
ldr r4, [r2, r3] /* Load word from Flash (_sram_d1_cached_init) */
str r4, [r0, r3] /* Store word to RAM_D1_CACHED (_sram_d1_cached_start) */
adds r3, r3, #4 /* Increment offset */
LoopCopyRamD1CachedInit:
adds r4, r0, r3 /* Check if all data is copied */
cmp r4, r1 /* Compare with end of RAM_D1_CACHED (_sram_d1_cached_end) */
bcc CopyRamD1CachedInit /* If not finished, continue copying */
/* Zero fill the bss segment */
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point */
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
