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
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.
. . . 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?
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.
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
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