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
}
.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);
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
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