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.

MSP430FR2311: [Custom BSL] Mapping proxy interrupt vector table in MSP430FR issue

Part Number: MSP430FR2311
Other Parts Discussed in Thread: CC1200

Hi,

(This is my first attempt on MSP430) I am now porting custom BSL from slaa600 to MSP430FR2311 using IAR 6.5. I am done with the BSL but in APP2, I have issue while try to mapping the "real" interrupt table(0xFF80~0xFFFF) to proxy interrupt table. I already search some threads about custom BSL but not much information. 

In the G model I found the mapping can be done like this

extern __interrupt void P1_Isr(void);
extern __interrupt void Dummy_Isr (void);

#   ifdef __IAR_SYSTEMS_ICC__
#       pragma location="APP_PROXY_VECTORS"
__root const uint16_t ProxyVectorTable[] =
#   elif defined (__TI_COMPILER_VERSION__)
#       pragma DATA_SECTION(ProxyVectorTable, ".APP_PROXY_VECTORS")
#       pragma RETAIN(ProxyVectorTable)
const uint16_t ProxyVectorTable[] =
#   endif
{
        0x4030, (uint16_t) P1_Isr,              // APP_PROXY_VECTOR(0) P1
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(1) P2
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(2) ADC10
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(3) USCI SPI TX
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(4) USCI SPI RX
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(5) TA0_1
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(6) T0_0
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(7) WDT
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(8) COMP_A
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(9) TA1_1
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(10) TA1_0
        0x4030, (uint16_t) Dummy_Isr,           // APP_PROXY_VECTOR(11) NMI
        0x4030, (uint16_t) Dummy_Isr,
        0x4030, (uint16_t) Dummy_Isr,
        0x4030, (uint16_t) Dummy_Isr,
};

But, in the FR model, it shows

//
//  Constant tables
//
/* Proxy table is not needed for FR5xx */

Question 1: why there is difference in G model and FR model, if there is no code available in FR model, so how proxy vector table is mapped to interrupt table? 

I try to copy the G model to FR to make it work (like above), but failed. And show a lot of errors

Error[Pa128]: truncating cast in constant expression...
#   ifdef __IAR_SYSTEMS_ICC__
#       pragma location="APP_PROXY_VECTORS"
__root const uint32_t ProxyVectorTable[] =
#   elif defined (__TI_COMPILER_VERSION__)
#       pragma DATA_SECTION(ProxyVectorTable, ".APP_PROXY_VECTORS")
#       pragma RETAIN(ProxyVectorTable)
const uint32_t ProxyVectorTable[] =
#   endif
{
        0x4030, (uint32_t) P1_Isr,              // APP_PROXY_VECTOR(0) P1
...

I change from uint16_t to uint32_t, the error gone, but it does not jump to the interrupt function when button at port 1 is pressed, it shows there is something happen when I press the button by stop at address 0x10000 which is out of memory size (the maximum is 0xFFFF for FR2311). Therefore, I think the mapping is wrong so the it cannot jump to the correct vector.  

Question 2: why with the G model the uint16_t  can be used but show error in FR2311? And since I need to change it to uint32_t, my proxy interrupt table becomes very big which wasting FRAM (FR2311 only has 3.75kB FRAM)    

As I see in the memory map, the actual interrupt vector table from 0xFF88~0xFFFF, meaning there is 120 bytes, but most of them are unused, only 15 interrupt vectors are defined in msp430fr2311.h

#define ECOMP0_VECTOR          (45 * 2u) /* 0xFFE2 */
#define PORT2_VECTOR           (46 * 2u) /* 0xFFE4 */
#define PORT1_VECTOR           (47 * 2u) /* 0xFFE6 */
#define ADC_VECTOR             (48 * 2u) /* 0xFFE8 */
#define EUSCI_B0_VECTOR        (49 * 2u) /* 0xFFEA */
#define EUSCI_A0_VECTOR        (50 * 2u) /* 0xFFEC */
#define WDT_VECTOR             (51 * 2u) /* 0xFFEE */
#define RTC_VECTOR             (52 * 2u) /* 0xFFF0 */
#define TIMER1_B1_VECTOR       (53 * 2u) /* 0xFFF2 */
#define TIMER1_B0_VECTOR       (54 * 2u) /* 0xFFF4 */
#define TIMER0_B1_VECTOR       (55 * 2u) /* 0xFFF6 */
#define TIMER0_B0_VECTOR       (56 * 2u) /* 0xFFF8 */
#define UNMI_VECTOR            (57 * 2u) /* 0xFFFA */
#define SYSNMI_VECTOR          (58 * 2u) /* 0xFFFC */
#define RESET_VECTOR           (59 * 2u) /* 0xFFFE */
here is my linker file of APP2:
// Application Checksum address -D_Appl_Checksum=_FLASH_START -D_Appl_Checksum_8=(_FLASH_START+2) // Application Start address (after checksum) -D_Appl_Start=(_FLASH_START+3) //F100+3=F103 // Application End Address -D_Appl_End=(_BOOT_Start-1) //F388-1=F387 // Application reset vector -D_Appl_Reset_Vector=(_Appl_End-1) // Start address of Proxy vector table -D_Appl_Proxy_Vector_Start=(_Appl_Reset_Vector-30) // End address of Proxy vector table -D_App_Proxy_Vector_End=(_Appl_Reset_Vector-1) // Size of area calculated by CRC (App+ProxyTable) -D_CRC_Size=(_Appl_End-_Appl_Start+1) -Z(CONST)APP_PROXY_VECTORS=_Appl_Proxy_Vector_Start-_App_Proxy_Vector_End -Z(CODE)INTVEC=_Appl_Proxy_Vector_Start-_Appl_End -Z(CODE)RESET=_Appl_Reset_Vector-_Appl_End

Question 3: So, can I only use 30 bytes in the the proxy vector table in my app to save memory? If not, please suggest what size of the proxy vector table to use all above interrupts (in case I want to use it), and why?

Question 4:I see in the "Custom ISR structure", the file "interrupt proxy.asm" is added directly to IAR project, is it possible to add assembly .asm file like that?(the compiler understand? Or any configuration must be set? ). I try to add it and it seems the linker doesn't understand where to call #include "msp430fr2311.h" 

Question 5: How to map proxy interrupt table to the real interrupt table in IAR?

thank you

  • Hi,

    Please see my response on the following E2E thread:

    While MSP430FRBoot does not have an exact example for the MSP430FR2311, it is much more applicable to what you're trying to accomplish. Please start by reading the MSP430FRBoot application report which explains why FRAM parts do not require a proxy interrupt vector table. This will also save you on code size as well.

    However, with the MSP430FR2311 only having 3.5K of FRAM, it's not going to be the best candidate for using a bootloader that resides in main memory. Unless your application is less than 1.5k in size, I doubt you would be able to fit both into the the FR2311. Have you looked into using the UART BSL that already resides in the part? While this can't be customized because it resides on ROM, it can be used to program the part without any additional code overhead. Here's a like to the FR2311's BSL user's guide: MSP430FR4xx and MSP430FR2xx Bootloader (BSL) User's Guide (Rev. C)

    Best regards,

    Caleb Overbay

  • Hi Caled,

    Thank you for your reply,

    I am done with my custome BSL on FR2311, and now develop APP. Yes, the booloader is now only 2.3kB, my app is less than 1.2kB, therefore, so far I do not have any problem with size. I understand your doubt since the begining of the project many FAEs told me it is imposible, but since we have litmited bugde and the app is really simle (just flashing LED and buzzer and ADC to check battery status). When choosing FR2311 we do estimate the code size, since the ROM BSL do not have OTA function which I need update FW over the air (OTA) function (use it with CC1200), so we choose the custome BSL. The OTA of custome BSL is working great now. The only issue is the APP (I still have 1.2kB for the APP now).

    I did read MSP430FRBoot many times (www.ti.com/.../slaa721a.pdf) before modify the custome BSL, and study the sample code, but I cannot undestand how the interrupt function is called in the app without mapping it with vector table in FRAM (the manual just explains how proxy table work in flash and do not explain how it work in FRAM, althouth it mentioned "interrupts can be reprogrammed").

    MSP430FRBoot was made for FRAM devices including the MSP430FR5994 and does not require a proxy vector table for interrupts. 
    This means there is no vector redirection and interrupt handling is almost the same as in a typical application. Using this as a starting
    place will solve the issues you're currently seeing with interrupts.
    all interrupts can be reprogrammed in
    FRAM devices without risking erasure of the reset vector

    Suppose all above statements are true, so how it work? how to reprogram interrupt table? I do not need to add proxy table in linker file nor declare it in source code, just declare 

    __interrupt P1_Ist(void)
    {
          mycode...
    }

    and it will automatically jump to this interrupt function when interrupt event happen? I did try this way but not working.

    Please help to explain in detail your statement above (and question 1, important for me) and provide some code for reference;  I do not know where to ask this issue. Thank you very much.


    BR,

  • Hi,

    Question 1: why there is difference in G model and FR model, if there is no code available in FR model, so how proxy vector table is mapped to interrupt table?
    A: The difference is that the G model is flash and the FR model is FRAM. Flash memory is divided into segments and a segment is the smallest amount of flash memory that can be erased. This is typically 512 bytes on an MSP430. The MSPBoot code is placed in the same segment of flash as the default interrupt vector table. Therefore, if new interrupts were added to your application MSPBoot would run the risk of deleting itself. For this reason the default interrupt vector table is mapped to a proxy interrupt vector table that is not in the same segment.

    FRAM does not require segmentation and can be treated as if it were RAM. Each individual FRAM cell can be erased and programmed without affecting the cells around it. This means the default vector table is sufficient and there is no need to map to a proxy interrupt vector table.

    All the magic here is done in the linker file. I'm assuming since you started with MSPBoot, your linker file includes the proxy interrupt vector table. This linker file is not default and has been modified to fit MSPBoot's needs. Take a look at one of the linker files for MSP430FRBoot and see how the default interrupt vector locations are still intact. You can use the Linker Generation Perl Script included in MSP430FRBoot to create a suitable linker file for the FR2311. Keep in mind though that some of the nomenclature is different between MSPBoot and MSP430FRBoot so your project most likely won't build immediately.

    Best regards,
    Caleb Overbay

**Attention** This is a public forum