This document describes a way how to execute a selected function(s) out of RAM memory for a project running out of Flash memory.
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_my_flash : org = 0x01000000, len = 4K // optional - this is dedicated section for the RAM function rom image
m_text : org = 0x01001000, len = 5628K // default section for code
m_my_ram : org = 0x40000000, len = 4K // optional - specific section where a RAM routine(s) should be copied into
m_data : org = 0x40001000, len = 764K // default section for data/stack/heap
}
SECTIONS
{
...
.MyRamCode :
{
MY_RAM_START = .; // this symbol is optional
KEEP (*(.MyRamCode)) // KEEP - avoid dead stripping if an object is not referenced
MY_RAM_END = .; // this symbol is optional
} > m_my_ram AT>m_my_flash // the section above is linked into m_my_ram and Rom image is stored into m_my_flash
SECTIONS
{
...
.MyRamCode :
{
MY_RAM_START = .; // this symbol are optional
KEEP (*(.MyRamCode)) // KEEP - avoid dead stripping if an object is not referenced
MY_RAM_END = .; // this symbol are optional
} > m_data AT>m_text // the section is linked into default data memory area and its rom image is placed into the default code memory
__attribute__ ((section(".MyRamCode"))) // place the function below into .MyRamCode section
int test_RAM(int arg1) __attribute__ ((longcall)); // declare the function as "far"
You can create some linker symbols (.MyRamCode RAM and ROM addresses and size) and import them to the module where copy-down is implemented.
__MY_RAM_ADR = ADDR (.MyRamCode);
__MY_RAM_SIZE = SIZEOF (.MyRamCode);
__MY_RAM_ROM_ADR = LOADADDR (.MyRamCode);
The final source file may look like this:
#include <string.h>
extern unsigned long __MY_RAM_ADR;
extern unsigned long __MY_RAM_ROM_ADR;
extern unsigned long __MY_RAM_SIZE;
__attribute__ ((section(".MyRamCode"))) // place the function below into .MyRamCode section
int test_RAM(int arg1) __attribute__ ((longcall)); // declare the function as "far"
...
void main(void)
{
int counter = 0;
memcpy(&__MY_RAM_ADR , &__MY_RAM_ROM_ADR, &__MY_RAM_SIZE); // copy the function from flash to RAM
counter = test_RAM(counter); // call the function
...
}
Hope it helps!
Stan
hello, Stanislav Sliva
I have tested it.but i find a problem which is it can run well in debug,when i take off the MULTILINK UNIVERSAL, and reset the board ,it cannot work normal,can you help me?
i find that if the VMA is different from the LMA, it happens. when the VMA(in ram) is different form LMA(in rom),the s32 will show "Program received signal SIGTRAP, Trace/breakpoint trap.",and go on running by F8 is pressed. if the MULTILINK UNIVERSAL is removed,it can not run normal in run mode.
The facts are as follows:
The MCU is mpc5746c.the ide is S32 Design Studio for Power Architecture Version: 1.2
In debug mode, the problem is as follow figure:
when the code which is " e_bl main" is run,it run _eabi first before into main.During the process , "program received signal SIGTRAP..." happens.
The program can go on running ,when the "resume button " is pressed on.But if I take off the MULTILINK UNIVERSAL,and reset the board,the program
can not runinto main,it is suspendend maybe. when the VMA is the same as LMA in the rom, the problem never happen.i think that the reason is se_illegal but how can i do to avoid it ? help me,help you ,thank you!
Hi,
I suspect this issue is caused by the fact you created a project in S32DS Power 1.x and imported the project into S32DS v1.2.
Please have a look here:
https://community.nxp.com/docs/DOC-335361
And thanks for sharing the screenshot I've added it into the document!
Hope it helps.
Stan
hi,
i feel very happy for your reply.
I have looked at the "HOWTO: Migrate project created in S32DS Power v1.x into v1.2+ " earnestly. i have been awared of that.
what i want to say is that my test project is created in S32DS Power v1.2,and added the section of ".MyRamCode" and others needed as you describe. and the problems happen.I try to modify the section as follows:
the "se_illegal" never happen when _init() is running,but the function that run a routine form ram in s32 can not be realized. so if you have time , you can test it in s32v1.2 .I think the problem will happen.If the lib has no problem, maybe the ld is needed to modify,but i have no idea.
waiting for your reply,thank you!
The same experienced using S32 Studio for powerpc v1.2; even easier way to reproduce:
- New project >> MPC5674F
- select library NewLib Nano
- added a ram function into main.c
- added .ramfuncs input section to .data section (will be copied by initialization)
main.c:
#include "derivative.h" /* include peripheral declarations */
extern void xcptn_xmpl(void);
int counter = 0;
#define RAMFUNC __attribute__ ((longcall, section(".ramfuncs")))
RAMFUNC void ramcall(void) {
counter+=2;
}
int main(void) {
xcptn_xmpl ();
for(;;) {
counter++;
ramcall();
}
}
56xx_flash.ld
....
.data :
{
*(.data)
*(.data.*)
*(.ramfuncs)
} > m_data AT>m_text
...
Generated disassembly on main entrypoint (main >> __eabi >> __init)
00004438 <__init>:
4438: 18 21 06 f0 e_stwu r1,-16(r1)
443c: 00 80 se_mflr r0
443e: 54 01 00 14 e_stw r0,20(r1)
4442: 00 00 se_illegal
4444: 79 ff fc ad e_bl 40f0 <frame_dummy>
4448: 79 ff fd b9 e_bl 4200 <__do_global_ctors_aux>
444c: 50 01 00 14 e_lwz r0,20(r1)
4450: 00 90 se_mtlr r0
4452: 20 f1 se_addi r1,16
4454: 00 04 se_blr
4456: 50 01 18 21 e_lwz r0,0(r1)
It seems that long call triggers a wrong alignment on the init trampoline; the problem happens both with Debug/Release (flash) targets (on Debug_RAM code is already in ram, the problem is not triggered).
I hope it helps.
Have you been solved it?Maybe what you think is right,what can we do to avoid it.
Hello All,
Thanks for reporting this problem!
I can confirm this is a e200 gcc linker defect (defect#: CMPE200GCC-181) which is currently investigated by the compiler team.
This works fine on ARM gcc (S32DS for ARM).
I'll keep you informed about the progress.
Thanks!
Stan
My workaround for this problem was tweaking file ELe200/src_gcc/libgcc/config/rs6000/eabivle-ci.S: in the __init function implementation I've added a se_nop to enforce 4byte padding which was is not implicit on vle (while it was with booke):
/* Head of __init function used for static constructors. */
#ifdef __VLE__
.section ".init","axv"
#else
.section ".init","ax"
#endif
.align 2
FUNC_START(__init)
#ifdef __VLE__
e_stwu 1,-16(1)
se_mflr 0
se_nop
e_stw 0,20(1)
#else
stwu 1,-16(1)
mflr 0
stw 0,20(1)
#endif
Unfortunately applying this workaround requires to rebuild compiler.
Regards,
Elker
Hello, Stanislav Sliva,
I did this according to your solution in S32DS for Power PC (MPC5744P).
But I encountered problem when I copy the code from flash to RAM.
In C source code, I declared the external variable created by .ld file:
__MY_RAM_ADR = ADDR (.MyRamCode);
__MY_RAM_SIZE = SIZEOF (.MyRamCode);
__MY_RAM_ROM_ADR = LOADADDR (.MyRamCode);
But these variables are actually strange values in my source code when I debug the code.
__MY_RAM_SIZE is correct. But __MY_RAM_ADR is zero and __MY_RAM_ROM_ADR is very strange value.
I checked the generated map file. All these three variables are correct value.
I don't understand why it's wrong value in my C source code.
I also tried to use them in assembly code in "Startup.S", just like the "DataCopy" for ".data" and ".sdata" section.
Both __MY_RAM_ADR and __MY_RAM_ROM_ADR are correct values.
Do you have any idea why I'm having this issue? Any additional settings for the compiler needed?
Best Regards,
Jason Yang
Hi,
I would like to copy all the functions in several files to RAM and execute. Is there an alternative for copying the object files to RAM instead of individual function.
Many thanks in advance.
Best regards,
Sreekanth Challa
Hi,
My target processor is MPC5643L
To fix this problem I did try to modify the library file.
From the output.map file we can find what library file used as __init section.
like..
.init 0x000119c4 0xc c:/nxp/s32ds_power_v2017.r1/cross_tools/powerpc-eabivle-4_9/bin/../lib/gcc/powerpc-eabivle/4.9.4/e200z4/fp/ecrti.o
0x000119c4 __init
Find the library file (my case is ecrti.o)
and manually modify to find "18 21 06 F0 00 80 54 01 00 14 00 00 " - in my case, 2 of part exists. need to modify all of those.
To "18 21 06 F0 00 80 00 80 54 01 00 14" - 00 80 inserted.
This is the part of
__init
e_stwu r1,-16(r1)
se_mflr r0
e_stw r0,20(r1)
se_illegal <---- 0x00, 0x00
To
__init
e_stwu r1,-16(r1)
se_mflr r0
se_mflr r0 <--- insert this repeated from just before, value = 0x00, 0x08
e_stw r0,20(r1) <--- 2byte shifted, value = 0x54010014
This modification works in my experiment. for Debug, Release both of object.
I hope it helps,
Regards,
I met the same issue, did you solve it?
Dear Duke!
Thank you very much. This seems to help! (using an MPC5745R)
Kind regards, Folkert
Hi Duke and Folkert,@Folkert Sikkema @Duke Lee
I tried it but failed, just wonder should I modify both ecrti.o and ecrtn.o or only ecrti.o? Another question is should I also modify the <__fini>?
btw because we use SPE, so what I modified is in e200z4/fp/spe.
Appreciate if you guys can share more detail.
Best regard.
Dear Xiaoxi,
I only needed to change ecrti.o as shown in the picture
Although this work-around works, I still wonder what the root-cause is...
Regards, Folkert
As same with Folkert,
Only the ecrti.o was needed to modify. in my case.
If you can trace your code, you can find what part has the problem.
If that is not 4 bytes aligned code as I mentioned.
probably you can use the same way to fix your code.
Or, post the problem point in the disassembled code.
Good luck.
Dear Duke!
Thank you very much. This works fine on my MPC5746C board, I move the m_text to 0x00FE0400 and boot failure before.
cmpe200gcc-181 has been fixed in compiler that comes in S32 Design Studio for Power Architecture 2017.R1 - Update 2 available
It's great!
We're waiting for the official patch of this problem.
Thank you for your update Alexander and NXP s32ds support team.
Duke it's already there. You can install latest one https://community.nxp.com/docs/DOC-341653 - it's cumulative.