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.

Custom Bootloader with large memory model

Other Parts Discussed in Thread: MSP430F2618

Hi,

I created a custom bootloader for the MSP430F2618 using the TI examples in SLAA600 in CCS v5.  The reset vector points to the bootloader which decides whether to jump to the app or wait for a download and the interrupt vectors are redirected using code below.  Everything worked really well but now we have a project that's gotten fairly large and I need to access the extended flash region from the bootloader. 

I can't go to the large memory model or my interrupt redirection falls apart because it tries to map my redirected vector table using 20 bit addresses which means it won't fit into the fixed location of the interrupt table and I can't access the extended memory without going to 20 bit pointers.

extern Uint16 _App_Proxy_Vector_Start[];			// Proxy table address defined in CMD

// Macro used to calculate address of vector in application proxy table
#define APP_PROXY_VECTOR(x)		((Uint16)&_App_Proxy_Vector_Start[x*2])

// Constant table of MSPBoot Vector table: It's fixed since it can't be erased
// and modified.  Points to a proxy vector table in application area.
#pragma DATA_SECTION(Vector_Table, ".BOOT_VECTOR_TABLE")
#pragma RETAIN(Vector_Table)
const Uint16 Vector_Table[] =
{
	UNUSED,						// FFC0 = Unused
	UNUSED,						// FFC2 = Unused
	UNUSED,						// FFC4 = Unused
	UNUSED,						// FFC6 = Unused
	UNUSED,						// FFC8 = Unused
	UNUSED,						// FFCA = Unused
	UNUSED,						// FFCC = Unused
	UNUSED,						// FFCE = Unused
	UNUSED,						// FFD0 = Unused
	UNUSED,						// FFD2 = Unused
	UNUSED,						// FFD4 = Unused
	UNUSED,						// FFD6 = Unused
	UNUSED,						// FFD8 = Unused
	UNUSED,						// FFDA = Unused
	APP_PROXY_VECTOR(0),		// FFDC = DAC12
	APP_PROXY_VECTOR(1),		// FFDE = DMA
	APP_PROXY_VECTOR(2),		// FFE0 = UCAB1TX
	APP_PROXY_VECTOR(3),		// FFE2 = UCAB1RX
	APP_PROXY_VECTOR(4),		// FFE4 = P1
	APP_PROXY_VECTOR(5),		// FFE6 = P2
	UNUSED,						// FFE8 = Unused
	APP_PROXY_VECTOR(6),		// FFEA = ADC12
	APP_PROXY_VECTOR(7),		// FFEC = UCAB0TX
	APP_PROXY_VECTOR(8),		// FFEE = UCAB0RX
	APP_PROXY_VECTOR(9),		// FFF0 = TACCR1,TACCR2,TAIFG
	APP_PROXY_VECTOR(10),		// FFF2 = TACCR0
	APP_PROXY_VECTOR(11),		// FFF4 = WDT
	APP_PROXY_VECTOR(12),		// FFF6 = Comparator A+
	APP_PROXY_VECTOR(13),		// FFF8 = TBCCR1, TBCCR6, TBIFG
	APP_PROXY_VECTOR(14),		// FFFA = TBCCR0
	APP_PROXY_VECTOR(15),		// FFFC = NMI,Oscillator,Flash access violation
};

Does anybody have any suggestions?  I'm not sure how to proceed from here and I fear this will lead to an assembly solution and I'm a novice at best.

Thanks,

Justin

  • For jump to 64k area are used 2 word instructions...

    mov.w #ABCDh, PC  // BR #ABCDh

    Most of CPUX instructions will take one more word, but there are "address" instructions that can be used for jump to 20-bit address space, and still fit in 2 words (mova is different than movx.a)...

    mova #34567h, PC  // BR #34567h

    If you still want to use (custom) vector table, than 20-bit value can fit with some lower bits unused (for example align every function to start at #XXX8h).

  • Is there a reason you can't modify the proxy vector table to support 32-bit (2 16-bit) instructions?

    extern Uint32 _App_Proxy_Vector_Start[];			// Proxy table address defined in CMD
    
    // Macro used to calculate address of vector in application proxy table
    #define APP_PROXY_VECTOR(x)		((Uint16)&_App_Proxy_Vector_Start[x*4)
    

    Or.... why can't you define all your ISRs to reside below 64K in Flash (via linker file segment control) and let other code reside in upper Flash?

  • zrno soli said:

    For jump to 64k area are used 2 word instructions...

    mov.w #ABCDh, PC  // BR #ABCDh

    Most of CPUX instructions will take one more word, but there are "address" instructions that can be used for jump to 20-bit address space, and still fit in 2 words (mova is different than movx.a)...

    mova #34567h, PC  // BR #34567h

    If you still want to use (custom) vector table, than 20-bit value can fit with some lower bits unused (for example align every function to start at #XXX8h).

    Thanks for the explanation, I'm going to give the assembly approach a try.

    Regards,

    Justin

  • Brian,

    Thanks for the response.  Maybe I'm misunderstanding your statement but the table I posted above is located in the bootloader and is mapped to the region 0xFFC0-0xFFFD which contains the 16-bit addressed interrupt vector table that resides in hardware.  So changing the table to support 32-bit will not work ( at least I don't think it will ). 

    If the ISR's reside in the below 64k I'll still need the bootloader application to be able to access the entire memory region so I'll have to turn on the large memory model in CCS.  Sorry if I'm misinterpreting your explanation but I'm not sure that anwers my questions.

    Thanks,

    Justin

  • jtm214 said:
    Maybe I'm misunderstanding your statement but the table I posted above is located in the bootloader and is mapped to the region 0xFFC0-0xFFFD which contains the 16-bit addressed interrupt vector table that resides in hardware.  So changing the table to support 32-bit will not work ( at least I don't think it will ).

    Maybe I misunderstood your system...

    Where does "extern Uint16 _App_Proxy_Vector_Start[];"  reside in your system memory? I assumed that was a jump table to the actual ISRs and that Vector_Table[] was the table located at 0xFFxx-0xFFFF.

    If my assumption is correct, then my recommendation was to change how _App_Proxy_Vector_Start[] was used and have it be 20-bit address capable of branching to the appropriate ISR.

  • This should work with large memory model:

    extern Uint16 _App_Proxy_Vector_Start[];            // Proxy table address defined in CMD
    
    // NEW! Define the base address where the proxy vector (above) is placed
    #define  PROXY_BASE_START  0x_YOUR_16BIT_ADDRESS_TO_App_Proxy_Vector_Start[]_HERE_
    
    // Macro below modifed...
    // Macro used to calculate address of vector in application proxy table
    #define APP_PROXY_VECTOR(x)     (PROXY_BASE_START + (x*2))
    
    // Constant table of MSPBoot Vector table: It's fixed since it can't be erased
    // and modified.  Points to a proxy vector table in application area.
    #pragma DATA_SECTION(Vector_Table, ".BOOT_VECTOR_TABLE")
    #pragma RETAIN(Vector_Table)
    const Uint16 Vector_Table[] =
    {
        UNUSED,                     // FFC0 = Unused
        UNUSED,                     // FFC2 = Unused
        UNUSED,                     // FFC4 = Unused
        UNUSED,                     // FFC6 = Unused
        UNUSED,                     // FFC8 = Unused
        UNUSED,                     // FFCA = Unused
        UNUSED,                     // FFCC = Unused
        UNUSED,                     // FFCE = Unused
        UNUSED,                     // FFD0 = Unused
        UNUSED,                     // FFD2 = Unused
        UNUSED,                     // FFD4 = Unused
        UNUSED,                     // FFD6 = Unused
        UNUSED,                     // FFD8 = Unused
        UNUSED,                     // FFDA = Unused
        APP_PROXY_VECTOR(0),        // FFDC = DAC12
        APP_PROXY_VECTOR(1),        // FFDE = DMA
        APP_PROXY_VECTOR(2),        // FFE0 = UCAB1TX
        APP_PROXY_VECTOR(3),        // FFE2 = UCAB1RX
        APP_PROXY_VECTOR(4),        // FFE4 = P1
        APP_PROXY_VECTOR(5),        // FFE6 = P2
        UNUSED,                     // FFE8 = Unused
        APP_PROXY_VECTOR(6),        // FFEA = ADC12
        APP_PROXY_VECTOR(7),        // FFEC = UCAB0TX
        APP_PROXY_VECTOR(8),        // FFEE = UCAB0RX
        APP_PROXY_VECTOR(9),        // FFF0 = TACCR1,TACCR2,TAIFG
        APP_PROXY_VECTOR(10),       // FFF2 = TACCR0
        APP_PROXY_VECTOR(11),       // FFF4 = WDT
        APP_PROXY_VECTOR(12),       // FFF6 = Comparator A+
        APP_PROXY_VECTOR(13),       // FFF8 = TBCCR1, TBCCR6, TBIFG
        APP_PROXY_VECTOR(14),       // FFFA = TBCCR0
        APP_PROXY_VECTOR(15),       // FFFC = NMI,Oscillator,Flash access violation
    };

    Note that I use a ram vector implementation along these same lines... the CPU vector table points to locations in RAM that are part of a jump table to the actual ISRs. (They are filled-in at runtime with either the bootloader or application ISRs depending on which context is currently running). So what you want to do is possible. It's just a matter of how you  "fool the compiler".

  • That's exactly what I was missing.

    Much obliged,

    Justin

**Attention** This is a public forum