EmbeddedRelated.com
Forums

How to generate a LPC program residing in flash that relocates and runs in ram

Started by "c.barbaro" October 12, 2006
Hi to all,

I'm developing a downloader for LPC2138 that loads the application
image file from SPI port instead for serial, as Philips ISP does.
This downloader should be able not only to upgrade the application
program but occasionally to upgrade itself.
To do this, the downloader that resides in lower blocks of flash must
relocate itself and run in ram.

Here is the question: where can I find a sample application (a led
flashing program will be good) that is resident in flash and relocates
in ram before the C main function is invoked?

I suppose that the key is in the startup.s module and in the linker
script files.

I'm developing using Keil uVision3 IDE and the Keil compiler.

Thank you in advance,

Carlo

An Engineer's Guide to the LPC2100 Series

At 13:19 12.10.2006 +0000, you wrote:

>Hi to all,
>
>I'm developing a downloader for LPC2138 that loads the application
>image file from SPI port instead for serial, as Philips ISP does.
>This downloader should be able not only to upgrade the application
>program but occasionally to upgrade itself.
>To do this, the downloader that resides in lower blocks of flash must
>relocate itself and run in ram.
>
>Here is the question: where can I find a sample application (a led
>flashing program will be good) that is resident in flash and relocates
>in ram before the C main function is invoked?
>
>I suppose that the key is in the startup.s module and in the linker
>script files.
>
>I'm developing using Keil uVision3 IDE and the Keil compiler.

I don't have a sample program for you but some hints:

1) All functions which should be placed in RAM must have the __ram keyword,
e.g.
void foo(void) __ram

2) Under LA Locate / User Classes insert e.g. ERAM (0x40000100-0x40006F00)
to define the so-called ERAM

3) You can not use *any* library function, as they are not compile with the
__ram keyword, so you have to rewrite such things like memcpy() with the
__ram keyword

4) Dont' even do e.g.

unsigned int value x, y = 12345;
x = y / 3;

This calles a library function and your program will crash, even when the
function containing the two lines mentioned above is never called (!!!!) -
this is very strange and I can not explain why this happens, but it is a
fact (Version 2.50a)

Much luck!

Regards
Herbert
--- In l..., "c.barbaro" wrote:
>
> Hi to all,
>
> I'm developing a downloader for LPC2138 that loads the application
> image file from SPI port instead for serial, as Philips ISP does.
> This downloader should be able not only to upgrade the application
> program but occasionally to upgrade itself.
> To do this, the downloader that resides in lower blocks of flash
must
> relocate itself and run in ram.
>
> Here is the question: where can I find a sample application (a led
> flashing program will be good) that is resident in flash and
relocates
> in ram before the C main function is invoked?
>
> I suppose that the key is in the startup.s module and in the linker
> script files.
>
> I'm developing using Keil uVision3 IDE and the Keil compiler.
>
> Thank you in advance,
>
> Carlo

Here's how I did it:

Create the loader application as a RAM executable; that means
configuring the linker to put ALL sections in RAM. Note the address
of the RAM sector.
Take note in the link map of the address where the code starts
(usually a symbol called .start or .reset_handler, etc.)
Generate an output file (binary preferred, or S-record or intel hex).
Using any handy shareware utility, convert the binary to a C header
file. This will create a .h (referred to as "YourApp.h") file with
the binary as a giant array of unsigned char. Make sure that the
array is declared const.

Now create a tiny "stub" program as a flash executable. All this
should consist of is #include "YourApp.h", a routine to copy the
contents of the array to the desired RAM location, and some inline
assembly to jump to the start address found above.

The flash executable, when installed and run, will copy the RAM
executable from flash to RAM, then run it.

While involved, the advantage to this method is that you have the
entire C library available; My loader is rather involved, in that it
has to talk to a bitmapped LCD, perform file transfers over the UART,
validate any files received, erase and write to flash, etc., so I
appreciate being able to use lib functions and reuse drivers and
other hunks of code from my "main application" to create the loader.

Another advantage is that since this is a RAM executable, you can
test and debug it easily in RAM; you only build it in to the stub
loader when it's ready.

--Gene
Hi Gene,

Is there a good shareware you can recommend for convert elf files to C
header file?

Thanks

David
Hi Gene,
thank you and other guys of the group for the suggestions on how to
solve my downloader problem.
I followed another method sligthly different:
1) I modified the linker configuration files to generate all my code
in RAM.
2) I observed that although all code,data,const segment were in ram,
the Keil compiler allocates the startup code in flash, starting from
address zero (I not yet investigated this, probably in the startup
assembler code there are directives to do this).
3) I developed a small utility that reads the hex file and changes all
ram addresses to a value that lies in flash (making attention not to
cover the startup code).
4) I modified the startup code, adding a fregment of code that copies
the flash area where my utility relocated the code again back to
original ram address. This cado was added just before the jump
instruction to main.
5) I compiled my program, I filtered the hex file with my utility and
loaded to the target LPC using the Philips flash utility.
6) Et voil the statup code boots, relocates the code in ram and jump
there. Even in this case the C library is fully usable since it is
relocated in ram together the application program.

I hope this help others to develop code running in ram.
Carlo

--- In l..., "reallygene" wrote:
>
> --- In l..., "c.barbaro" wrote:
> >
> > Hi to all,
> >
> > I'm developing a downloader for LPC2138 that loads the application
> > image file from SPI port instead for serial, as Philips ISP does.
> > This downloader should be able not only to upgrade the application
> > program but occasionally to upgrade itself.
> > To do this, the downloader that resides in lower blocks of flash
> must
> > relocate itself and run in ram.
> >
> > Here is the question: where can I find a sample application (a led
> > flashing program will be good) that is resident in flash and
> relocates
> > in ram before the C main function is invoked?
> >
> > I suppose that the key is in the startup.s module and in the linker
> > script files.
> >
> > I'm developing using Keil uVision3 IDE and the Keil compiler.
> >
> > Thank you in advance,
> >
> > Carlo
>
> Here's how I did it:
>
> Create the loader application as a RAM executable; that means
> configuring the linker to put ALL sections in RAM. Note the address
> of the RAM sector.
> Take note in the link map of the address where the code starts
> (usually a symbol called .start or .reset_handler, etc.)
> Generate an output file (binary preferred, or S-record or intel hex).
> Using any handy shareware utility, convert the binary to a C header
> file. This will create a .h (referred to as "YourApp.h") file with
> the binary as a giant array of unsigned char. Make sure that the
> array is declared const.
>
> Now create a tiny "stub" program as a flash executable. All this
> should consist of is #include "YourApp.h", a routine to copy the
> contents of the array to the desired RAM location, and some inline
> assembly to jump to the start address found above.
>
> The flash executable, when installed and run, will copy the RAM
> executable from flash to RAM, then run it.
>
> While involved, the advantage to this method is that you have the
> entire C library available; My loader is rather involved, in that it
> has to talk to a bitmapped LCD, perform file transfers over the UART,
> validate any files received, erase and write to flash, etc., so I
> appreciate being able to use lib functions and reuse drivers and
> other hunks of code from my "main application" to create the loader.
>
> Another advantage is that since this is a RAM executable, you can
> test and debug it easily in RAM; you only build it in to the stub
> loader when it's ready.
>
> --Gene
>