Dynamically Copying Code to RAM

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

Dynamically Copying Code to RAM

1,111 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by coco on Sun Sep 22 18:58:38 MST 2013
Hi, I'm using LPC1830 (no internal flash, only external SPIFI flash and 200K RAM). Any idea on how to copy code (swap-in/swap-out) into the RAM during run time? Thanks.
Labels (1)
0 Kudos
5 Replies

815 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rmilne on Tue May 12 12:48:17 MST 2015
Hi,

For IAR (7.20) the following linker and code copies spifi to sram (_ramfunc attribute not required).  Note that I add the "COPY_SRAM" symbol to the "Options...->C/C++ Compiler->Preprocessor->Defined symbols" box.  Note also that the boot source is set for SPIFI (either by hw pins or in the OTP) and FlashLPC18xx_43xx_SPIFI.mac is selected as the debugger macro file (J-Link in my case).

Linker file example:

/* LPC4350/LPC4330 linker file */
define symbol intvec_start__            = 0x10000000;
define symbol ROM_start__               = 0x00000000;
define symbol ROM_end__                 = 0x00000000;
define symbol APP_RAM_start__           = 0x10000000;
define symbol APP_RAM_end__             = 0x1001FFFF;
define symbol RAM_start__               = 0x10080000;
define symbol RAM_end__                 = 0x10091FFF;

define memory mem with size = 4G;
define region ROM_region                = mem:[from ROM_start__ to ROM_end__];
define region APP_RAM_region            = mem:[from APP_RAM_start__ to APP_RAM_end__];
define region RAM_region                = mem:[from RAM_start__ to RAM_end__];

define symbol size_cstack__             = 0x2000;
define symbol size_heap__               = 0x200;

define block CSTACK    with alignment = 8, size = size_cstack__   { };
define block HEAP      with alignment = 8, size = size_heap__     { };

initialize by copy { readwrite };

place at address mem:intvec_start__ { section .intvec };
place in APP_RAM_region           { readonly };
place in RAM_region               { readwrite, block CSTACK, block HEAP };


sysinit.c:

void SystemInit(void)
{
#if defined(CORE_M3) || defined(CORE_M4)
  unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08;

#if defined(__IAR_SYSTEMS_ICC__)
  extern void *__vector_table;
  #ifdef COPY_SRAM
    unsigned int *pM4MEMMAP = (unsigned int*)0x40043100; //CREG_M4MEMMAP

    *pSCB_VTOR = (unsigned int)&__vector_table;
    *pM4MEMMAP = 0x10000000;
  #else
    *pSCB_VTOR = (unsigned int) &__vector_table;
  #endif
#elif defined(__CODE_RED)
  extern void *g_pfnVectors;

  *pSCB_VTOR = (unsigned int) &g_pfnVectors;
#elif defined(__ARMCC_VERSION)
  extern void *__Vectors;

  *pSCB_VTOR = (unsigned int) &__Vectors;
#endif

#if defined(__FPU_PRESENT) && __FPU_PRESENT == 1
  fpuInit();
#endif

  /* Board specific SystemInit */
  Board_SystemInit();


#endif // defined(CORE_M3) || defined(CORE_M4)
}


The better way to accomplish the SPIFI to SRAM copy is to let the boot ROM do it via a header.  Build for a 0x00000000 vector start, output as a .bin and prepend the header using the HDR\RAW modes controls of DFUSec.exe.  Use JLink.exe to write that modified binary to 0x14000000.  Debug with IAR is still possible via "Debug without Downloading".
0 Kudos

815 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Mon Jun 30 23:36:00 MST 2014
If you want further assistance here, I suggest that you provide details of which toolchain you are actually using and exactly what you are trying to do. For example, if you are using LPCXpresso, then this FAQ may be useful….

http://www.lpcware.com/content/faq/lpcxpresso/placing-specific-functions-ram-blocks

What do you mean by swap-in/swap-out?

Regards,
LPCXpresso Support
0 Kudos

815 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Mon Jun 30 05:39:51 MST 2014
With Keil uVision it is quite easy: just mouse click with the right button on a file in the project explorer and then you can make the setting that it should run e.g. from IRAM1. This affects then all code of this file. The compiler automatically generates the required copy code (resides between system_init and main() ).

With IAR EWARM or LPCXpresso it is more complex, here you need to do the settings in the linker script. You should be able to find some examples for this in the code examples coming along with the tools.

Regards,
NXP Support Team.
0 Kudos

815 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by s.a.manick@gmail.com on Tue Jun 03 07:06:58 MST 2014
Hi,

It would help if you could explain how to set the compiler to run from SRAM by giving an example.

Best Regards,
Manickam.
0 Kudos

815 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Tue Sep 24 06:51:37 MST 2013
With swap-in/swap-out you most likely mean that you relocate code to the internal SRAM and execute it from there. After execution you come back to the SPIFI code execution.
In principle it's simply a copy process from the object code to the SRAM and then you branch to the address where you copied the code to.
But there are also the interrupt vectors. If you don't use IRQs, fine. If yes then your interrupt vector will be cought from the SPIFI and then jump to the ISR which is also in SPIFI.
So depending on what you want to do in the SRAM code you need to relocate more or less.
If you want to have the same piece of code running from SPIFI and from SRAM, then you need to create position independent code.
If you only need to relocate the code4 one time after startup, then I would give this job to the compiler: specify the object which need to run from SPIFI, specify the others which need to run from SRAM and then the compiler/linker will do the rest.
Overall it is a complex but not very difficult thing if you know what I mean ;-)

Regards,
NXP Support.
0 Kudos