This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR2033: Custom bootloader

Part Number: MSP430FR2033
Other Parts Discussed in Thread: MSP430F5529,

I am trying to create a custom boot loader (not using the BSL or MSPFRBOOT) to be able to update the main application whilst receiving data. On start up and on reset the processor should enter the boot loader to check to see if any updates are required.

The update will be sent over I2C from an MSP430F5529 (Master) to the MSP430FR2033 (Slave) whilst the MSP430FR2033 is in the boot loader application. The boot loader is not using the BSL, it is it's own application in main memory.

  1. I have read that because the MSP430FR2033 is using FRAM and does not have a minimum erase size (and is treated like ram), it does not need proxy vector table, but in the MSP430FRBOOT code examples they do have proxy vector tables. Why does it not require a proxy vector table if the linkers contain the same addresses for the hardware interrupts? Does each application reconfigure the HW Vector Table in the int00 interrupt at boot? Or do I need a proxy vector table?.
  2. Our design is to have the HW Reset Vector always jump to the boot interrupt of the boot loader. This is so the boot loader can check if the main application needs to update on start up, and if not, jump to the main application. We jump to main by having a jump instruction to the int00 routine of the main. We jump to the boot loader from the main application by doing a brownout reset. The brownout reset works, however it doesn't seem to jump to the boot loader and we are not sure why.
  3. What flash options should we be using for each application? Currently we flash in the boot loader using a full erase and program. Then we flash in the application by doing a differential download on the main application. We immediately lose debug control when we do this because the reset vector goes into the boot loader. Is this the correct way to flash these two applications onto the same processor?

This is the boot loader linker:

MEMORY
{
    SFR                     : origin = 0x0000, length = 0x0010
    PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
    PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
    RESET_VECTOR			: origin = 0x1900, length = 0x0100
    RAM                     : origin = 0x2000, length = 0x0800
    FRAM					: origin = 0xF400, length = 0x0B80
    JTAGSIGNATURE           : origin = 0xFF80, length = 0x0004, fill = 0xFFFF
    BSLSIGNATURE            : origin = 0xFF84, length = 0x0004, fill = 0xFFFF
    INT00                   : origin = 0xFF88, length = 0x0002
    INT01                   : origin = 0xFF8A, length = 0x0002
    INT02                   : origin = 0xFF8C, length = 0x0002
    INT03                   : origin = 0xFF8E, length = 0x0002
    INT04                   : origin = 0xFF90, length = 0x0002
    INT05                   : origin = 0xFF92, length = 0x0002
    INT06                   : origin = 0xFF94, length = 0x0002
    INT07                   : origin = 0xFF96, length = 0x0002
    INT08                   : origin = 0xFF98, length = 0x0002
    INT09                   : origin = 0xFF9A, length = 0x0002
    INT10                   : origin = 0xFF9C, length = 0x0002
    INT11                   : origin = 0xFF9E, length = 0x0002
    INT12                   : origin = 0xFFA0, length = 0x0002
    INT13                   : origin = 0xFFA2, length = 0x0002
    INT14                   : origin = 0xFFA4, length = 0x0002
    INT15                   : origin = 0xFFA6, length = 0x0002
    INT16                   : origin = 0xFFA8, length = 0x0002
    INT17                   : origin = 0xFFAA, length = 0x0002
    INT18                   : origin = 0xFFAC, length = 0x0002
    INT19                   : origin = 0xFFAE, length = 0x0002
    INT20                   : origin = 0xFFB0, length = 0x0002
    INT21                   : origin = 0xFFB2, length = 0x0002
    INT22                   : origin = 0xFFB4, length = 0x0002
    INT23                   : origin = 0xFFB6, length = 0x0002
    INT24                   : origin = 0xFFB8, length = 0x0002
    INT25                   : origin = 0xFFBA, length = 0x0002
    INT26                   : origin = 0xFFBC, length = 0x0002
    INT27                   : origin = 0xFFBE, length = 0x0002
    INT28                   : origin = 0xFFC0, length = 0x0002
    INT29                   : origin = 0xFFC2, length = 0x0002
    INT30                   : origin = 0xFFC4, length = 0x0002
    INT31                   : origin = 0xFFC6, length = 0x0002
    INT32                   : origin = 0xFFC8, length = 0x0002
    INT33                   : origin = 0xFFCA, length = 0x0002
    INT34                   : origin = 0xFFCC, length = 0x0002
    INT35                   : origin = 0xFFCE, length = 0x0002
    INT36                   : origin = 0xFFD0, length = 0x0002
    INT37                   : origin = 0xFFD2, length = 0x0002
    INT38                   : origin = 0xFFD4, length = 0x0002
    INT39                   : origin = 0xFFD6, length = 0x0002
    INT40                   : origin = 0xFFD8, length = 0x0002
    INT41                   : origin = 0xFFDA, length = 0x0002
    INT42                   : origin = 0xFFDC, length = 0x0002
    INT43                   : origin = 0xFFDE, length = 0x0002
    INT44                   : origin = 0xFFE0, length = 0x0002
    INT45                   : origin = 0xFFE2, length = 0x0002
    INT46                   : origin = 0xFFE4, length = 0x0002
    INT47                   : origin = 0xFFE6, length = 0x0002
    INT48                   : origin = 0xFFE8, length = 0x0002
    INT49                   : origin = 0xFFEA, length = 0x0002
    INT50                   : origin = 0xFFEC, length = 0x0002
    INT51                   : origin = 0xFFEE, length = 0x0002
    INT52                   : origin = 0xFFF0, length = 0x0002
    INT53                   : origin = 0xFFF2, length = 0x0002
    INT54                   : origin = 0xFFF4, length = 0x0002
    INT55                   : origin = 0xFFF6, length = 0x0002
    INT56                   : origin = 0xFFF8, length = 0x0002
    INT57                   : origin = 0xFFFA, length = 0x0002
    INT58                   : origin = 0xFFFC, length = 0x0002
    RESET                   : origin = 0xFFFE, length = 0x0002
}

/****************************************************************************/
/* Specify the sections allocation into memory                              */
/****************************************************************************/

SECTIONS
{
    GROUP(ALL_FRAM)
    {
       GROUP(READ_WRITE_MEMORY)
       {
          .TI.persistent : {}                /* For #pragma persistent            */
       }

       GROUP(READ_ONLY_MEMORY)
       {
          .cinit      : {}                   /* Initialization tables             */
          .pinit      : {}                   /* C++ constructor tables            */
          .binit      : {}                   /* Boot-time Initialization tables   */
          .init_array : {}                   /* C++ constructor tables            */
          .mspabi.exidx : {}                 /* C++ constructor tables            */
          .mspabi.extab : {}                 /* C++ constructor tables            */
          .const      : {}                   /* Constant data                     */
       }

       GROUP(EXECUTABLE_MEMORY)
       {
          .text       : {}                   /* Code                              */

       }
    } > FRAM

#ifdef __TI_COMPILER_VERSION__
  #if __TI_COMPILER_VERSION__ >= 15009000
    #ifndef __LARGE_DATA_MODEL__
    .TI.ramfunc : {} load=FRAM, run=RAM, table(BINIT)
    #else
    .TI.ramfunc : {} load=FRAM | FRAM2, run=RAM, table(BINIT)
    #endif
  #endif
#endif

    .jtagsignature : {} > JTAGSIGNATURE   /* JTAG Signature                    */
    .bslsignature  : {} > BSLSIGNATURE    /* BSL Signature                     */

    .bss        : {} > RAM                /* Global & static vars              */
    .data       : {} > RAM                /* Global & static vars              */
    .TI.noinit  : {} > RAM                /* For #pragma noinit                */
    .cio        : {} > RAM                /* C I/O buffer                      */
    .sysmem     : {} > RAM                /* Dynamic memory allocation area    */
    .stack      : {} > RAM (HIGH)         /* Software system stack             */
    .text:_c_int00_noargs_noexit: {} > RESET_VECTOR

    /* MSP430 Interrupt vectors          */
    .int00       : {}               > INT00
    .int01       : {}               > INT01
    .int02       : {}               > INT02
    .int03       : {}               > INT03
    .int04       : {}               > INT04
    .int05       : {}               > INT05
    .int06       : {}               > INT06
    .int07       : {}               > INT07
    .int08       : {}               > INT08
    .int09       : {}               > INT09
    .int10       : {}               > INT10
    .int11       : {}               > INT11
    .int12       : {}               > INT12
    .int13       : {}               > INT13
    .int14       : {}               > INT14
    .int15       : {}               > INT15
    .int16       : {}               > INT16
    .int17       : {}               > INT17
    .int18       : {}               > INT18
    .int19       : {}               > INT19
    .int20       : {}               > INT20
    .int21       : {}               > INT21
    .int22       : {}               > INT22
    .int23       : {}               > INT23
    .int24       : {}               > INT24
    .int25       : {}               > INT25
    .int26       : {}               > INT26
    .int27       : {}               > INT27
    .int28       : {}               > INT28
    .int29       : {}               > INT29
    .int30       : {}               > INT30
    .int31       : {}               > INT31
    .int32       : {}               > INT32
    .int33       : {}               > INT33
    .int34       : {}               > INT34
    .int35       : {}               > INT35
    .int36       : {}               > INT36
    .int37       : {}               > INT37
    .int38       : {}               > INT38
    .int39       : {}               > INT39
    .int40       : {}               > INT40
    .int41       : {}               > INT41
    .int42       : {}               > INT42
    .int43       : {}               > INT43
    .int44       : {}               > INT44
    .int45       : {}               > INT45
    PORT2        : { * ( .int46 ) } > INT46 type = VECT_INIT
    PORT1        : { * ( .int47 ) } > INT47 type = VECT_INIT
    ADC          : { * ( .int48 ) } > INT48 type = VECT_INIT
    USCI_B0      : { * ( .int49 ) } > INT49 type = VECT_INIT
    USCI_A0      : { * ( .int50 ) } > INT50 type = VECT_INIT
    WDT          : { * ( .int51 ) } > INT51 type = VECT_INIT
    RTC          : { * ( .int52 ) } > INT52 type = VECT_INIT
    TIMER1_A1    : { * ( .int53 ) } > INT53 type = VECT_INIT
    TIMER1_A0    : { * ( .int54 ) } > INT54 type = VECT_INIT
    TIMER0_A1    : { * ( .int55 ) } > INT55 type = VECT_INIT
    TIMER0_A0    : { * ( .int56 ) } > INT56 type = VECT_INIT
    UNMI         : { * ( .int57 ) } > INT57 type = VECT_INIT
    SYSNMI       : { * ( .int58 ) } > INT58 type = VECT_INIT
    .reset       : {}               > RESET  /* MSP430 Reset vector         */
}

This is the main application linker:

MEMORY
{
    SFR                     : origin = 0x0000, length = 0x0010
    PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
    PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
    RAM                     : origin = 0x2000, length = 0x0800
    INFOA                   : origin = 0x1800, length = 0x0100
    FRAM                    : origin = 0xC480, length = 0x2F7F
    FRAM_JUMP_INSTRUCTION   : origin = 0xC400, length = 0x0008
    FRAM_BOOT_ISR           : origin = 0xC408, length = 0x0078
    JTAGSIGNATURE           : origin = 0xFF80, length = 0x0004, fill = 0xFFFF
    BSLSIGNATURE            : origin = 0xFF84, length = 0x0004, fill = 0xFFFF
    INT00                   : origin = 0xFF88, length = 0x0002
    INT01                   : origin = 0xFF8A, length = 0x0002
    INT02                   : origin = 0xFF8C, length = 0x0002
    INT03                   : origin = 0xFF8E, length = 0x0002
    INT04                   : origin = 0xFF90, length = 0x0002
    INT05                   : origin = 0xFF92, length = 0x0002
    INT06                   : origin = 0xFF94, length = 0x0002
    INT07                   : origin = 0xFF96, length = 0x0002
    INT08                   : origin = 0xFF98, length = 0x0002
    INT09                   : origin = 0xFF9A, length = 0x0002
    INT10                   : origin = 0xFF9C, length = 0x0002
    INT11                   : origin = 0xFF9E, length = 0x0002
    INT12                   : origin = 0xFFA0, length = 0x0002
    INT13                   : origin = 0xFFA2, length = 0x0002
    INT14                   : origin = 0xFFA4, length = 0x0002
    INT15                   : origin = 0xFFA6, length = 0x0002
    INT16                   : origin = 0xFFA8, length = 0x0002
    INT17                   : origin = 0xFFAA, length = 0x0002
    INT18                   : origin = 0xFFAC, length = 0x0002
    INT19                   : origin = 0xFFAE, length = 0x0002
    INT20                   : origin = 0xFFB0, length = 0x0002
    INT21                   : origin = 0xFFB2, length = 0x0002
    INT22                   : origin = 0xFFB4, length = 0x0002
    INT23                   : origin = 0xFFB6, length = 0x0002
    INT24                   : origin = 0xFFB8, length = 0x0002
    INT25                   : origin = 0xFFBA, length = 0x0002
    INT26                   : origin = 0xFFBC, length = 0x0002
    INT27                   : origin = 0xFFBE, length = 0x0002
    INT28                   : origin = 0xFFC0, length = 0x0002
    INT29                   : origin = 0xFFC2, length = 0x0002
    INT30                   : origin = 0xFFC4, length = 0x0002
    INT31                   : origin = 0xFFC6, length = 0x0002
    INT32                   : origin = 0xFFC8, length = 0x0002
    INT33                   : origin = 0xFFCA, length = 0x0002
    INT34                   : origin = 0xFFCC, length = 0x0002
    INT35                   : origin = 0xFFCE, length = 0x0002
    INT36                   : origin = 0xFFD0, length = 0x0002
    INT37                   : origin = 0xFFD2, length = 0x0002
    INT38                   : origin = 0xFFD4, length = 0x0002
    INT39                   : origin = 0xFFD6, length = 0x0002
    INT40                   : origin = 0xFFD8, length = 0x0002
    INT41                   : origin = 0xFFDA, length = 0x0002
    INT42                   : origin = 0xFFDC, length = 0x0002
    INT43                   : origin = 0xFFDE, length = 0x0002
    INT44                   : origin = 0xFFE0, length = 0x0002
    INT45                   : origin = 0xFFE2, length = 0x0002
    INT46                   : origin = 0xFFE4, length = 0x0002
    INT47                   : origin = 0xFFE6, length = 0x0002
    INT48                   : origin = 0xFFE8, length = 0x0002
    INT49                   : origin = 0xFFEA, length = 0x0002
    INT50                   : origin = 0xFFEC, length = 0x0002
    INT51                   : origin = 0xFFEE, length = 0x0002
    INT52                   : origin = 0xFFF0, length = 0x0002
    INT53                   : origin = 0xFFF2, length = 0x0002
    INT54                   : origin = 0xFFF4, length = 0x0002
    INT55                   : origin = 0xFFF6, length = 0x0002
    INT56                   : origin = 0xFFF8, length = 0x0002
    INT57                   : origin = 0xFFFA, length = 0x0002
    INT58                   : origin = 0xFFFC, length = 0x0002
    RESET                   : origin = 0xFFFE, length = 0x0002
}

/****************************************************************************/
/* Specify the sections allocation into memory                              */
/****************************************************************************/

SECTIONS
{
    GROUP(ALL_FRAM)
    {
       GROUP(READ_WRITE_MEMORY)
       {
          .TI.persistent : {}                /* For #pragma persistent            */
       }

       GROUP(READ_ONLY_MEMORY)
       {
          .cinit      : {}                   /* Initialization tables             */
          .pinit      : {}                   /* C++ constructor tables            */
          .init_array : {}                   /* C++ constructor tables            */
          .mspabi.exidx : {}                 /* C++ constructor tables            */
          .mspabi.extab : {}                 /* C++ constructor tables            */
          .const      : {}                   /* Constant data                     */
       }

       GROUP(EXECUTABLE_MEMORY)
       {
          .text       : {}                   /* Code                              */
          .text:_isr  : {}
       }
    } > FRAM

    .jtagsignature : {} > JTAGSIGNATURE   /* JTAG Signature                    */
    .bslsignature  : {} > BSLSIGNATURE    /* BSL Signature                     */
    .jtagpassword                         /* JTAG Password                     */

    .bss        : {} > RAM                /* Global & static vars              */
    .data       : {} > RAM                /* Global & static vars              */
    .TI.noinit  : {} > RAM                /* For #pragma noinit                */
    .cio        : {} > RAM                /* C I/O buffer                      */
    .sysmem     : {} > RAM                /* Dynamic memory allocation area    */
    .stack      : {} > RAM (HIGH)         /* Software system stack             */
    .reset_vector : {} > FRAM_BOOT_ISR
.text:_c_int00_noargs_noexit: {} > FRAM_BOOT_ISR /* MSP430 Interrupt vectors */ .int00 : {} > INT00 .int01 : {} > INT01 .int02 : {} > INT02 .int03 : {} > INT03 .int04 : {} > INT04 .int05 : {} > INT05 .int06 : {} > INT06 .int07 : {} > INT07 .int08 : {} > INT08 .int09 : {} > INT09 .int10 : {} > INT10 .int11 : {} > INT11 .int12 : {} > INT12 .int13 : {} > INT13 .int14 : {} > INT14 .int15 : {} > INT15 .int16 : {} > INT16 .int17 : {} > INT17 .int18 : {} > INT18 .int19 : {} > INT19 .int20 : {} > INT20 .int21 : {} > INT21 .int22 : {} > INT22 .int23 : {} > INT23 .int24 : {} > INT24 .int25 : {} > INT25 .int26 : {} > INT26 .int27 : {} > INT27 .int28 : {} > INT28 .int29 : {} > INT29 .int30 : {} > INT30 .int31 : {} > INT31 .int32 : {} > INT32 .int33 : {} > INT33 .int34 : {} > INT34 .int35 : {} > INT35 .int36 : {} > INT36 .int37 : {} > INT37 .int38 : {} > INT38 .int39 : {} > INT39 .int40 : {} > INT40 .int41 : {} > INT41 .int42 : {} > INT42 .int43 : {} > INT43 .int44 : {} > INT44 .int45 : {} > INT45 PORT2 : { * ( .int46 ) } > INT46 type = VECT_INIT PORT1 : { * ( .int47 ) } > INT47 type = VECT_INIT ADC : { * ( .int48 ) } > INT48 type = VECT_INIT USCI_B0 : { * ( .int49 ) } > INT49 type = VECT_INIT USCI_A0 : { * ( .int50 ) } > INT50 type = VECT_INIT WDT : { * ( .int51 ) } > INT51 type = VECT_INIT RTC : { * ( .int52 ) } > INT52 type = VECT_INIT TIMER1_A1 : { * ( .int53 ) } > INT53 type = VECT_INIT TIMER1_A0 : { * ( .int54 ) } > INT54 type = VECT_INIT TIMER0_A1 : { * ( .int55 ) } > INT55 type = VECT_INIT TIMER0_A0 : { * ( .int56 ) } > INT56 type = VECT_INIT UNMI : { * ( .int57 ) } > INT57 type = VECT_INIT SYSNMI : { * ( .int58 ) } > INT58 type = VECT_INIT .reset : {} > FRAM_JUMP_INSTRUCTION /* MSP430 Reset vector */ }

This is the jump instruction in the main application to jump to the boot loaders reset:

#pragma RETAIN(bootloader_jump)
#pragma location=0xC400
const int bootloader_jump[] = {0x0280, 0x1900};

This is the jump from the boot loader back to the main:

((void (*)()) 0xC408) ();

And this is the brown out reset:

PMMCTL0 = PMMPW|PMMSWBOR;

Thanks.

  • Edited to remove accidental repeated post of the linker code

  • Hi Dan, 

    Can I ask why you decided not to use MSP430FRBoot for this application?

    Dan Long said:
    I have read that because the MSP430FR2033 is using FRAM and does not have a minimum erase size (and is treated like ram), it does not need proxy vector table, but in the MSP430FRBOOT code examples they do have proxy vector tables. Why does it not require a proxy vector table if the linkers contain the same addresses for the hardware interrupts? Does each application reconfigure the HW Vector Table in the int00 interrupt at boot? Or do I need a proxy vector table?.

    MSP430FRBoot does not use a proxy interrupt vector table even though there is one defined in the linker file. MSP430FRBoot was created based on MSPBoot which was made for flash devices and there are still some remnants left over in the code that need to be removed. In MSPBoot, the boot code is located in the same flash segment as the interrupt vector table. If the user wanted to update the vector table this would require an erase of the boot code. To get around this issue, the default vector table points to a proxy vector table that holds the real interrupt vectors. This is not necessary for an FRAM part because their is no minimum erase size and therefore no danger of erasing the boot code. 

    Dan Long said:
    Our design is to have the HW Reset Vector always jump to the boot interrupt of the boot loader. This is so the boot loader can check if the main application needs to update on start up, and if not, jump to the main application. We jump to main by having a jump instruction to the int00 routine of the main. We jump to the boot loader from the main application by doing a brownout reset. The brownout reset works, however it doesn't seem to jump to the boot loader and we are not sure why.

    I recommend taking a look at how MSP430FRBoot accomplishes this. In the bootloader linker file, the reset is defined as the default reset interrupt address 0xFFFE. This way, when the MCU starts up, it will always jump to the bootloader first. Then to jump back to the application from the bootloader, a password is set in RAM and then a BOR is performed. Once the BOR occurs, the bootloader checks this password and then jumps to the application using a similar line of code as you've specified above {((void (*)()) _Appl_Reset_Vector) ();}

    Dan Long said:
    What flash options should we be using for each application? Currently we flash in the boot loader using a full erase and program. Then we flash in the application by doing a differential download on the main application. We immediately lose debug control when we do this because the reset vector goes into the boot loader. Is this the correct way to flash these two applications onto the same processor?

    There are multiple ways to do this and it depends on whether you want to maintain debug or are programming for production. In CCS you can maintain debug control by loading the symbols of the code that is currently running. For the approach you've described above this is probably the simplest approach. After you load the application code you can regain debug control by loading the symbols for the boot loader code. Then when you jump to the application, you can regain control by loading the symbols for the application:

    Hope this helps and let me know if you have any further questions. 

    Best regards, 

    Caleb Overbay

  • Hi Caleb,

    Caleb Overbay said:

    Can I ask why you decided not to use MSP430FRBoot for this application?

    The reason why we aren't using the MSP430FRBoot for this is that our system requires the slave microcontrollers to follow a registration sequence with the master and then maintain a heartbeat message to indicate its presence on the bus whether in the main application or in the boot loader. This is using a specific packet and command structure that we felt would be easier to implement and use in our own custom boot loader. This would also give us the flexibility of changing anything further down the line. To achieve this we need a timer interrupt and an I2C interrupt.

    Caleb Overbay said:
    MSP430FRBoot was created based on MSPBoot which was made for flash devices and there are still some remnants left over in the code that need to be removed.

    Thank you for pointing this out. This caused a bit of confusion.

    Caleb Overbay said:
    I recommend taking a look at how MSP430FRBoot accomplishes this. In the bootloader linker file, the reset is defined as the default reset interrupt address 0xFFFE. This way, when the MCU starts up, it will always jump to the bootloader first.

    Not long after posting this we managed to figure out the correct reset process to enter and leave the boot loader. Your response has confirmed that we are doing it the right way now.

    Caleb Overbay said:
    In CCS you can maintain debug control by loading the symbols of the code that is currently running.

     

    This will certainly help debugging. Thank you.

    In regards to not needing a proxy vector table, what is the best way of relocating the interrupts into the hardware interrupt vector table? We use I2C and timers in both the main application and the boot loader. So currently we have an I2C and a timer interrupt routine in each application. Is the best method to simply write the interrupt addresses to separate reserved locations in memory and then copy them to the hardware vector table when needed? Such as before leaving the boot loader, copy the main applications interrupts into the hardware vector table, and then on boot loader start up, copy the boot loaders interrupts into the hardware vector table? Or is there a cleaner way of doing this?

    Thank you for your help, you have certainly cleared some of this up for us.

    Regards,

    Dan

  • Hi Dan, 

    Dan Long said:
    In regards to not needing a proxy vector table, what is the best way of relocating the interrupts into the hardware interrupt vector table? We use I2C and timers in both the main application and the boot loader. So currently we have an I2C and a timer interrupt routine in each application. Is the best method to simply write the interrupt addresses to separate reserved locations in memory and then copy them to the hardware vector table when needed? Such as before leaving the boot loader, copy the main applications interrupts into the hardware vector table, and then on boot loader start up, copy the boot loaders interrupts into the hardware vector table? Or is there a cleaner way of doing this?

    In MSPBoot, this is solved by never using interrupts in the bootloader. So if you wanted to use I2C or a Timer in the bootloader you would need to poll the interrupt flags. This probably isn't ideal for your application though. Do the ISR's perform the same function regardless of whether they are being used for the bootloader or the application? If this is the case, you could reuse the code in the bootloader instead of overwriting the vectors. If not, I'm having difficulty thinking of a better way than what you've described. 

    Best regards, 
    Caleb Overbay

  • Hi Caleb,

    I've tested overwriting the hardware vector table and it seems to work as desired. Both ISRs in the application and the boot loader are the same, but there is the possibility for either to be changed further down the line, so having them separate seems like the best approach.

    Thank you for your help.

    Best Regards,
    Dan

**Attention** This is a public forum