cancel
Showing results for 
Search instead for 
Did you mean: 

Move object (.obj) to external SRAM

npatil15
Senior

Hello,

Trying to move complete *.cpp.obj to external SRAM configure via FMC. Check the below .ld file for STM32F7 controller.

MEMORY
{
  RAM (xrw)              : ORIGIN = 0x20000000, LENGTH = 512K
  FLASH (rx)             : ORIGIN = 0x8000000,  LENGTH = 2048K
  EXT_SRAM_DATA (rw)     : ORIGIN = 0x60000000, LENGTH = 256K
  EXT_SRAM_MODULES (rw)  : ORIGIN = 0x60040000, LENGTH = 256K
}

  /* ========== Section for Buffers / Variables (up to 256KB) ========= */
  .ext_sram_data :
  {
      . = ALIGN(8);
      KEEP(*(.ext_sram_data))
      KEEP(*(.ext_sram_data*))
      . = ALIGN(8);
  } > EXT_SRAM_DATA AT> FLASH

  .ext_sram_modules :
  {
    . = ALIGN(8);
    KEEP(*(testModule.cpp.obj))
    . = ALIGN(8);
  } >EXT_SRAM_MODULES AT> FLASH

 

After code compile, I can see the build details as

Memory region         Used Size  Region Size  %age Used
             RAM:      119928 B       512 KB     22.87%
           FLASH:      246444 B         2 MB     11.75%
   EXT_SRAM_DATA:           0 B       256 KB      0.00%
EXT_SRAM_MODULES:           0 B       256 KB      0.00%

And .map file as below

.ext_sram_data  0x60000000        0x0 load address 0x0803c2ac
                0x60000000                        . = ALIGN (0x8)
 *(.ext_sram_data)
 *(.ext_sram_data*)
                0x60000000                        . = ALIGN (0x8)

.ext_sram_modules
                0x60040000        0x0 load address 0x0803c2ac
                0x60040000                        . = ALIGN (0x8)
 *(testModule.cpp.obj)
                0x60040000                        . = ALIGN (0x8)

 

I have tried to add uint8_t var[1024] global array in testModule.cpp but still I can see space has used from external SRAM. 

So am I correctly using the feature to move complete object to external SRAM or if it is correct, where I can check that the space has been utilized?

Thanks,

Nitin

 

1 ACCEPTED SOLUTION

Accepted Solutions
npatil15
Senior

Hello,

I found the root cause; I was moving objects to external Flash and that I can ensure by reading the external Flash from STM32CubeProgrammer. But as I move complete object then it also moved global, static to external Flash. And those variables need access before main() (i.e., before __libc_init_array).

So, when object has globally created heap region, that causes fault, because we haven't ready for heap related initialization. To solve this, we need to call "vPortDefineHeapRegions(xHeapRegions)" before "__libc_init_array" available in startup file, where we have create a array of heap regions.

HeapRegion_t xHeapRegions[] =
{
#if !USE_EXTERNAL_HEAP_ONLY
    { internalHeap,          sizeof(internalHeap) },
#endif
  { &ext_sram_start, (size_t)(EXTERNAL_HEAP_SIZE) },
  { NULL, 0 }
};

 

View solution in original post

16 REPLIES 16
mƎALLEm
ST Employee

Hello,

You've located these sections to the Flash

 } > EXT_SRAM_DATA AT> FLASH

Remove > FLASH from these sections:

  .ext_sram_data :
  {
      . = ALIGN(8);
      KEEP(*(.ext_sram_data))
      KEEP(*(.ext_sram_data*))
      . = ALIGN(8);
  } > EXT_SRAM_DATA
To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
npatil15
Senior

Hello, 

I have two section, one for DATA and other for MODULES, so my expectation is if I can be able to move complete object to external RAM then it will be useful. So, I have updated the .ld file as explain in the description.

I have tried to remove AT FLASH from MODULES and DATA section both but still I can't see the global or static variable at the top in the external RAM memory still I can see they have used the internal RAM address.

So, what configuration I missed here to achieved this, to move complete module to external SRAM.

Thanks,

Nitin

npatil15
Senior

Hello,

I have tried to remove FLASH but looks like it can see in. map file at the address, but I can't see it has any size allocated, why? And code is running.

   
MEMORY
{
RAM (xrw)           : ORIGIN = 0x20000000, LENGTH = 512K
FLASH (rx)          : ORIGIN = 0x8000000,  LENGTH = 2048K
EXT_FLASH (rx)      : ORIGIN = 0x64000000, LENGTH = 16M
EXT_SRAM_HEAP (xrw) : ORIGIN = 0x60000000, LENGTH = 256K
EXT_SRAM_STACK (rw) : ORIGIN = 0x60040000, LENGTH = 256K
}

.ext_sram_stack :
  {
    . = ALIGN(8);
    *(.ext_sram_stack*)         /* Use for __attribute__((section(".ext_sram_stack"))) */
    *(.ext_sram_stack)
    *testModule.cpp.obj(.text .text.* .rodata .rodata.*)
    . = ALIGN(8);
  } >EXT_SRAM_STACK

 

Here is .map file

.ext_sram_stack
                0x60040000        0x0
                0x60040000                        . = ALIGN (0x8)
 *(.ext_sram_stack*)
 *(.ext_sram_stack)
 *testModule.cpp.obj(.text .text.* .rodata .rodata.*)
                0x60040000                        . = ALIGN (0x8)

 

Other section of .map file

Memory Configuration

Name             Origin             Length             Attributes
RAM              0x20000000         0x00080000         xrw
FLASH            0x08000000         0x00200000         xr
EXT_FLASH        0x64000000         0x01000000         xr
EXT_SRAM_HEAP    0x60000000         0x00040000         xrw
EXT_SRAM_STACK   0x60040000         0x00040000         rw
*default*        0x00000000         0xffffffff

 Thanks

JohannesK
Associate III

Hi @npatil15 !

You could also check the output from the ELF file with arm-none-eabi-size directly, like the following example:

$ arm-none-eabi-size -A -x test.elf
test.elf  :
section              size         addr
.text              0x1474    0x8000000
.rodata              0x26    0x8001474
.data                 0x0   0x24000000
.bss                  0x8   0x24000000
.heap             0x7eff8   0x24000008
.stack             0x1000   0x2407f000
.ARM.attributes      0x2f          0x0
.comment             0x24          0x0
Total             0x814ed
$

I doesn't calculate the usage in percent and also doesn't show the name from the memory region, but should show all section addresses and sizes from the ELF file as defined in the linker script.

 

 

  

 

npatil15
Senior

Hello @mƎALLEm & @JohannesK ,

Somehow, I got success in small thing. I can be able to load .data section of testModule to external SRAM. Now I need support on to load .text section so that I can store code section in external sram.

Check below, where I have tried to add all the things related to testModule, thinking it should not miss anything while loading any function or data, and when I just keep (.data .data.*) then it works as it does not need to load any function here.

.ext_sram_stack :
{
  . = ALIGN(4);

  /* Option A: attribute-tagged entities */
  *(.ext_sram_stack)
  *(.ext_sram_stack.*)

  /* Use wildcard to be resilient to path differences */
  *testModule*(.text .rodata .ARM.extab .preinit_array .init_array .fini_array .data .tdata)
  *testModule*(.text.* .rodata.* .ARM.extab.* .preinit_array.* .init_array.* .fini_array.* .data.* .tdata.*)

  . = ALIGN(4);
  __ext_stack_start__ = ADDR(.ext_sram_stack);
  __ext_stack_end__   = .;
} > EXT_SRAM_STACK AT> EXT_FLASH

__ext_stack_load__ = LOADADDR(.ext_sram_stack);
__ext_stack_size__ = SIZEOF(.ext_sram_stack);

And here below just after FMC_Iinit() I have write this logic to load the EXT_FLASH data to EXT_SRAM_STACK, currently I'm not sure does the location is correct or not.

extern uint8_t __ext_stack_start__, __ext_stack_end__, __ext_stack_load__;
uint8_t *dst = &__ext_stack_start__;
uint8_t *end = &__ext_stack_end__;
uint8_t *src=&__ext_stack_load__;
size_t n = (size_t)(end - dst);
for (size_t i = 0; i < n; ++i) 
    dst[i] = src[i];
__DSB(); 
__ISB();

Here is .map file

              0x60040000                        __ext_stack_start__ = ADDR (.ext_sram_stack)
                0x60051d98                        __ext_stack_end__ = .
                0x64000000                        __ext_stack_load__ = LOADADDR (.ext_sram_stack)
                0x00011d98                        __ext_stack_size__ = SIZEOF (.ext_sram_stack)

Here below the function, I'm trying to access

.text.testModuleTaskWrapper
                0x600498cc       0x1c CMakeFiles/MCU_Configuration.dir/Classes/TestModule/src/testModule.cpp.obj
                0x600498cc                testModuleTaskWrapper

I can see all the function are not pointing to external sram address range.

For information:

MCU_Configuration.elf  :
section                 size         addr
.isr_vector            0x1f8    0x8000000
.ext_flash_code          0x0   0x64000000
.ext_sram_stack      0x11d98   0x60040000
.text                0x32f50    0x8000200
.rodata               0x3c7c    0x8033150
.ARM.extab               0x0    0x8036dcc
.ARM                     0x8    0x8036dcc
.preinit_array           0x0    0x8036dd4
.init_array             0x18    0x8036dd4
.fini_array              0x4    0x8036dec
.data                  0x1dc   0x20000000
.tdata                   0x0   0x200001dc
.tbss                    0x0   0x200001dc
.bss                 0x1cecc   0x200001e0
._user_heap_stack      0x604   0x2001d0ac
.ext_sram_heap           0x0   0x60000000
.ARM.attributes         0x2e          0x0
.comment                0x43          0x0
.debug_info         0x1426fb          0x0
.debug_abbrev        0x1fe93          0x0
.debug_aranges        0x8808          0x0
.debug_rnglists       0x6756          0x0
.debug_macro         0x6ae7f          0x0
.debug_line          0x888f4          0x0
.debug_str          0x179e41          0x0
.debug_frame         0x25c84          0x0
.debug_line_str        0x16b          0x0
.debug_loclists       0x232b          0x0
Total               0x46ce57

So, help me out what I'm missing here?

Thanks,

Nitin

 

JohannesK
Associate III

Hello,

Sorry, for my maybe *** question. But what do you mean with that the code from testModule.cpp.obj is not pointing to external SRAM?

As I can see in your posted extract from the map file it's located in EXT_RAM_STACK as you defined in linker script:

.text.testModuleTaskWrapper
                0x600498cc       0x1c CMakeFiles/MCU_Configuration.dir/Classes/TestModule/src/testModule.cpp.obj
                0x600498cc                testModuleTaskWrapper

The entry point from the function testModulTaskWrapper should be at address 0x600498CC in the range from EXT_RAM_STACK according your linker script. You have defined it here: 

} > EXT_SRAM_STACK AT> EXT_FLASH

 You have defined these memory sections above:

EXT_FLASH (rx)      : ORIGIN = 0x64000000, LENGTH = 16M
EXT_SRAM_HEAP (xrw) : ORIGIN = 0x60000000, LENGTH = 256K
EXT_SRAM_STACK (rw) : ORIGIN = 0x60040000, LENGTH = 256K

You have placed all sections from testModule.cpp.obj in EXT_RAM_STACK loaded from EXT_FLASH currently.

What behavior do you want exactly? Do you want that the code from testModule.cpp.obj is located EXT_SRAM_HEAP which you defined as executable (xrw) too? Or should the code (.text) from testModule.cpp.obj execute from external flash? Sorry, I don't know exactly what you need.

BTW: Your copy function (FLASH to SRAM) should be okay. But you might to need call the function pointers from preinit_array, init_array and fini_array by yourself to get the main code work. So I would suggest to modify your current linker script and add start/end symbols for each sections. I can help you with an example, but first I need to know what behavior do you exactly need. 

 

npatil15
Senior

Hello @JohannesK ,

I want the testModule .text .text.* section to run from external SRAM. Currently when I tried it crashed and jump to Hardfault. So what I'm missing ?

 

In previous, it was working only with when I move testModule .data .data.* section to external SRAM.

Thanks,

Nitin

JohannesK
Associate III

Hello @npatil15 ,

Okay, from EXT_RAM_HEAP or EXT_RAM_STACK? (You have defined EXT_RAM_STACK as read/write only.)

And according the Hardfault: Can you provide more debugging information? I mean the reason for the Hardfault.

Here is a good thread for debugging Hardfaults:

How to debug a HardFault on an Arm® Cortex®-M STM32

 

npatil15
Senior

Hello @JohannesK ,

I was trying to run from EXT_RAM_STACK. And yes, it is read/write and that may be the reason it was failing?

I will try to make it executable permissions and update. And if still I got hardfault then I will come with debug information as per suggested link.

Thanks,

Nitin