Andrea Pastega

Bootloader for DZ60

Discussion created by Andrea Pastega on Oct 29, 2007
Latest reply on Jan 6, 2012 by Steven Chen
Hello.
I'm adding a bootloader to my application, I developed for MC9S08DZ60.
Basically I have some routines on the protected area of the flash, which contains the bootloader and obviuosly the standard IRQ table, and then the user application on the non protected flash. The IRQ table is duplicated, so I need to redirect the event calls when the bootloader is not active, or to pass event control to the bootloader routines when it is enabled by user application for flash uploading.
At the beginning I thought to use the flag FNORED on NVOPT to switch between the vector tables, but then I saw that FOPT is not write-accessible by code, so I decided to use a set of calls to redirect execution to the user application table when bootloader is disabled. I left FNORED to 1, so the bootloader always filters the event calls.
The main table is so defined:

void (* const _BOOT_vect[])() @0xFFC0 = {   /* Interrupt vector table */
         Bootload_ISR_31,                /* Int.no. 31 Vacmp2 (at F9C0)                Unassigned */
         Bootload_ISR_30,                /* Int.no. 30 Vacmp1 (at F9C2)                Unassigned */
         Bootload_ISR_29,                /* Int.no. 29 Vcantx (at F9C4)                Unassigned */
         Bootload_ISR_28,                /* Int.no. 28 Vcanrx (at F9C6)                Unassigned */
         Bootload_ISR_27,                /* Int.no. 27 Vcanerr (at F9C8)               Unassigned */
       ...
         Bootload_ISR_06,                /* Int.no.  6 Vtpm1ch1 (at F9F2)              Unassigned */
         Bootload_ISR_05,                /* Int.no.  5 Vtpm1ch0 (at F9F4)              Unassigned */
         Bootload_ISR_04,                /* Int.no.  4 Vlol (at F9F6)                  Unassigned */
         Bootload_ISR_03,                /* Int.no.  3 Vlvd (at F9F8)                  Unassigned */
         Bootload_ISR_02,                /* Int.no.  2 Virq (at F9FA)                  Unassigned */
         Bootload_ISR_01,                /* Int.no.  1 Vswi (at F9FC)                  Unassigned */
         Bootload_Main          /* Int.no.  0 Vreset (at F9FE)                Reset vector */
 };
 
where the functions are:

void Bootload_ISR_01(void) { asm ("LDHX 0xF9FC; JMP ,X"); };
void Bootload_ISR_02(void) { asm ("LDHX 0xF9FA; JMP ,X"); };
void Bootload_ISR_03(void) { asm ("LDHX 0xF9F8; JMP ,X"); };
void Bootload_ISR_04(void) { asm ("LDHX 0xF9F6; JMP ,X"); };
void Bootload_ISR_05(void) { asm ("LDHX 0xF9F4; JMP ,X"); };
void Bootload_ISR_06(void) { asm ("LDHX 0xF9F2; JMP ,X"); };
void Bootload_ISR_07(void) { asm ("LDHX 0xF9F0; JMP ,X"); };
...
void Bootload_ISR_26(void) { asm ("LDHX 0xF9CA; JMP ,X"); };
void Bootload_ISR_27(void) { asm ("LDHX 0xF9C8; JMP ,X"); };
void Bootload_ISR_28(void) { asm ("LDHX 0xF9C6; JMP ,X"); };
void Bootload_ISR_29(void) { asm ("LDHX 0xF9C4; JMP ,X"); };
void Bootload_ISR_30(void) { asm ("LDHX 0xF9C2; JMP ,X"); };
void Bootload_ISR_31(void) { asm ("LDHX 0xF9C0; JMP ,X"); };

while the user application table is that created by P&E (relocated):

void (* const _vect[])() @0xF9C0 = {   /* Interrupt vector table */
         Cpu_Interrupt,                /* Int.no. 31 Vacmp2 (at F9C0)                Unassigned */
         Cpu_Interrupt,                /* Int.no. 30 Vacmp1 (at F9C2)                Unassigned */
         Cpu_Interrupt,                /* Int.no. 29 Vcantx (at F9C4)                Unassigned */
         Cpu_Interrupt,                /* Int.no. 28 Vcanrx (at F9C6)                Unassigned */
         Cpu_Interrupt,                /* Int.no. 27 Vcanerr (at F9C8)               Unassigned */
       ...
         Cpu_Interrupt,                /* Int.no.  6 Vtpm1ch1 (at F9F2)              Unassigned */
         Cpu_Interrupt,                /* Int.no.  5 Vtpm1ch0 (at F9F4)              Unassigned */
         Cpu_Interrupt,                /* Int.no.  4 Vlol (at F9F6)                  Unassigned */
         Cpu_Interrupt,                /* Int.no.  3 Vlvd (at F9F8)                  Unassigned */
         Cpu_Interrupt,                /* Int.no.  2 Virq (at F9FA)                  Unassigned */
         Cpu_Interrupt,                /* Int.no.  1 Vswi (at F9FC)                  Unassigned */
         _EntryPoint                   /* Int.no.  0 Vreset (at F9FE)                Reset vector */
 };


The execution is propagated correctly to the right user routines, but there's something non working on the return addresses, because after the IRQ calls the execution goes out of the rails.
Where is the error?
Is there a better management possible for this kind of application?
Thanks in advance

Outcomes