Matthew Peters wrote:
A ram loader would be quite simple to make, realy... the main question on
how to go about making one is will it ever reprogram itself.
If it will, you have to write an extra bit to copy the code to ram, and
execute from there.
yes, with all its drawbacks... what happens if the reprogramming fails?
you end up with an erased flash.
there may be options to avoid that but it involves a litte effort:
place a simple serial protocol handler, the ram flash loader and code
for interrupt vector redirection in the topmost segments. it has to be
the topmost segments as you cant erase the interrupt vectors while
having the security that it can always recover even if flashing is
interrupted.
i'd make a table with the interrupt handlers addresses in a specific
location in flash. e.g. righ below the fixed loader. that way the table
is programmed with the rest of the software, the application.
on startup, that fixed code listens on the serial port if it receives
the reprogramming command. if it does not, it continues with the address
in the redirected int vectors table. otherwise it starts the
reprogramming subprogram.
you can also consider that it automaticaly enters the reprogramming
subprogram when the redirecten ints table is not valid. and otherwise
only through a command of the application. but that last bit has the
problem that, if he application is buggy, it may prevent you from
entering the loader again.
the reprogramming subprogram at least has commands to a) erase the rest
of the flash, keeping the loader in place b) block write command c)
reset cpu (to start the new software later, or to abort)
i'll have to write such a loader at some time for a product too as the
serial lines go trough optocouplers and only the Rx/Tx lines are
wired... but i dont have any code right now.
Now, the code to work with the flash is all the mspgcc includes(though i
haven't accually tried using them myself), so that should make the job
easier... then it's pretty simple to just load from your memory device,
and write to the flash(after erasing the block)...
the loader must not use any library functions unless they are stored in
the protected flash area too and can be copied to the ram... (to put it
simple: avoid them in the loader ;-)
Myself, i would make it always copy it's code to ram, since then there
isn't as much chance of mistakes. I'ld also write a block to copy back the
loader code into flash if it finds that area blank. But that is just my
method.
ony work if you have enough ram... with 512 bytes it may be hard to
write a serial protocol handler, flash writer that fits into the
available space... i'd keep the serial protocol parts in the flash.
never erasing it.
only the flash block programming is copied to the ram (altough its not
required. you can easily program flash while running from the same flash
from an other bank. but with a ram programmer its faster)
for a flash programmer that writes blocks from the ram into the flash,
you can look at the (py)jtag sources. it has assembler bits to do that:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mspgcc/jtag/funclets/
(eraseFlash.S and progFlash.S are interesting for you, you would end
with "ret" instead of "jmp $")
the layout in the memory device should be well thought out and layed
out... hopefully all the code for talking with the memory, and the full
loader, will fit in your devices ram... if it doesn't, one option is to
have your loader in two places in flash while programming... but then you
have to keep both clear of your accual code...
for the above loader i'd layout it something like that:
0xffff intvecs \
0xffe0 end loader } this part is never erased 1kB
0xfc00 begin loader /
0xfbff end application / redirection table 32 Bytes
0xxxxx rest of flash for application
the redirection table has the same order as the real int vector table so
the topmost entry is the application entry point. other entries are
maped 1:1 except maybe the serial rx interrupt, depending on the loader
implementation.
HTH
chris