Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

Execute Code in RAM?

Execute Code in RAM?

2005-03-10 by ateichtmann

Hi,

for an in-system update of the firmware i have the following idea:
1. store the new firmware in an external serial flash
2. allocate memory in RAM with malloc() for the update function
3. copy update-function from ROM to RAM
4. call update-function in RAM
5. update-function copies firmware from external serial flash to 
internal flash with IAP commands

My question is, how code can be executed in RAM.
How can i call a function in RAM?
Thanks for all hints.

Regards
Arvid

Re: [lpc2000] Execute Code in RAM?

2005-03-10 by 42Bastian Schick

>
> My question is, how code can be executed in RAM.
> How can i call a function in RAM?

Simply:

void (*myfunc)();

myfunc = (void (*)())0x40000000;

myfunc();

-- 
42Bastian Schick

Re: Execute Code in RAM?

2005-03-10 by ateichtmann

> > My question is, how code can be executed in RAM.
> > How can i call a function in RAM?
> 
> Simply:
> void (*myfunc)();
> myfunc = (void (*)())0x40000000;
> myfunc();

Sorry, does not work...
The compiler does not like the second line.
My problem is, that i don't know how to declare a function, whose 
address can be changed during runtime.
How is the syntax of a working code?

Regards
Arvid

RE: [lpc2000] Re: Execute Code in RAM?

2005-03-10 by Messal, Art

Depending on your compiler/linker you can specify a function

as a "ram function".  Look for a preprocessor directive for this

and be sure to properly configure the linker - it must know where

in flash to store the routine and where to copy it into RAM...

 

 

   -Art-

 

  _____  
Show quoted textHide quoted text
From: ateichtmann [mailto:arvid_teichtmann@...] 
Sent: Thursday, March 10, 2005 6:15 AM
To: lpc2000@yahoogroups.com
Subject: [lpc2000] Re: Execute Code in RAM?

 


> > My question is, how code can be executed in RAM.
> > How can i call a function in RAM?
> 
> Simply:
> void (*myfunc)();
> myfunc = (void (*)())0x40000000;
> myfunc();

Sorry, does not work...
The compiler does not like the second line.
My problem is, that i don't know how to declare a function, whose 
address can be changed during runtime.
How is the syntax of a working code?

Regards
Arvid










Yahoo! Groups Sponsor



ADVERTISEMENT
 <http://us.ard.yahoo.com/SIG=129lhicrf/M=298184.6018725.7038619.3001176/D=groups/S=1706554205:HM/EXP=1110547038/A=2593423/R=0/SIG=11el9gslf/*http:/www.netflix.com/Default?mqso=60190075> click here


  <http://us.adserver.yahoo.com/l?M=298184.6018725.7038619.3001176/D=groups/S=:HM/A=2593423/rand=411689151> 

 

  _____  

Yahoo! Groups Links

*	To visit your group on the web, go to:
http://groups.yahoo.com/group/lpc2000/ <http://groups.yahoo.com/group/lpc2000/> 
  
*	To unsubscribe from this group, send an email to:
lpc2000-unsubscribe@yahoogroups.com <mailto:lpc2000-unsubscribe@yahoogroups.com?subject=Unsubscribe> 
  
*	Your use of Yahoo! Groups is subject to the Yahoo! <http://docs.yahoo.com/info/terms/>  Terms of Service. 



[Non-text portions of this message have been removed]

Re: [lpc2000] Re: Execute Code in RAM?

2005-03-11 by 42Bastian Schick

Arvid

> My problem is, that i don't know how to declare a function, whose
> address can be changed during runtime.
> How is the syntax of a working code?

void wrapper(unsigned long addr)
{
   void (*func)();

   func = (void (*)())addr;
   func();
}

For the function itself, make sure to link it for its execution address

  .flasher 0x40000040 : AT(ADDR(.rodata)+SIZEOF(.rodata)
  {
	flasher.o(.text)
  }

This will place the code of flasher in Flash, but linked for 0x40000040.


-- 
42Bastian Schick

Re: [lpc2000] Execute Code in RAM?

2005-03-11 by Michael Anburaj

Arvid,

As somebody said it depends on the tool-chain.

Method 1: Different Load & execute address (liner
script method)

ARM tools (ADS or SDT):

Create a scatter map file much like the following:

flash 0x00000000 0x00020000
{
	TEXT +0
	{
		*(+RO)
	}

	LOADTEXT 0x40001000
	{
		flashlib.o
	}
}

Where LOADTEXT is the section which will contain the
flashlib.o object (The object which you want to run
out of RAM). Now that in the link step use this
scatter map & the linker would link this object
(flashlib.o) for RAM address 0x40001000, but load it
in flash following the .text (or) RO regions of other
objects when creating the executable
(elf/axf/bin/hex/srec).

And the linker (ADS or SDT) would provide the
following run-time variables. And it is the
responsibility of the run-time code/writer to move the
code from ROM to RAM:

Load$$LOADTEXT$$Base        -- Address in ROM
Image$$LOADTEXT$$Base       -- Address in RAM
Image$$LOADTEXT$$Length     -- Length to be copied

These variables should be used to copy the code from
flash to RM at run-time (done either at the startup
assembly code or in C code initializing this library).

And you call the function just like any other
function. And the call will be made to the copied
location in RAM

myflashlibfunction(); /* this should call the function
in RAM */

The same idea can be used in GCC using linker scripts.


Method 2: PIC (position independent code)

1. compile this particular code (which needs to run
out of RAM) as PIC -- check the right flags in the
compiler manual.

2. Then just as you explained, do the things to move
the code to RAM. Since, its PIC code, it can run from
any location.

Call the function as someone explained -- using
function pointers.

Cheers,
-Mike.

--- ateichtmann <arvid_teichtmann@...> wrote:
> 
> Hi,
> 
> for an in-system update of the firmware i have the
> following idea:
> 1. store the new firmware in an external serial
> flash
> 2. allocate memory in RAM with malloc() for the
> update function
> 3. copy update-function from ROM to RAM
> 4. call update-function in RAM
> 5. update-function copies firmware from external
> serial flash to 
> internal flash with IAP commands
> 
> My question is, how code can be executed in RAM.
> How can i call a function in RAM?
> Thanks for all hints.
> 
> Regards
> Arvid
> 
> 
> 
> 
> 


		
__________________________________ 
Do you Yahoo!? 
Yahoo! Small Business - Try our new resources site!
http://smallbusiness.yahoo.com/resources/

Re: [lpc2000] Execute Code in RAM?

2005-03-11 by Michael Anburaj

I forgot to mention few important points in my
previous email.

1. I favor Method-1. It had less overhead & also PIC
objects would run slightly slower & would take-up more
memory. Method-2 is useful in case of run-time loaded
module, OSes like Linux do that (Where modules get
loaded at random locations).
2. Method-1 (RISC architecture related issue): RISC
architectures (for instance ARM) have a limitation on
the Branching ability (The address range is
restricted). ARM7 can only branch within + or - 32MB.
If the Flash & RAM are more than 32MB apart then, the
function call cannot be made just like another normal
function (linker would complain about the long
branch). In such a case the call should be made using
function pointers.

Cheers,
-Mike.

--- Michael Anburaj <embeddedeng@...> wrote:
> Arvid,
> 
> As somebody said it depends on the tool-chain.
> 
> Method 1: Different Load & execute address (liner
> script method)
> 
> ARM tools (ADS or SDT):
> 
> Create a scatter map file much like the following:
> 
> flash 0x00000000 0x00020000
> {
> 	TEXT +0
> 	{
> 		*(+RO)
> 	}
> 
> 	LOADTEXT 0x40001000
> 	{
> 		flashlib.o
> 	}
> }
> 
> Where LOADTEXT is the section which will contain the
> flashlib.o object (The object which you want to run
> out of RAM). Now that in the link step use this
> scatter map & the linker would link this object
> (flashlib.o) for RAM address 0x40001000, but load it
> in flash following the .text (or) RO regions of
> other
> objects when creating the executable
> (elf/axf/bin/hex/srec).
> 
> And the linker (ADS or SDT) would provide the
> following run-time variables. And it is the
> responsibility of the run-time code/writer to move
> the
> code from ROM to RAM:
> 
> Load$$LOADTEXT$$Base        -- Address in ROM
> Image$$LOADTEXT$$Base       -- Address in RAM
> Image$$LOADTEXT$$Length     -- Length to be copied
> 
> These variables should be used to copy the code from
> flash to RM at run-time (done either at the startup
> assembly code or in C code initializing this
> library).
> 
> And you call the function just like any other
> function. And the call will be made to the copied
> location in RAM
> 
> myflashlibfunction(); /* this should call the
> function
> in RAM */
> 
> The same idea can be used in GCC using linker
> scripts.
> 
> 
> Method 2: PIC (position independent code)
> 
> 1. compile this particular code (which needs to run
> out of RAM) as PIC -- check the right flags in the
> compiler manual.
> 
> 2. Then just as you explained, do the things to move
> the code to RAM. Since, its PIC code, it can run
> from
> any location.
> 
> Call the function as someone explained -- using
> function pointers.
> 
> Cheers,
> -Mike.
> 
> --- ateichtmann <arvid_teichtmann@...> wrote:
> > 
> > Hi,
> > 
> > for an in-system update of the firmware i have the
> > following idea:
> > 1. store the new firmware in an external serial
> > flash
> > 2. allocate memory in RAM with malloc() for the
> > update function
> > 3. copy update-function from ROM to RAM
> > 4. call update-function in RAM
> > 5. update-function copies firmware from external
> > serial flash to 
> > internal flash with IAP commands
> > 
> > My question is, how code can be executed in RAM.
> > How can i call a function in RAM?
> > Thanks for all hints.
> > 
> > Regards
> > Arvid
> > 
> > 
> > 
> > 
> > 
> 
> 
> 		
> __________________________________ 
> Do you Yahoo!? 
> Yahoo! Small Business - Try our new resources site!
> http://smallbusiness.yahoo.com/resources/ 
> 

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com

Re: [lpc2000] Execute Code in RAM?

2005-03-11 by Michael Johnson

Hi Arvid,

To do this with CrossWorks (which I presume you are using) you'll need 
to put the overlay functions in their own section. This can be done 
using the GCC section attribute on each function

int overlayfn(int) __attribute__ ((section("overlay")));

int overlayfn(int x)
{
  return x+1;
}

or alternatively you can use the "Section Options | Code Section Name" 
property to put all functions from a compilation unit into a named section.

You then need to modify the section_placement file.

Right click on the "flash_placement.xml" in the project explorer and 
select "Import" to take a local copy of the section_placement file.

Double click on the "flash_placement.xml" file and using the editor add 
a new section into the "FLASH" memory segment called (for example) 
"overlay".

Change the "Load" property of the section to be "Yes" and change the 
"Section To Run In" to be (for example) "overlay_run".

In the "SRAM" memory segment create a section called (for example) 
"overlay_run".

Save the file TWICE - bug in the section_placement editor requires this. 

The file should look like this

<!DOCTYPE Linker_Placement_File>
<Root name="Flash Section Placement" >
  <MemorySegment name="FLASH" >
    <ProgramSection load="Yes" inputsections="*(.vectors .vectors.*)" 
name=".vectors" />
    <ProgramSection alignment="4" load="Yes" inputsections="*(.init 
.init.*)" name=".init" />
    <ProgramSection alignment="4" load="No" name=".text_load" />
    <ProgramSection alignment="4" load="Yes" inputsections="*(.text 
.text.* .glue_7t .glue_7 .gnu.linkonce.t.*)" name=".text" />
    <ProgramSection alignment="4" load="Yes" inputsections="KEEP 
(*(SORT(.dtors.*))) KEEP (*(.dtors))" name=".dtors" />
    <ProgramSection alignment="4" load="Yes" inputsections="KEEP 
(*(SORT(.ctors.*))) KEEP (*(.ctors))" name=".ctors" />
    <ProgramSection alignment="4" load="Yes" inputsections="*(.rodata 
.rodata.* .gnu.linkonce.r.*)" name=".rodata" />
    <ProgramSection alignment="4" load="Yes" runin=".fast_run" 
inputsections="*(.fast .fast.*)" name=".fast" />
    <ProgramSection alignment="4" load="Yes" runin=".data_run" 
inputsections="*(.data .data.* .gnu.linkonce.d.*)" name=".data" />
    <ProgramSection load="Yes" runin="overlay_run" name="overlay" />
  </MemorySegment>
  <MemorySegment name="External SRAM;SRAM;SDRAM;DRAM" >
    <ProgramSection alignment="4" load="No" name=".data_run" />
    <ProgramSection alignment="4" load="No" inputsections="*(.bss .bss.* 
.gnu.linkonce.b.*) *(COMMON)" name=".bss" />
    <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" 
name=".heap" />
    <ProgramSection alignment="4" size="__STACKSIZE__" load="No" 
name=".stack" />
    <ProgramSection alignment="4" size="__STACKSIZE_IRQ__" load="No" 
name=".stack_irq" />
    <ProgramSection alignment="4" size="__STACKSIZE_FIQ__" load="No" 
name=".stack_fiq" />
    <ProgramSection alignment="4" size="__STACKSIZE_SVC__" load="No" 
name=".stack_svc" />
    <ProgramSection alignment="4" size="__STACKSIZE_ABT__" load="No" 
name=".stack_abt" />
    <ProgramSection alignment="4" size="__STACKSIZE_UND__" load="No" 
name=".stack_und" />
    <ProgramSection name="overlay_run" />
  </MemorySegment>
  <MemorySegment name="Internal SRAM;SRAM;SDRAM;DRAM" >
    <ProgramSection size="0x3C" load="No" name=".vectors_ram" />
    <ProgramSection alignment="4" load="No" name=".fast_run" />
  </MemorySegment>
</Root>

you can use "Edit As.. Text to verify.

Now the overlay function must be copied (at some point) using the 
following code

extern unsigned __overlay_start__, __overlay_end__, __overlay_load_start__;

{
 .....
  memcpy(&__overlay_start__, &__overlay_load_start__, ((unsigned 
char*)&__overlay_end__)-((unsigned char *)&__overlay_start__));
 .....
}

The symbols are linker generated symbols (they aren't in memory 
locations) hence the odd use of & to get their value.

Now you can call the functions as normal.

I can send you a zipped example of this if you need it.

Regards
Michael
Show quoted textHide quoted text
>Hi,
>
>for an in-system update of the firmware i have the following idea:
>1. store the new firmware in an external serial flash
>2. allocate memory in RAM with malloc() for the update function
>3. copy update-function from ROM to RAM
>4. call update-function in RAM
>5. update-function copies firmware from external serial flash to 
>internal flash with IAP commands
>
>My question is, how code can be executed in RAM.
>How can i call a function in RAM?
>Thanks for all hints.
>
>Regards
>Arvid
>
>
>
>
>
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>  
>

Re: Execute Code in RAM?

2005-03-11 by zs_gaspar

Some mounth ago we do same things. We use an Atmel AT91M55800A and an
external flash wich don't have busy pin. When i program the flash it
hangs up, so i have to run flash write code from ram.
We used the easiest way, copy all the functions/need run in ram/ from
flash to ram, make new ponter to it, and call the new function to
write flash.

the code:
void (* flash_write) (uint32, uint8);

__arm
void flash_write_(uint32 addr, uint8 data) {
  flash_raw_write(0x555,0xF0);//RESET  
  flash_specstart_seq();
  flash_raw_write(0x555,0x00A0);
  flash_raw_write(addr,data);
  flash_datapoll();
}

void copy_fv_init(void *init) {
  to=(uint32*)init;
}

__arm
void* copy_fv(void *from_addr,int wordcount) {
   int i;  
   //uint16 *from=(uint16*)(((uint8*)from_addr)-1);
   uint32 *from=(uint32*)(((uint32*)from_addr));
   void *start=(void *)to;
   for (i=0; i<wordcount; i++) {
      *to=*from;
      to++,from++;
   }
   return start;
} 
...
flash_write=(void (*)(uint32,uint8))copy_fv((void*)&flash_write_,120);
...

copy_fv_init sets the start addr. where the function will be placed.
copy_fv  copy the function, with 120word/it can be determine
exactly,but it won't need for us/

a call:

flash_write(FLASH_FAT_BASE+r_addr,data);

It works fine! But we buy a flash that have busy output, and connect
it to externel wait pin of the ARM, so we don't have to run in ram
when writeing flash.
Good Luck!

OKEB
from HUNGARY

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.