HCS08 firmware update on CAN

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HCS08 firmware update on CAN

15,891 Views
Simone
Contributor II

Hello everyone!
I'm working on the new DZ60 uC, and what I'm searching is a way to remotely update its firmware.
I've made some research on the net and in the forum, and I've found something interesting about it (AN2140, TN228, TN235; I attached them for your convenience).
From what I know at the moment, it's possible to run a routine in Ram in order to erase or reprogram the flash, but my ideas are still a little confused.
What I have in mind is to update the firmware (i.e. reprogram it in part or entirely), "downloading" the new firmware by CAN.
I have a system composed by many different parts connected on a CAN bus; the goal is to permit the update of any part simply plugging an SD card, containing the firmware files, into the motherboard. The motherboard reads the data on the SD and transfer them to the appropriate target device on the CAN bus. At this point the target should be able to read the data and auto-update its firmware... and that's the crucial point!

-   If I complete the transfer of the new firmware, copy it in ram, and then erase/reprogram the flash I don't need to move in Ram the code to use the Mscan and to manage the interrupts on CAN receive, but I think that probably the entire firmware won't fit into the Ram.
-   If I move in Ram the code to manage Mscan I won't have the last problem since the firmware is received and written 8 bytes at the time, but there is the backside that if for some reason there is a problem on the CAN transmission, the process will stop and my device will be lost.

Do you have any idea or suggestion?

Simone

 

TN235.pdf

AN2140.pdf

TN228.pdf

Message Edited by t.dowe on 2009-09-24 03:06 PM
Labels (1)
30 Replies

1,607 Views
bigmac
Specialist III
Hello Simone,
 
Firstly, I should say that I am not familiar with CAN and its operational and timing limitations.  Others will need to advise on these issues.
 


Simone wrote:
The bootloader will reside in protected flash, so it will be always available. On startup the bootloader is called, and it checks the control sector bytes; if they are all 0xFF it starts the "main" routine jumping at the right location in non-protected flash, otherwise it waits for CAN messages to download data (maybe sending signals on CAN bus of his state . . . On the reception of the update request on CAN bus the program writes 0xFF to control sector bytes and then reset.


Your understanding is basically correct.  You might arrange that one of the bytes in the control sector is a "programming complete" flag.  This way, the reset procedure would need to test only a single byte to determine if bootloader mode should be entered.  Perhaps you should also allow for a CAN message (within normal program operation) to cause entry to bootloader mode, so that the master can initiate the reprogramming process.  To indicate a programmed sector, I might choose a value of 0x00.
 


. . .  in which way I enter the bootloader routine during normal operation? Can I reset the device with a CAN message?
In order to prevent the "master" sending messages when the "slave" is writing to flash, would it be better to enable a sort of protocol, in which the master send the first message with the update request, then the slave (now in boot mode) asks the download parameters (such as number of sector to write etc...), and subsequently asks for single sector trasfer?

Allocate a CAN message for entry to bootloader, as mentioned above.  Yes, you will need a protocol that is compatible with the operation of CAN.  The master should have total control over the reprogramming process, including the current sector to be erased and programmed.  It should also be able to determine which sectors have already been programmed, and those sectors that still  need to be programmed, by reading the relevant bytes from the control sector.  Only the master "knows" how many sectors will be occupied by the new firmware.
 
This way the master can ensure that all sectors have been correctly programmed prior to finally writing the "programming complete" byte.
 
Regards,
Mac
 
0 Kudos
Reply

1,607 Views
Lundin
Senior Contributor IV

Correct me if I'm wrong, but I believe that the DZ60 has just got 1 single bank of flash? If so, then the bootloader cannot reside in flash, since you can't execute code from a flash bank while it is being programmed.

0 Kudos
Reply

1,607 Views
bigmac
Specialist III

Hello Lundin,

Actually, most of the bootloader code can reside in flash.  Only a small routine is required to execute while access to the flash array is inhibited, during the execution of each flash command.  This routine would usually be located in RAM, maybe by being placed on the stack (doonstack method).

However, my understanding is that the EEPROM in the DZ60 is a separate array from the main program flash array.  It would seem that the routine could be placed within the EEPROM array, instead of using RAM.  Of course, the EEPROM based code cannot be used for the programming of EEPROM - an equivalent routine would also need to reside in program flash for this purpose.

Regards,

Mac

0 Kudos
Reply

1,607 Views
rocco
Senior Contributor II
An alternative to Mac's "control-sector" technique is to use a firmware checksum.

I don't use CAN, but my bootloader does re-program the flash on devices along an RS485 bus.

What I do in my firmware startup routine is to compute a checksum on the entire flash. I then compare it with a stored checksum in the last two bytes of flash. If the compare fails, I jump straight into the bootstrap firmware. I can also enter the bootstrap firmware by sending a command down the RS485 bus.

When reprogramming a device, the host controller sends the firmware to the device one page at a time, and waits for an ACK that says that the page has been programmed and verified. It sends the new checksum for programming as the final operation. This way, if programming is ever interrupted, the checksum will be incorrect and the bootstrap routine will be entered automatically upon reset.

There are several disadvantages to this approach over Mac's approach. With Mac's technique, if programming is interrupted, the control-sector tells you where to continue programming. This can be a big advantage if communications are poor, since you don't need to start programming from the beginning after each failure, and the job will get done eventually.

Also, checking the control-sector at startup will be fast, whereas computing the checksum for all of flash will not. You can count on the checksum routine adding a bunch of milliseconds to your startup.

An advantage of the checksum is that it is pretty simple to implement (which is why I use it). Another advantage is that the bootstrap will be run automatically upon reset if the flash gets corrupted.
0 Kudos
Reply

1,607 Views
aag
Contributor I

Hello,

 

I'm developing a bootloader using the MC9S08AW16. There are a bootloader, a bootloader_util and a firmware.
The MCU starts in bootloader mode. From the bootloader mode I can enter the bootloader_util using hardware means(button combination) or by sending a command.
If the bootloader is not told to enter the bootloader the bootloader_util, then it launches the firmware if there is one available.
The bootloader_util allows to flash a new firmware using SCI. With a "quit" command, the bootloader_util generates an ILOP that reboots the MCU.
In bootloader, if reset is due to ILOP then the firmware is launched.

The application works fine, but *sometimes* it hangs in bootloader_util and there is no way to make it boot in firmware, even with the "quit" command.
Below is my code simplified:


main:
//a hardware mean to enter the bootloader_util
if (VOLUP_BUT == PUSHED && BRIGHTUP_BUT == PUSHED)
  {
    enter_bootloader_util( );
  }
  else
{            
    // if bootloader cmd is received we enter the bootloader_util code
          wait_bootloader_cmd( );

    //at this point the bootloader cmd was not received

    //if reset was due to ILOP then jump to firmware
    if (ILOP == 1)
    {
        enter_firmware();
    }

    //if reset was due to hw watchdog => do some staff
    if(COP == 1)
    {
        do_some_staff( );
    }

    //normal behavior => try to enter firmware if present
    enter_firmware();
    //else enter bootloader_util
    enter_bootloader_util();
}



Below is my enter_firmware routine:
unsigned char opcode = 0x00;

opcode = *(char *)FIRMWARE_ADDR_START;
if (opcode != 0xFF)
{
    //there is another opcode than NULL opcode
    _asm
        jmp FIRMWARE_ADDR_START
    _endasm;
}


the ILOP is generated as following:
_asm
    lda    #0x8E
    sta    0x70
    jmp     0x70
_endasm;

8E is the STOP opcode that I disabled in the initialization in SOPT register (STOPE = 0)
Thank you in advance for your reactivity.
aag

0 Kudos
Reply

1,607 Views
Simone
Contributor II
A little delay on startup is not critical for my application; however, I'll try both the check methods to see which suits best the job.
If it's not a problem for you, can you show me your bootloader code? I'm not familiar with assembler and I feel a little disoriented.
 
Thanks again,
 
Simone
0 Kudos
Reply

1,606 Views
rocco
Senior Contributor II
Hi Simone,

Here is the code. It is a modified version of AN2295, which uses the serial port. This one is configured for the 908GP32.

If you have any questions, let me know. You may need some macro definitions.
0 Kudos
Reply

1,607 Views
Simone
Contributor II
Hi Rocco!
 
I'm trying to integrate your code into my application; assembler is not so awful as it may seem at the first glance! I'm just messing around with the register porting from GP32 to DZ60.
I need some macro declaration, like you said last time (INIT, INIT_BOOT, RESET); in addition, there is one thing I can't understand: the compiler tells me "Forward reference not allowed" in this instruction "LEN:  equ RAM_+1".
 
Thanks!
Simone
 
0 Kudos
Reply

1,607 Views
bigmac
Specialist III
Hello Simone,
 
It would seem you require a "bootloader" facility that uses CAN for communications, rather than the usual SCI.  The bootloader code would be located in protected flash, and would never be erased.  This means that communications can always be retained.  Of course, this code could never be updated, except by means of BDM.
 
I assume the required process would be to upload enough of the new code to completely fill a sector (768 bytes), to a suitable RAM buffer.  To erase and reprogram each sector, one at a time, would require a small amount of code to be transferred to the stack, and executed from there, at times when the flash memory is inaccessible.  For the sector erase period (20ms), you will need to take into account that communications will be disabled.
 
To allow for loss of communications, and failure of the process, or even loss of power, you would need to devise a scheme where the successfull reprogramming of each sector is flagged in a special control sector.  At the start of the reprogramming procedure, this sector could be the first one erased (but not programmed at this point), to flag that bootloader mode is now required.  Then, as each new sector is erased, reprogrammed, and verified, a byte within the control sector, to represent the newly reprogrammed sector, could then be programmed with a value other than 0xFF.  Only when the last sector for the new firmware is reprogrammed would operation switch to the new code.
 
Regards,
Mac
 
0 Kudos
Reply

1,607 Views
celsoken
Contributor V
I am not a DZ60 expert, neither I have an idea on what kinda hardware you're working with, but I have two suggestions:

- if you can add extra USD, place a small serial flash to hold all your 64Kbyte update, use CAN to fill it, block sanilty check, and your ram to xfer code;

- second option (if you can't do the first one), make a small and permanent CAN based bootloader, protect the area, use part of your ram to xfer sectors (768), use doonstack  or similar functions to erase/program flash. Take good care with your vectors, and validate all blocks of code before transferring control. Durty job, but it works.

Good luck,

Celso
0 Kudos
Reply