AnsweredAssumed Answered

Initialization of RAM_D2 in STM32H743

Question asked by Michael Partheil on Mar 9, 2018
Latest reply on Mar 15, 2018 by Michael Partheil

Dear all,

 

I'm using the Nucelo-144 board with a STM32H743ZI, with the GCC+Makefile toolchain, and am trying to get the RAM in the D2 domain to work.

 

I generated a Makefile-project with CubeMX and added the following to the linker file:

/* used by the startup to initialize data */
_siRAM_D2 = LOADADDR(.RAM_D2.data);

/* Initialized data sections goes into RAM_D2, load LMA copy after code */
.RAM_D2.data :
{
   . = ALIGN(4);
   _sRAM_D2 = .; /* create a global symbol at data start */
   *(.RAM_D2.data) /* .data sections */
   *(.RAM_D2.data*) /* .data* sections */

   . = ALIGN(4);
   _eRAM_D2 = .; /* define a global symbol at data end */
} >RAM_D2 AT> FLASH

 

/* Uninitialized data section */
. = ALIGN(4);
.RAM_D2.bss (NOLOAD) :
{
   /* This is used by the startup in order to initialize the .bss secion */
   _sbss_RAM_D2 = .; /* define a global symbol at bss start */
   *(.RAM_D2.bss)
   *(.RAM_D2.bss*)

   . = ALIGN(4);
   _ebss_RAM_D2 = .; /* define a global symbol at bss end */
} >RAM_D2

 

.RAM_D2 : {*(.RAM_D2)} >RAM_D2 AT> FLASH

Also, to initialize .RAM_D2.data and zero the .RAM_D2.bss segment I added the following to the startup assembly file:

/* Copy the data segment initializers from flash to RAM_D2 */
   movs r1, #0
   b LoopCopyDataInit_RAM_D2

CopyDataInit_RAM_D2:
   ldr r3, =_siRAM_D2
   ldr r3, [r3, r1]
   str r3, [r0, r1]
   adds r1, r1, #4

LoopCopyDataInit_RAM_D2:
   ldr r0, =_sRAM_D2
   ldr r3, =_eRAM_D2
   adds r2, r0, r1
   cmp r2, r3
   bcc CopyDataInit_RAM_D2
   ldr r2, =_sbss_RAM_D2
   b LoopFillZerobss_RAM_D2


/* Zero fill the bss segment. */
FillZerobss_RAM_D2:
   movs r3, #0
   str r3, [r2], #4

LoopFillZerobss_RAM_D2:
   ldr r3, = _ebss_RAM_D2
   cmp r2, r3
   bcc FillZerobss_RAM_D2

Now, everything compiles and objdump shows the sections with correct length, position and attributes, and I can place variables in the D2 RAM using __attribute__((section(".RAM_d1.data")) directives.

 

However, it looks like these memory regions are neither initialized (for .RAM_D2.data) nor zeroed out (for .RAM_D2.bss), that is, the initialization code in the startup assembly does not work. The interesting thing is that using exactly the same code and linker script but for the D1 and D3 RAM works perfectly fine?!

 

Also, I tried initializing the memory in C with the following code (only for .RAM_D2.data, .RAM_D2.bss is similar):

extern uint32_t _siRAM_D2;
extern uint32_t _sRAM_D2;
extern uint32_t _eRAM_D2;
void__initialize_data(uint32_t* flash_begin, uint32_t* data_begin, uint32_t* data_end){
   uint32_t *p = data_begin;
   while(p < data_end){
      *p++=*flash_begin++;
   }
}
In main():
__initialize_data(&_siRAM_D2,&_sRAM_D2,&_eRAM_D2);
Here the interesting thing is that when I place the call to __initialize_data immediately at the beginning of main(), it does not work, but at some later point in time (after HAL and board init) it does indeed work!
Does anyone have an idea what the problem could be here? Especially, is there a difference between the D1, D2, and D3 RAMs that could be causing this? Because, as I wrote above, everything is 100% fine for D1 and D3, just not for D2 RAM...
Thanks a lot!
Michael

Outcomes