Bootloader must be designed to be very reliable. In other word, bootloader is an unsung hero carrying out its job when necessary. It shouldn’t be replaced or destroyed at anytime. However, if you understand how the bootloader is implemented in a micro-controller, you will know it’s nothing different from other pieces of your custom application code — just some binaries stored in the flash. So it is possible that they can be erased and overwritten. A well designed bootloader would avoid self-destruction from most mistake. However, hardware failure couldn’t be planned and eliminated. Your bootloader is under risk if no protecction is in force against those exception. Worst case scenario, page 0 of your device’s flash is erased and for some reason (most likely, IO error or power surge), the most critical row 0 of this page couldn’t be correctly re-programmed. Your micro-controller will end up not being ablt to jump to the starting address of bootloader next time when it is powered on. Instead, the chip will hang up itself right after power-on because it has no idea of where to jump to according to the flash’s row 0 of flash 0. If you don’t quite understand why row 0 of page 0 is so important for bootloader design, and why this critial line of data must be rewritten every time, please refer to my first post of this series.
A roll-back strategy is introduced here to save a bootloader from losing its GOTO-RESET instruction. A bootLoader overwrite flag is created and set to 0 on initializtion. The flag is set to 1 right after page 0 is erased, indicating that roll-back might be needed if following re-programming of this page couldn’t be correctly performed. The flag is only set back to 0 after row 0 of page 0 has been loaded with new jumping instructions, indicating that roll-back is no longer needed. In order to retain the critical GOTO-RESET data, a temporary buffer is created to store it before page 0 is erased:
.bss bt_Addr:.space 6 ; Two goto instructions(6 bytes) for jumping back to ; bootloader's starting address: ; Two goto instructions come as the first 6 bytes of row 0 of page 0
This is how I implemented the roll-back mechanism. I am explaining inline. You could end up have different style of coding
Roll_Bk: ; Load write latch mov #0xFA, W0 mov W0, TBLPAG ; Buffer bt_Addr has been loaded with GOTO-RESET's content when page 0 ; is erased. mov #bt_Addr, W1 tblwth.b [W1++], [W0] tblwtl.b [W1++], [W0++] tblwtl.b [W1++], [W0++] tblwth.b [W1++], [W0] tblwtl.b [W1++], [W0++] tblwtl.b [W1], [W0] ; Programming two instructions that is stored at W0(which is 0)at address 0(goto) ; Load address mov #0, W0 ; W0 is 0, which is the starting address of GOTO-RESET instructions ; in the flash. It is located at the very beginning of the flash. mov W0, NVMADRU mov W0, NVMADR ; Setup NVMCON for word programming mov #0x4001, W0 rcall Write return