SPE Flash Downloading
Command Index
Introduction
In order to remotely download new code to a device the device
must be able to maintain enough of its operation during the downloading
process so as to be able to continue with the downloading.
In practice this means near enough everything of the existing code
must be maintained so to avoid a significant increase in complexity it is
easiest to maintain all the existing code. This means that sufficient
additional memory is needed to hold the entire replacement code.
When we had done flash downloading in our earlier VIU and AlarmCore
68HC11 based products this was achieved by dividing the standard flash
memory into two halves: a low half in the lower portion of the
address space and a high half in the upper portion. The fact that this
limited us to using only half of the available address space was never a
problem. By the time we came to add flash download ability to our SPE we had
already used well over half the address space so a new solution was needed.
The solution we choose was to use a DataFlash chip. This device,
an Atmel ATF45DB041, features SPI serial access and a capacity of over
512KB (actually 540,672 bytes). This has plenty of capacity to support
extending of of logging capability as well as holding a new copy of
program code. Fortunately we had made allowance in our SPE hardware
design for such a chip quite a long time ago. This means that most
existing units could be upgraded on a return-to-base basis if needed.
The next problem was how to swap operating code from the old version
to the new version. Care is needed to ensure that the SPE is not left
in an inoperably state should something go wrong during the swap over
process. With our 68HC11 products we used an Atmel AT29C512 flash chip.
Writing to this chip is done as a whole page write with which includes
erase. So when we received the new copy of the vector table page we
would do a CRC calculation over the new code and if it matched the value
in the vector table page and a signature string in this same page matched
then we would write the new page. Being a single step whole page erase
and write there was little room for a half pie operation leaving the unit
inoperable.
The SPE is a different story altogether. Erase and write are seperate
operations. Writes are on a word-by-word basis. The whole operating code
has to be erased and replaced to do the swap, not just the vector table.
The solution was going to need to be more complex that what we had got
away with before. So what we did was to set aside a small region (1KB)
of memory that would not be changed. This region would contain all the
interrupt vectors and the code to check and replace the main code. A
secondary vector table would then exist in the replaceable code and the
fixed code would call these vectors. This adds to the interrupt latency
time so the fixed code was written in assembler so that only a single
branch instruction would be needed. This adds three clock cycles. For
the vectored timer interrupts the vector resolution code was included
in the assembler and additional vectors added to the downloaded vector
table. This reduced the latency compared to the C version that we had
before. For the reset vector we now call a code check function first.
This checks the validity of the downloaded code that's in the MsP430
and if this is good then jumps to its interrupt vector. If the MSP430
code fails the check then the code check function looks to the DataFlash
for a good copy of code. If it finds one there then it proceeds to copy
it into the MSP430.
Another issue with code updating is the parameter settings. With the
68HC11 products we used a fixed structure for the parameters. Any changes
to the parameter definitions had to be backward compatible. This can make
things a bit difficult when you want top extend the storage space used by
a parameter. To get around this problem with the SPE we instead opted to
write all the settings to the dataFlash in text form, as they get reported
by the ^HSAS command, and then read them in as commands once the new code
is started.
How to do a Flash Update
First thing is to erase the memory space in the DataFlash chip that we
need to hold the new version of code. This is done with the command
AT^HFES. This command takes no parameters
and erases sector two of the DataFlash chip. The DataFlash chip is arranged
in six Sectors. Sector zero is 2K and we use this for the text version
of the parameter settings. Sector one is 62K and we don't have anything
in mind for this at the moment. Sector two is 64K and this is the sector
we use for our flash code download. Sectors three, four and five are each
128K and we intend to use these for extended log records. (I should mention
here that the DataFlash chip is arranged in pages with each page being
264 bytes. The 264 byte page size is intended to allow 256 bytes for data
and an extra eight bytes for additional information related to the data.
When I say, for example, 64K I really mean 256 pages so this is really
67,584 bytes. For our code download we only use the 256 bytes so that
addressing is kept simple. For the parameter setting we use all 264 bytes
so that we can read it back using the continuous array read feature.)
So now that we have a blank sector to store the download we can start
writing pages. We use the AT^HFWP command and a
typical example might look like this (no line breaks in real life):
AT^HFWP310,8tAKADIA4sIyAPLCMQDy8PEAMwDy0jUA8tI2APLCNwDywj
UAMEGwEgA2fEDXAJIS1v+SEtr/fPPy0jUAMEEKEgsSCBIITApOG0EIALA
SADZ8QFMAkhLW/wxIsBKizpIS1v8MSExcfPOSEtb/TEOSEtb/8tI1ALAS
JjY8sIAA+yfywjUAfECEAJIS1v9MQ5IS1v8MSowQfPOSEtb/evNMSpIS1
v8KQxqRCgAHLA1LDVpsTZIS1v8aU/Y/8tI1APLCNQB8QIMAkhLW/wxIsB
KizpIS1v9IWHjzTEiSEtb/TEOSEtb/8tI1ALASJjY8sIAA+ycMQzhBO0E
6QTBBChILEv
A user could type in a list of commands like this but we'd think them
a bit crazy if they did. We use a program to convert the flash image into
a list of such commands. Looking at the command you will see that there
are two parameters. This first is the page number (310 in this case,
though g20 and ITU code versions generally start with page 278).
Page numbers are relative to the start of the chip so that the command
can be used over the whole of the chip and not just sector two. This page
number in this case is 310. This means that it's the 54th page of sector
two and so corresponds to the address range 0x3600-0x36FF in the MSP430.
The second parameter is the data encoded in base-64 fashion as used by the
MIME email format. If there are fewer characters than are needed to
generate the full 264 bytes then any unspecified bits are assumed to be
set (the erased state).
The ^HFWP command has counterparts in the AT^HFRP
command and its variants AT^HFRPA and
AT^HFRPX. These commands can be used to read back
a flash page in base-64, ASCII and Hex formats respectively. These commands
are intended primarly for debugging purposes.
Having written all flash code pages to the DataFlash chip if all is well
the update command, AT^HFUD, can be issued. The
update command takes a single parameter which is a string that must match
the signature string in the copy of code that has just been downloaded.
A typical example might look like:
AT^HFUD"(c) Copyright Harvest Electronics"
Error responses might look like:
^HFUD: 1,"Signature mismatch"
or
^HFUD: 2,"Bad code image"
A good response will cause the SPE to reset (starting the new code)
and no response string will be returned. You might want to have RST among
your call options so the the SPE will call in after the restart.
A "Bad code image" can result from any flash page write getting lost
somehow. To help sort out such problems we have two extra commands:
AT^HFBC and AT^HFPC.
The ^HFBC command takes no parameters and returns a list of 32 block CRCs
for blocks in sector two of the DataFlash. A block, by the way,
is eight pages or 2K. The block CRCs can be checked and for any that
are incorrect a ^HFPC command can be issued with the block number as a
parameter. This will then return the page CRCs of the eight pages
within the specified block. A new ^HFWP command can then be issued to
rewrite the errored page. The ^HFWP command includes a page erase so a
corrupt page can be corrected without having to do a ^HFES command and
starting the download again.
|