Total Units Connected: 2196
 

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.