Dear Expert,
I am working on flash remapping for MPC5748G, but I am unable to remap physical address to the desired logical address.
I have checked through debugging and found that all registers which are responsible for flash remapping has been written correctly as shown below.
since all registers has been written correctly but still, I cannot remap physical address to my desired logical address.
my code is as follows.
__attribute__ ((section(".func1")))void memoryremapa ();
__attribute__ ((section(".func2")))void memoryremapb ();
void Overlay(uint32_t word0, uint32_t word1, uint32_t word2, uint32_t descriptor);
int main()
{
Overlay(0x013c0000, 0x09200000, 0xFFFF0012, 0);
while(1)
{
memoryremapa();
memoryremapb();
}
}
__attribute__ ((section(".func1")))void memoryremapa ()
{
for (uint32_t i = 0; i < 500000; i++) {}
LED2_TOGGLE;
}
__attribute__ ((section(".func2")))void memoryremapb ()
{
for (uint32_t i = 0; i < 500000; i++) {}
LED0_TOGGLE;
}
void Overlay(uint32_t word0, uint32_t word1, uint32_t word2, uint32_t descriptor)
{
PFLASH_Type*const base = PFLASH;
base->PFCRD[descriptor].Word2 = word2;/* Enable remapping for individual masters, size of page */
base->PFCRD[descriptor].Word0 = word0;/* Logical address */
base->PFCRD[descriptor].Word1 = word1;/* Physical address */
base->PFCRDE|= (uint32_t)0x80000000 >> descriptor; /* Enable descriptor */
base->PFCRCR = PFLASH_PFCRCR_GRMEN(1);
base->PFCRCR |= PFLASH_PFCRCR_IRMEN(1);
}
This is how my linker file looks like.
according to code, physical address 0x013c0000 memoryremapb() function has been remapped to logical address 0x09200000 which is mirrored of physical address so memoryremapb() function should be executing instead of memoryremapa() function, but I found both functions they are executing. Please let me know what the problem is.
Regards
Muhammad Faisal Khan
解決済! 解決策の投稿を見る。
Attached is working example.
Function test() is forced to 0x0110_0000 by linker file but it's compiled for address 0x0930_0000 (using AT directive).
This is default state - function at 0x0x0110_0000 is simply mirrored to 0x0910_0000 as expected (no remapping yet):
This is a state after remapping - after execution of Overlay() function. I remapped it to 0x0930_0000:
And once stepping into test(), I can see that the code is successfully executing from this address:
And one more important thing which you can see in the example - it is necessary to allow instruction fetching from remapped space by:
PFLASH.PFCRCR.B.IRMEN = 1; /* Allow instruction fetches */
Regards,
Lukas
Hi @FAISAL0323
First thing is that you mismatched logical and physical address.
Overlay(0x013c0000, 0x09200000, 0xFFFF0012, 0);
void Overlay(uint32_t word0, uint32_t word1, uint32_t word2, uint32_t descriptor)
base->PFCRD[descriptor].Word0 = word0;/* Logical address */
base->PFCRD[descriptor].Word1 = word1;/* Physical address */
According to this, you are trying to remap normal flash by mirrored flash. But it works in opposite way. You can remap only mirrored space.
Regardless of that, the idea is also different. You simply forced one function to 0x138000 and second to 0x13C000. So, anytime you call these functions, those will be executed from this normal flash. This is expected behavior. It doesn't matter if you enabled the overlay feature or not. The only thing that will happen is that the code will be visible also at desired address in mirrored address space.
If you want to execute a function from remapped/mirrored address, you need to compile the function for this address space, so it will be stored in normal flash but compiled for remapped addresses. Just an example:
m_text1 : org = 0x1100000, len = 1K
m_text1_mirror : org = 0x9100000, len = 1K
.func1 :
{
KEEP(*(.func1))
} > m_text1_mirror AT>m_text1
If you call a function from .func1 section now, it will jump to remapped/mirrored address.
Regards,
Lukas
Dear Lukas,
Thanks for the detailed reply, I tried the solution given by you but still I am unable to get my desired results. I still have problem. Please have a look at my code and linker file to let me know what the problem is.
#include "derivative.h" /* include peripheral declarations */
extern void xcptn_xmpl(void);
__attribute__ ((section(".func1"))) void memoryremapa();
__attribute__ ((section(".func2"))) void memoryremapb();
int main(void)
{
volatile int counter = 0;
xcptn_xmpl (); /* Configure and Enable Interrupts */
// Setup the remap logic and physical addresses,
// per-master enable, and region size.
PFLASH.PFCRD[0].Word0.R = 0x09200000; // logical address
PFLASH.PFCRD[0].Word1.R = 0x01200000; // physical address
PFLASH.PFCRD[0].Word2.R = 0xffff0012; // 256KB region
// Enable remap descriptor 0.
PFLASH.PFCRDE.R = 0xffff0000;
// Enable instruction remap.
PFLASH.PFCRCR.B.IRMEN = 1;
// Enable flash remap.
PFLASH.PFCRCR.B.GRMEN = 1;
memoryremapa();
while (1);
/* Loop forever */
for(;;) {
counter++;
}
}
__attribute__ ((section(".func1"))) void memoryremapa()
{
uint8_t b = 1;
uint8_t c = 0;
if(b ==1)
{
c = 9;
}
else
{c = 10;}
}
__attribute__ ((section(".func2"))) void memoryremapb()
{
uint8_t b = 1;
uint8_t c = 0;
if(b ==1)
{
c = 9;
}
else
{c = 10;}
}
memoryremapb() function which is placed at 0x01200000 physical address has been remapped to 0x09200000 logical address but when I try to execute a function from remapped/mirrored address, after compile the function for 0x09200000 logical address but still I am unable to execute that, infect still when I call memoryremapa() function, it still executes memoryremapa() function definition only. but i want, remapped function should be executing which is memoryremapb().
Lastly, I would like to know how we can see contents of logical address through debugging to make it sure remapping has been done successfully?
Here is linker file.
/* Entry Point */
ENTRY(_start)
/* define heap and stack size */
__HEAP_SIZE = 0 ;
__STACK_SIZE = 4096 ;
SRAM_SIZE = 256K;
/* Define SRAM Base Address */
SRAM_BASE_ADDR = 0x40000000;
MEMORY
{
flash_rchw : org = 0x00FA0000, len = 0x4
cpu0_reset_vec : org = 0x00FA0000+0x10, len = 0x4
cpu1_reset_vec : org = 0x00FA0000+0x14, len = 0x4
cpu2_reset_vec : org = 0x00FA0000+0x04, len = 0x4
m_text : org = 0x1000000, len = 256K
m_text1 : org = 0x01100000, len = 256K
m_text2 : org = 0x01200000, len = 256K
m_text2_mirror : org = 0x09200000, len = 256K
m_data : org = 0x40000000, len = 256K
}
SECTIONS
{
.func1 :
{
KEEP*(.func1)
} > m_text2_mirror AT>m_text2
.func2 :
{
KEEP*(.func2)
} > m_text2
.rchw :
{
KEEP(*(.rchw))
} > flash_rchw
.cpu0_reset_vector :
{
KEEP(*(.cpu0_reset_vector))
} > cpu0_reset_vec
.cpu1_reset_vector :
{
KEEP(*(.cpu1_reset_vector))
} > cpu1_reset_vec
.cpu2_reset_vector :
{
KEEP(*(.cpu2_reset_vector))
} > cpu2_reset_vec
/* Note: if you move the 'startup' section shall modify the RCHW2_0 value for the corresponding core in the flashrchw.c file. */
.startup : ALIGN(0x400)
{
__start = . ;
*(.startup)
} > m_text
.core_exceptions_table : ALIGN(4096)
{
__IVPR_VALUE = . ;
KEEP(*(.core_exceptions_table))
} > m_text
.intc_vector_table : ALIGN(4096)
{
KEEP(*(.intc_vector_table))
} > m_text
.text :
{
*(.text.startup)
*(.text)
*(.text.*)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(16);
} > m_text
.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > m_text
.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > m_text
.rodata :
{
*(.rodata)
*(.rodata.*)
*(.got1)
} > m_text
.eh_frame_hdr : { *(.eh_frame_hdr) } > m_text
.eh_frame : { KEEP (*(.eh_frame)) } > m_text
.data :
{
*(.data)
*(.data.*)
*(.got.plt)
*(.got)
*(.got2)
*(.dynamic)
*(.fixup)
. = ALIGN(4);
} > m_data AT>m_text
.sdata2 :
{
*(.sdata2)
*(.sdata2.*)
} > m_data AT>m_text
.sbss2 (NOLOAD) :
{
/* _SDA2_BASE_ = .; */
*(.sbss2)
*(.sbss2.*)
} > m_data
.sdata :
{
*(.sdata)
*(.sdata.*)
} > m_data AT>m_text
.bss (NOLOAD) :
{
__BSS_START = .;
*(.sbss)
*(.sbss.*)
*(.bss)
*(.bss.*)
*(COMMON)
__BSS_END = .;
} > m_data
.stack (NOLOAD) : ALIGN(16)
{
__HEAP = . ;
PROVIDE (_end = . );
PROVIDE (end = . );
. += __HEAP_SIZE ;
__HEAP_END = . ;
_stack_end = . ;
. += __STACK_SIZE ;
_stack_addr = . ;
__SP_INIT = . ;
. += 4;
} > m_data
/*-------- LABELS USED IN CODE -------------------------------*/
/* Labels for Copying Initialised Data from Flash to RAM */
__DATA_SRAM_ADDR = ADDR(.data);
__SDATA_SRAM_ADDR = ADDR(.sdata);
__DATA_SIZE = SIZEOF(.data);
__SDATA_SIZE = SIZEOF(.sdata);
__DATA_ROM_ADDR = LOADADDR(.data);
__SDATA_ROM_ADDR = LOADADDR(.sdata);
/* Labels Used for Initialising SRAM ECC */
__SRAM_SIZE = SRAM_SIZE;
__SRAM_BASE_ADDR = SRAM_BASE_ADDR;
__BSS_SIZE = __BSS_END - __BSS_START;
}
Thanks for your time.
Best Regards
Muhammad Faisal Khan
Attached is working example.
Function test() is forced to 0x0110_0000 by linker file but it's compiled for address 0x0930_0000 (using AT directive).
This is default state - function at 0x0x0110_0000 is simply mirrored to 0x0910_0000 as expected (no remapping yet):
This is a state after remapping - after execution of Overlay() function. I remapped it to 0x0930_0000:
And once stepping into test(), I can see that the code is successfully executing from this address:
And one more important thing which you can see in the example - it is necessary to allow instruction fetching from remapped space by:
PFLASH.PFCRCR.B.IRMEN = 1; /* Allow instruction fetches */
Regards,
Lukas
Dear Lukas,
Thank you for that. it really helps to understand concept of remapping, but I still have ambiguities which need to be cleared.
1. I can see in default state, physical address is already mirrored to logical address, then why there is need to use PLFASH registers, to do remapping?
2. Which statement actually makes that mirror address?
3. What is difference between remapping and mirroring?
4. Can we use mirror address for remapping? just like in your example, can I use 0x0910_0000 which is mirror address in default state for remapping?
5. Can we execute our code from mirror address? if yes then why there is need of remapping?
Thanks for your time.
Best regards
Muhammad Faisal Khan
There are two typical use-cases why to use remapping.
Regards,
Lukas
Dear Lukas,
Thanks for detailed explanation.
Regards
Muhammad Faisal Khan