Getting initialized variables into HyperRAM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Getting initialized variables into HyperRAM

628 Views
derekkrouze
Contributor II

Hello, 

I've recently gotten HyperRAM working with the i.mx rt 1064. However, now I'm trying to place data in it for use with the application. I'm using a variation of the MIMXRT1064xxxxx_flexspi_nor.ld provided with the NXP sdk. I am currently not using MCUXpresso, but gcc and vscode implementation.

 

I added the memory region to the .ld file

 

MEMORY
{
  m_flash_config        (RX)  : ORIGIN = 0x70000000, LENGTH = 0x00001000
  m_ivt                 (RX)  : ORIGIN = 0x70001000, LENGTH = 0x00001000
  m_interrupts          (RX)  : ORIGIN = 0x70002000, LENGTH = 0x00000400
  m_text                (RX)  : ORIGIN = 0x70002400, LENGTH = 0x003FDC00
  m_data                (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00020000
  m_data2               (RW)  : ORIGIN = 0x20200000, LENGTH = 0x00080000
  m_hyperram            (RWX)  : ORIGIN = 0x60000000, LENGTH = 0x00020000
}

 

and a basic way to move data into the custom section:

 

  .data_hyperram :
  {
    FILL(0xff)
    . = ALIGN(4) ;
    __start_data_hyperram = .;
    KEEP(*(m_hyperram_data))    
    . = ALIGN(4) ;
    __end_data_hyperram = .;
  } > m_hyperram​

 

In my application I then have a macro to place variables there:

 

#define HYPERRAM_SECTION_DATA(func) __attribute__((section("m_hyperram_data"))) func

HYPERRAM_SECTION_DATA(volatile uint32_t testdata = 0x12345678);

 

 My variables seem to be correctly placed into the HyperRAM section, but they are not initialized. I am unsure if there is more I need to add to my .ld file, or if there are custom copy routines that I need to add to the startup.s file. Any help on where to go from here would be greatly appreciated. 
 
0 Kudos
2 Replies

610 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

It needs related routine/code to do the vaiable initialization at HyperRAM.

The MCUXpresso provides related code to do the variable initialization, while I am not sure gcc and vscode implementation provide the same function or not.

You need to add related code at <startup.s> file to do related variable initialization.

Thanks for the attention.

Mike

0 Kudos

598 Views
derekkrouze
Contributor II

Thanks Mike,

I played around with this for a little bit and came up with a solution. Figured I'd post that for the next person who runs into this. The main missing piece was telling the linker where to place the data section. A section needed to be carved out below the .data section and the AT() keyword needed to be used:

  __HYPERRAM_DATA_ROM = __HYPERFLASH_DATA_ROM + (__end_data_hyperflash - __start_data_hyperflash);

  /* HyperRam section*/  
  .data_hyperram : AT(__HYPERRAM_DATA_ROM)
  {
    FILL(0xff)
    . = ALIGN(4) ;
    __start_data_hyperram = .;    
    KEEP(*(m_hyperram_data))    
    . = ALIGN(4) ;
    . = ALIGN(32);
    __ram_function_start__ = .;
    KEEP(*(m_hyperram_code))
    . = ALIGN(128);
    __ram_function_end__ = .;    
    __end_data_hyperram = .;
  } > m_hyperram

 Then I found two different ways to copy the initialized values into RAM, one through modifying the startup assembly code, or you can do this with C in the startup routine. 

ASM:

#ifdef __STARTUP_INITIALIZE_RAMFUNCTION
    ldr    r2, =__ram_function_start__
    ldr    r3, =__ram_function_end__
#ifdef __PERFORMANCE_IMPLEMENTATION
/* Here are two copies of loop implementations. First one favors performance
 * and the second one favors code size. Default uses the second one.
 * Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */
    subs    r3, r2
    ble    .LC_ramfunc_copy_end
.LC_ramfunc_copy_start:
    subs    r3, #4
    ldr    r0, [r1, r3]
    str    r0, [r2, r3]
    bgt    .LC_ramfunc_copy_start
.LC_ramfunc_copy_end:
#else  /* code size implemenation */
.LC_ramfunc_copy_start:
    cmp     r2, r3
    ittt    lt
    ldrlt   r0, [r1], #4
    strlt   r0, [r2], #4
    blt    .LC_ramfunc_copy_start
#endif
#endif /* __STARTUP_INITIALIZE_RAMFUNCTION */

C:

extern unsigned int __start_data_hyperflash;
extern unsigned int __end_data_hyperflash;
extern unsigned int __HYPERFLASH_DATA_ROM;

void copy_hyperram_data()
{
#ifndef __HYPERFLASH_ASM_ROM_COPY
  unsigned int* hyperflash_rom_table = &__HYPERFLASH_DATA_ROM;
  unsigned int* hyperflash_ram_table = &__start_data_hyperflash;
  unsigned int hyperflash_copy_size = (&__end_data_hyperflash - &__start_data_hyperflash);

  for (unsigned int Index = 0; Index < hyperflash_copy_size; Index++)
  {
    hyperflash_ram_table[Index] = hyperflash_rom_table[Index];
  }
#endif  //__HYPERRAM_ASM_ROM_COPY
}

Granted this is for my specific use case, but I'd imagine other linker files would follow the same procedure.

-Derek