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.

HOW CREATE A SECONDARY INTERRUPT TABLE

Other Parts Discussed in Thread: MSP430FG477, MSP430F5419, MSP430F2232, MSP430F2252, MSP430F5528

 

Hi,

I am writting a custom bootloader and to manage this I have to create a secondary interrupt table within the application space.  Basically, the bootloader would get the 'real' interrupt table. So interrupts would breifly go through this real table, and be passed on to the application code (if valid) to via the interrupt talbe within the application code space..

My new table would be located into an other segment from 0xF0C0 to 0xF0FF

I don't succeed to get my interrupt to work at all so If someone have already achieved to do that I would please to know how.

 

MCU: MSP430F47166

SW: CCS v4

the linker file:

 

MEMORY

{

    SFR                     : origin = 0x0000, length = 0x0010

    PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0

    PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100

    RAM                     : origin = 0x1100, length = 0x1000

    INFOA                   : origin = 0x10C0, length = 0x0040

    INFOB                   : origin = 0x1080, length = 0x0040

    INFOC                   : origin = 0x1040, length = 0x0040

    INFOD                   : origin = 0x1000, length = 0x0040

/*   FLASH                   : origin = 0x2B00, length = 0xD2C0 /* TAILLE CODE = 53952o + 64o (IT vector) */

   FLASH                   : origin = 0x2B00, length = 0xC2C0 /* TAILLE CODE = 549856o + 64o (IT vector) */

 

    INT00                   : origin = 0xF0C0, length = 0x0002 /* Image de la table des vecteurs situé à 0xFDC0 */

    INT01                   : origin = 0xF0C2, length = 0x0002

    INT02                   : origin = 0xF0C4, length = 0x0002

    INT03                   : origin = 0xF0C6, length = 0x0002

    INT04                   : origin = 0xF0C8, length = 0x0002

    INT05                   : origin = 0xF0CA, length = 0x0002

    INT06                   : origin = 0xF0CC, length = 0x0002

    INT07                   : origin = 0xF0CE, length = 0x0002

    INT08                   : origin = 0xF0D0, length = 0x0002

    INT09                   : origin = 0xF0D2, length = 0x0002

    INT10                   : origin = 0xF0D4, length = 0x0002

    INT11                   : origin = 0xF0D6, length = 0x0002

    INT12                   : origin = 0xF0D8, length = 0x0002

    INT13                   : origin = 0xF0DA, length = 0x0002

    INT14                   : origin = 0xF0DC, length = 0x0002

    INT15                   : origin = 0xF0DE, length = 0x0002

    INT16                   : origin = 0xF0E0, length = 0x0002

    INT17                   : origin = 0xF0E2, length = 0x0002

    INT18                   : origin = 0xF0E4, length = 0x0002

    INT19                   : origin = 0xF0E6, length = 0x0002

    INT20                   : origin = 0xF0E8, length = 0x0002

    INT21                   : origin = 0xF0EA, length = 0x0002

    INT22                   : origin = 0xF0EC, length = 0x0002

    INT23                   : origin = 0xF0EE, length = 0x0002

    INT24                   : origin = 0xF0F0, length = 0x0002

    INT25                   : origin = 0xF0F2, length = 0x0002

    INT26                   : origin = 0xF0F4, length = 0x0002

    INT27                   : origin = 0xF0F6, length = 0x0002

    INT28                   : origin = 0xF0F8, length = 0x0002

    INT29                   : origin = 0xF0FA, length = 0x0002

    INT30                   : origin = 0xF0FC, length = 0x0002

 

    INT000                   : origin = 0xFFC0, length = 0x0002, fill = 0xF0C0

    INT010                   : origin = 0xFFC2, length = 0x0002, fill = 0xF0C2

    INT020                   : origin = 0xFFC4, length = 0x0002, fill = 0xF0C4

    INT030                   : origin = 0xFFC6, length = 0x0002, fill = 0xF0C6

    INT040                   : origin = 0xFFC8, length = 0x0002, fill = 0xF0C8

    INT050                   : origin = 0xFFCA, length = 0x0002, fill = 0xF0CA

    INT060                   : origin = 0xFFCC, length = 0x0002, fill = 0xF0CC

    INT070                   : origin = 0xFFCE, length = 0x0002, fill = 0xF0CE

    INT080                   : origin = 0xFFD0, length = 0x0002, fill = 0xF0D0

    INT090                   : origin = 0xFFD2, length = 0x0002, fill = 0xF0D2

    INT100                   : origin = 0xFFD4, length = 0x0002, fill = 0xF0D4

    INT110                   : origin = 0xFFD6, length = 0x0002, fill = 0xF0D6

    INT120                   : origin = 0xFFD8, length = 0x0002, fill = 0xF0D8

    INT130                   : origin = 0xFFDA, length = 0x0002, fill = 0xF0DA

    INT140                   : origin = 0xFFDC, length = 0x0002, fill = 0xF0DC

    INT150                   : origin = 0xFFDE, length = 0x0002, fill = 0xF0DE

    INT160                   : origin = 0xFFE0, length = 0x0002, fill = 0xF0E0

    INT170                   : origin = 0xFFE2, length = 0x0002, fill = 0xF0E2

    INT180                   : origin = 0xFFE4, length = 0x0002, fill = 0xF0E4

    INT190                   : origin = 0xFFE6, length = 0x0002, fill = 0xF0E6

    INT200                   : origin = 0xFFE8, length = 0x0002, fill = 0xF0E8

    INT210                   : origin = 0xFFEA, length = 0x0002, fill = 0xF0EA

    INT220                   : origin = 0xFFEC, length = 0x0002, fill = 0xF0EC

    INT230                   : origin = 0xFFEE, length = 0x0002, fill = 0xF0EE

    INT240                   : origin = 0xFFF0, length = 0x0002, fill = 0xF0F0

    INT250                   : origin = 0xFFF2, length = 0x0002, fill = 0xF0F2

    INT260                   : origin = 0xFFF4, length = 0x0002, fill = 0xF0F4

    INT270                   : origin = 0xFFF6, length = 0x0002, fill = 0xF0F6

    INT280                   : origin = 0xFFF8, length = 0x0002, fill = 0xF0F8

    INT290                   : origin = 0xFFFA, length = 0x0002, fill = 0xF0FA

    INT300                   : origin = 0xFFFC, length = 0x0002, fill = 0xF0FC

 

    RESET                   : origin = 0xFFFE, length = 0x0002

}

 

/****************************************************************************/

/* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY                              */

/****************************************************************************/

 

SECTIONS

{

    .bss       : {} > RAM                /* GLOBAL & STATIC VARS              */

    .sysmem    : {} > RAM                /* DYNAMIC MEMORY ALLOCATION AREA    */

    .stack     : {} > RAM (HIGH)         /* SOFTWARE SYSTEM STACK             */

 

    .text      : {}>> FLASH | FLASH2     /* CODE                              */

    .text:_isr : {} > FLASH              /* ISR CODE SPACE                    */

    .cinit     : {} > FLASH              /* INITIALIZATION TABLES             */

    .const     : {} > FLASH | FLASH2     /* CONSTANT DATA                     */

    .cio       : {} > RAM                /* C I/O BUFFER                      */

 

    .pinit     : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */

 

    .infoA     : {} > INFOA              /* MSP430 INFO FLASH MEMORY SEGMENTS */

    .infoB     : {} > INFOB

    .infoC     : {} > INFOC

    .infoD     : {} > INFOD

 

  .int_00   : {} > INT00                /* MSP430 INTERRUPT VECTORS          */

    .int_01   : {} > INT01

    .int_02   : {} > INT02

    .int_03   : {} > INT03

    .int_04   : {} > INT04

    .int_05   : {} > INT05

    .int_06   : {} > INT06

    .int_07   : {} > INT07

    .int_08   : {} > INT08

    .int_09   : {} > INT09

    .int_10   : {} > INT10

    .int_11   : {} > INT11

    .int_12   : {} > INT12

    .int_13   : {} > INT13

    .int_14   : {} > INT14

    .int_15   : {} > INT15

    .int_16   : {} > INT16

    .int_17   : {} > INT17

    .int_18   : {} > INT18

    .int_19   : {} > INT19

    .int_20   : {} > INT20

    .int_21   : {} > INT21

    .int_22   : {} > INT22

    .int_23   : {} > INT23

    .int_24   : {} > INT24

    .int_25   : {} > INT25

    .int_26   : {} > INT26

    .int_27   : {} > INT27

    .int_28   : {} > INT28

    .int_29   : {} > INT29

    .int_30   : {} > INT30

 

    .int00   : {} > INT000                /* MSP430 INTERRUPT VECTORS          */

    .int01   : {} > INT010

    .int02   : {} > INT020

    .int03   : {} > INT030

    .int04   : {} > INT040

    .int05   : {} > INT050

    .int06   : {} > INT060

    .int07   : {} > INT070

    .int08   : {} > INT080

    .int09   : {} > INT090

    .int10   : {} > INT100

    .int11   : {} > INT110

    .int12   : {} > INT120

    .int13   : {} > INT130

    .int14   : {} > INT140

    .int15   : {} > INT150

    .int16   : {} > INT160

    .int17   : {} > INT170

    .int18   : {} > INT180

    .int19   : {} > INT190

    .int20   : {} > INT200

    .int21   : {} > INT210

    .int22   : {} > INT220

    .int23   : {} > INT230

    .int24   : {} > INT240

    .int25   : {} > INT250

    .int26   : {} > INT260

    .int27   : {} > INT270

    .int28   : {} > INT280

    .int29   : {} > INT290

    .int30   : {} > INT300

 

    .reset   : {} > RESET              /* MSP430 RESET VECTOR               */ 

}

 

I tried to manipulate my c file 

#pragama void function(void)

#pragama CODE_SECTIONS(function,address) // New interrupt vector Address

_interrupt void function(void)

 

 

 

  • Hi Emilien,

    Did you check out app-note SLAA341 regarding a flash-based UART bootloader?  It mirrors the interrupt vector table into the "application" space at a new segment. The bootloader uses the actual vectors and remaps them to the application space. Only caveat is that the app-note was written for IAR. But is should be straight-forward to convert to CCS (maybe the TI guys can revise the app-note source files for CCS too, if they are listening).

    Link: http://focus.ti.com/general/docs/litabsmultiplefilelist.tsp?literatureNumber=slaa341

    Good Luck and Regards,

    Gene M.

     

  • Doing what you want requires some effort.

    First, you'll need the original vector table point to a jumptable. You cannot point from the original table into your own table directly, as the processor expects CODE it can execute, not just another vector.

    I don't know how (or if at all) inline assembly works on CCE or IAR. What you need is an ISR (one for each vector entry!) which has no entry code and jumps directly or indirectly to the real ISR.

    Example:

    0xf0c0  .DW 0x8000  (address of your ISR)

    0xfc00 JMP &0xfc0c  (indirect jump to the address stored at 0xf0c0)

    0xffc0 .DW 0xfc00  ('fake' vector pointing to the jump)

    Stuffing the real vector table with the addresses of the jump(s) can be done by NEVER using the #pragma vector anywhere and assigning function pointer variables to the proper sections as listed in the linker command file. I don't know the CCE/IAR syntax for defining the destination segment of a variable.

    The critical part is placing the jumps where they belong - and creating the jumps at all.

    On some MSPs, you can redirect the vector table to the end of RAM instead of the end of ROM. This only requires copying the new vector table to RAM, reserving the end of ram (so it isn't used for stack) and switching the control bit. Then you don't need the jumps. It is, however, a bit risky to have the interrupt vectors in ram.

     

  • Hi,

    To accomplish this, it requires a custom command linker file and an assembly level code. We have a code example that was developed for F5419 devices. However, this code can easily be ported to F47166 device. It contains both code example for IAR and CCS too.

    Give it a try and let us know if you find any issues using this package.

    Regards,

    William

    Custom ISR Structure.zip
  • I tried your code example and maked it compatible for the F47166, it works 

    Thanks to all of you for your help

    It is my second try on TI E2E and I am very satisfied of speed and answer's qualities.

     

    Emilien 

  • Hello there,

    refering to the project Custom ISR Structure, I had modified my project to relocated my interrupt at 0x8BE0 to 0x8BFF. I had modified the interrupt proxy.asm for the interrupt of the MSP430FG477 and the .cmd. It has build, but I am not able to run the software on debug. Here the message of CCS V4: 

    MSP430: Can't Run Target CPU: Could not run device (to breakpoint)

    I imaging that I did something wrong in my modification. Here my .cmd 

    MEMORY
    {
        SFR                     : origin = 0x0000, length = 0x0010
        PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
        PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
        RAM                     : origin = 0x0200, length = 0x0400
        INFOA                   : origin = 0x10C0, length = 0x0040
        INFOB                   : origin = 0x1080, length = 0x0040
        INFOC                   : origin = 0x1040, length = 0x0040
        INFOD                   : origin = 0x1000, length = 0x0040
        FLASH                   : origin = 0x8000, length = 0x0A00
       
     /* Reserved segment definition for the main program's interrupt vectors,* reset vector, branch vectors. */
        BRINTVEC                : origin = 0xFE00, length = 0x180
       
     /* Relocated segment definition for interrupt vectors / reset vector. */  
        INT00                   : origin = 0x8BE0, length = 0x0002
        INT01                   : origin = 0x8BE2, length = 0x0002
        INT02                   : origin = 0x8BE4, length = 0x0002
        INT03                   : origin = 0x8BE6, length = 0x0002
        INT04                   : origin = 0x8BE8, length = 0x0002
        INT05                   : origin = 0x8BEA, length = 0x0002
        INT06                   : origin = 0x8BEC, length = 0x0002
        INT07                   : origin = 0x8BEE, length = 0x0002
        INT08                   : origin = 0x8BF0, length = 0x0002
        INT09                   : origin = 0x8BF2, length = 0x0002
        INT10                   : origin = 0x8BF4, length = 0x0002
        INT11                   : origin = 0x8BF6, length = 0x0002
        INT12                   : origin = 0x8BF8, length = 0x0002
        INT13                   : origin = 0x8BFA, length = 0x0002
        INT14                   : origin = 0x8BFC, length = 0x0002
        RESET                   : origin = 0x8BFE, length = 0x0002
       
        /* Reserved main interrupt vectors space. */
        MAININTVEC                 : origin = 0xFF80, length = 0x0080
       
    }

    /****************************************************************************/
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY                              */
    /****************************************************************************/

    SECTIONS
    {
        .bss       : {} > RAM                /* GLOBAL & STATIC VARS              */
        .sysmem    : {} > RAM                /* DYNAMIC MEMORY ALLOCATION AREA    */
        .stack     : {} > RAM (HIGH)         /* SOFTWARE SYSTEM STACK             */

        .text      : {} > FLASH              /* CODE                              */
        .text:_isr : {} > FLASH              /* ISR CODE SPACE                    */
        .cinit     : {} > FLASH              /* INITIALIZATION TABLES             */
        .const     : {} > FLASH              /* CONSTANT DATA                     */
        .cio       : {} > RAM                /* C I/O BUFFER                      */

        .pinit     : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */

        .infoA     : {} > INFOA              /* MSP430 INFO FLASH MEMORY SEGMENTS */
        .infoB     : {} > INFOB
        .infoC     : {} > INFOC
        .infoD     : {} > INFOD
       
        .mainintvec : {} > MAININTVEC        /* MAIN PROGRAM INT VECTOR TABLE     */

        .brintvec : {} > BRINTVEC            /* BRANCH INST PROGRAM INT VECTOR TABLE */

        .int00   : {} > INT00                /* MSP430 INTERRUPT VECTORS          */
        .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
        .reset   : {} > RESET              /* MSP430 RESET VECTOR               */
    }

    /****************************************************************************/
    /* INCLUDE PERIPHERALS MEMORY MAP                                           */
    /****************************************************************************/

    -l msp430xG47x.cmd

     

    and the interrupt proxy.asm : 

     

    ;-------------------------------------------------------------------------------
    ; The following code section is used to define variables to allow
    ; accessing the interrupt vectors which are defined by the main program.
    ;-------------------------------------------------------------------------------
    BASICTIMER_PROXY   .equ  0x8BE0                ; 0x8BE0 Basic Timer
    PORT2_PROXY             .equ  0x8BE2                ; 0x8BE2 Port 2
                                                                                      ; 0x8BE4 None
    DAC12_PROXY             .equ  0x8BE6                ; 0x8BE6 DAC
    PORT1_PROXY             .equ  0x8BE8                ; 0x8BE8 Port 1
    TIMERA1_PROXY          .equ  0x8BEA                ; 0x8BEA Timer A CC1-2, TA
    TIMERA0_PROXY          .equ  0x8BEC                ; 0x8BEC Timer A CC0
    SD16A_PROXY              .equ  0x8BEE                ; 0x8BEE ADC SD16A
    USCIAB0TX_PROXY     .equ  0x8BF0                ; 0x8BF0 USCI A0/B0 Transmit
    USCIAB0RX_PROXY    .equ  0x8BF2                ; 0x8BF2 USCI A0/B0 Receive
    WDT_PROXY                  .equ  0x8BF4                ; 0x8BF4 Watchdog Timer
    COMPARATORA_PROXY  .equ  0x8BF6                ; 0x8BF6 Comparator A
    TIMERB1_PROXY               .equ  0x8BF8                ; 0x8BF8 Timer B CC1-2, TB
    TIMERB0_PROXY               .equ  0x8BFA                ; 0x8BFA Timer B CC0
    NMI_PROXY                         .equ  0x8BFC                ; 0x8BFC Non-maskable
    RESET_PROXY                   .equ  0x8BFE                ; 0x8BFE Reset vector

                    .cdecls C,LIST, "msp430xG47x.h"
    ;-------------------------------------------------------------------------------
    ; The following code section contains the actual ISR implementation
    ; for all possible MSP430F5419 interrupt sources. All that is being done
    ; here is an indirect jump to the address that is stored in the
    ; main program's virtual interrupt vector table. Other than a 5 CPU
    ; cycle overhead added to each ISR call, there are no side effects of
    ; doing this.
    ; Also, interrupt vectors not implemented on the device are trapped and
    ; not forwarded to the main program.
    ;-------------------------------------------------------------------------------
                    .sect   ".brintvec"          ; Assemble to branch interrupt
                                                           ; memory
    ;-------------------------------------------------------------------------------
    BASICTIMER_ISR  BR      &BASICTIMER_PROXY       ; Indirect jump using proxy
    PORT2_ISR       BR      &PORT2_PROXY            ; Indirect jump using proxy
    DAC12_ISR       BR      &DAC12_PROXY            ; Indirect jump using proxy
    PORT1_ISR       BR      &PORT1_PROXY            ; Indirect jump using proxy
    TIMERA1_ISR     BR      &TIMERA1_PROXY          ; Indirect jump using proxy
    TIMERA0_ISR     BR      &TIMERA0_PROXY          ; Indirect jump using proxy 
    SD16A_ISR       BR      &SD16A_PROXY            ; Indirect jump using proxy
    USCIAB0TX_ISR   BR      &USCIAB0TX_PROXY        ; Indirect jump using proxy
    USCIAB0RX_ISR   BR      &USCIAB0RX_PROXY        ; Indirect jump using proxy
    WDT_ISR         BR      &WDT_PROXY              ; Indirect jump using proxy
    COMPARATORA_ISR BR      &COMPARATORA_PROXY      ; Indirect jump using proxy
    TIMERB1_ISR     BR         &TIMERB1_PROXY          ; Indirect jump using proxy
    TIMERB0_ISR     BR      &TIMERB0_PROXY          ; Indirect jump using proxy
    NMI_ISR         BR      &NMI_PROXY              ; Indirect jump using proxy
    RESET_ISR       BR      &RESET_PROXY            ; Indirect jump using proxy 

    ;-------------------------------------------------------------------------------
    ; The following code section populates the actual MSP430F5419 interrupt
    ; vectors to point to code sections within the boot loader code. In these
    ; code sections, an indirect jump is performed and with this the interrupt
    ; requests are routed to the main program.
    ;-------------------------------------------------------------------------------
                .sect   ".mainintvec"        
           
                .word   BASICTIMER_ISR              ; 0x8BE0 Basic Timer 
                .word   PORT2_ISR                         ; 0x8BE2 Port 2
                .word   DAC12_ISR                         ; 0x8BE6 DAC
                .word   PORT1_ISR                         ; 0x8BE8 Port 1
                .word   TIMERA1_ISR                      ; 0x8BEA Timer A CC1-2, TA
                .word   TIMERA0_ISR                      ; 0x8BEC Timer A CC0
                .word   SD16A_ISR                          ; 0x8BEE ADC SD16A
                .word   USCIAB0TX_ISR                 ; 0x8BF0 USCI A0/B0 Transmit
                .word   USCIAB0RX_ISR                ; 0x8BF2 USCI A0/B0 Receive
                .word   WDT_ISR                              ; 0x8BF4 Watchdog Timer
                .word   COMPARATORA_ISR          ; 0x8BF6 Comparator A
                .word   TIMERB1_ISR                      ; 0x8BF8 Timer B CC1-2, TB
                .word   TIMERB0_ISR                      ; 0x8BFA Timer B CC0
                .word   NMI_ISR                                ; 0x8BFC Non-maskable
                .word   RESET_ISR                          ; 0x8BFE Reset vector
    ;-------------------------------------------------------------------------------
                .end

     

    Thank for any help!

    Maxime Tardif

     


     

  • I'm a bit puzzled about the memory usage.
    Flash begins at 0x8000 and ends at 0xffff. You have a fixed content @0xffe0, but the flash segment where it is in begins at 0xfe00. So why don't you put your branch code there too, as it is also static. And move the application interrupt vectors to 0xfd80, the end of application flash.
    Also, if you make the tables as large as possible, you can make it MSP independent.vector table and the branches don't care for the interrupt they are serving. So if you code straight down from 0xfffe, it will fit any device.
    Actually, there was no need to modify the original ASM file at all. Only the CMD file.

    Teh message 'cannot run device (to breakpoint)' usually means that the debugger has set an automatic breakpoint at main but the code never comes there. However, I don't see why this happens. YOu should do a memory dump (in the debugger?) and see whether things are where you expect them.

  • Hello,

    thanks for fast answers! It might be a little confused the way that I have present my problem.

    I'm doing a boot loader and a main application, in two project (as it been advice in many post of TI E2E). The .cmd presented was the boot loader software at 0x8000 to 0x89FF.I wanted to relocated interrupt of the bootloader in segment 0x8A00 to 0x8BFF. The main application is at 0x8C00 to the end (0xFE00).

    I was actuelly able to load my main software with my bootloader and make it run! (The two software was sharing the sames interruptions.)The problem is when I return to the boot loader. I'm Jumping in the boot loader and then,interrupt conflict between the two software begin. That why I want to avoid this, by giving to the main software is own interrupt.

    This was the way the mapping of my project was when I had post my problem.


    As I was searching and reading on TI forums, and had change my mapping to this since our last conversation:

     

    Main App at 0x8000 to 0xF1FF

    Main App Interrupt relocated to  0xF200 to 0xF3FF

    Boot Loader 0xF400 to 0xFE00

    Boot Loader Interrupt 0xFE00 to 0xFFFF (Standard)

     

    I have follow the advice of this post for this mapping:

    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/99865/353674.aspx#353674

     

    "You have a fixed content @0xffe0, but the flash segment where it is in begins at 0xfe00. So why don't you put your branch code there too, as it is also static. And move the application interrupt vectors to 0xfd80, the end of application flash. Also, if you make the tables as large as possible, you can make it MSP independent.vector table and the branches don't care for the interrupt they are serving. So if you code straight down from 0xfffe, it will fit any device."

    I understand your concern about this and I take it has great modification to add! But it can not create problem for now.

     

    "Actually, there was no need to modify the original ASM file at all. Only the CMD file."

    I don't understand that statement. The example code interrupt proxy.asm was made for the MSP430F5419. My MSP430FG477 did not have the sames interrupt vectors adress. 

    For example, the PORT2_ISR is at 0xFFD4 for the MSP430F5419 and at 0xFFE2 for my MSP430FG477! So I need to change it !

    And I surely need to specify relocated vector adress too, in that files? I'm a bit confused about that !

    This is my first time doing a boot loader, maybe I understand wrong in some point. Tell me if  I'm wrong in some way.

     

    "Teh message 'cannot run device (to breakpoint)' usually means that the debugger has set an automatic breakpoint at main but the code never comes there. However, I don't see why this happens. YOu should do a memory dump (in the debugger?) and see whether things are where you expect them."

    I have made a dump of my flash after debugging and I did not see something wrong. My software is at 0x8000, is interrupt are at 0xF3E0. And the redirected code is at 0xFE00 segment. I joint the dump files, if you want take a look at it. Again Maybe I'm wrong!

    I let you the .cmd of my main code and the interrupt proxy.asm if you need to take a look.

    1362.MainSoft_Dump.txt

    4530.lnk_msp430fg477.txt
    /******************************************************************************/
    /* lnk_msp430fg477.cmd - LINKER COMMAND FILE FOR LINKING MSP430FG477 PROGRAMS */
    /*                                                                            */
    /*  Ver | dd mmm yyyy | Who  | Description of changes                         */
    /* =====|=============|======|=============================================   */
    /*  0.01| 08 Mar 2004 | A.D. | First prototype                                */
    /*  0.02| 26 Mai 2004 | A.D. | Leading symbol underscores removed,            */
    /*      |             |      | Interrupt vector definition changed            */
    /*  0.03| 22 Jun 2004 | A.D. | File reformatted                               */
    /*                                                                            */
    /*   Usage:  lnk430 <obj files...>    -o <out file> -m <map file> lnk.cmd     */
    /*           cl430  <src files...> -z -o <out file> -m <map file> lnk.cmd     */
    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    
    /* These linker options are for command line linking only.  For IDE linking,  */
    /* you should set your linker options in Project Properties                   */
    /* -c                                               LINK USING C CONVENTIONS  */
    /* -stack  0x0100                                   SOFTWARE STACK SIZE       */
    /* -heap   0x0100                                   HEAP AREA SIZE            */
    
    /*----------------------------------------------------------------------------*/
    /* 'Allocate' peripheral registers at given addresses                         */
    /*----------------------------------------------------------------------------*/
    
    /****************************************************************************/
    /* SPECIFY THE SYSTEM MEMORY MAP                                            */
    /****************************************************************************/
    
    MEMORY
    {
        SFR                     : origin = 0x0000, length = 0x0010
        PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
        PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
        RAM                     : origin = 0x0200, length = 0x0400
        INFOA                   : origin = 0x10C0, length = 0x0040
        INFOB                   : origin = 0x1080, length = 0x0040
        INFOC                   : origin = 0x1040, length = 0x0040
        INFOD                   : origin = 0x1000, length = 0x0040
        FLASH                   : origin = 0x8000, length = 0x73E0
        
     /* Reserved segment definition for the main program's interrupt vectors,* reset vector, branch vectors. */
        BRINTVEC                : origin = 0xFE00, length = 0x180
        
     /* Relocated segment definition for interrupt vectors / reset vector. */   
        INT00                   : origin = 0xF3E0, length = 0x0002
        INT01                   : origin = 0xF3E2, length = 0x0002
        INT02                   : origin = 0xF3E4, length = 0x0002
        INT03                   : origin = 0xF3E6, length = 0x0002
        INT04                   : origin = 0xF3E8, length = 0x0002
        INT05                   : origin = 0xF3EA, length = 0x0002
        INT06                   : origin = 0xF3EC, length = 0x0002
        INT07                   : origin = 0xF3EE, length = 0x0002
        INT08                   : origin = 0xF3F0, length = 0x0002
        INT09                   : origin = 0xF3F2, length = 0x0002
        INT10                   : origin = 0xF3F4, length = 0x0002
        INT11                   : origin = 0xF3F6, length = 0x0002
        INT12                   : origin = 0xF3F8, length = 0x0002
        INT13                   : origin = 0xF3FA, length = 0x0002
        INT14                   : origin = 0xF3FC, length = 0x0002
        RESET                   : origin = 0xF3FE, length = 0x0002
        
        /* Reserved main interrupt vectors space. */
        MAININTVEC     	        : origin = 0xFF80, length = 0x0080
        
    }
    
    /****************************************************************************/
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY                              */
    /****************************************************************************/
    
    SECTIONS
    {
        .bss       : {} > RAM                /* GLOBAL & STATIC VARS              */
        .sysmem    : {} > RAM                /* DYNAMIC MEMORY ALLOCATION AREA    */
        .stack     : {} > RAM (HIGH)         /* SOFTWARE SYSTEM STACK             */
    
        .text      : {} > FLASH              /* CODE                              */
        .text:_isr : {} > FLASH              /* ISR CODE SPACE                    */
        .cinit     : {} > FLASH              /* INITIALIZATION TABLES             */
        .const     : {} > FLASH              /* CONSTANT DATA                     */
        .cio       : {} > RAM                /* C I/O BUFFER                      */
    
        .pinit     : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
    
        .infoA     : {} > INFOA              /* MSP430 INFO FLASH MEMORY SEGMENTS */
        .infoB     : {} > INFOB
        .infoC     : {} > INFOC
        .infoD     : {} > INFOD
        
        .mainintvec : {} > MAININTVEC        /* MAIN PROGRAM INT VECTOR TABLE     */
    
        .brintvec : {} > BRINTVEC            /* BRANCH INST PROGRAM INT VECTOR TABLE */
    
        .int00   : {} > INT00                /* MSP430 INTERRUPT VECTORS          */
        .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
        .reset   : {} > RESET              /* MSP430 RESET VECTOR               */ 
    }
    
    /****************************************************************************/
    /* INCLUDE PERIPHERALS MEMORY MAP                                           */
    /****************************************************************************/
    
    -l msp430xG47x.cmd
    
    

    7115.interrupt proxy.txt
    ;*******************************************************************************
    ;   interrupt proxy.asm
    ;
    ;   This file is used to fix the interrupt table and route MSP430F5419 hardware
    ;   interrupt requests to the Main Program using proxy routines / vectors.
    ;****************
    ;   W. Goh
    ;   Texas Instruments Inc.
    ;   April 2010
    ;   Built with Code Composer Studio v4.2 Build: 07005 
    ;*******************************************************************************
    ;-------------------------------------------------------------------------------
    ; The following code section is used to define variables to allow
    ; accessing the interrupt vectors which are defined by the main program.
    ;-------------------------------------------------------------------------------
    BASICTIMER_PROXY   .equ  0xF3E0                ; 0x8BE0 Basic Timer
    PORT2_PROXY        .equ  0xF3E2                ; 0x8BE2 Port 2
                                                   ; 0x8BE4 None 
    DAC12_PROXY        .equ  0xF3E6                ; 0x8BE6 DAC
    PORT1_PROXY        .equ  0xF3E8                ; 0x8BE8 Port 1
    TIMERA1_PROXY      .equ  0xF3EA                ; 0x8BEA Timer A CC1-2, TA 
    TIMERA0_PROXY      .equ  0xF3EC                ; 0x8BEC Timer A CC0
    SD16A_PROXY        .equ  0xF3EE                ; 0x8BEE ADC SD16A
    USCIAB0TX_PROXY    .equ  0xF3F0                ; 0x8BF0 USCI A0/B0 Transmit
    USCIAB0RX_PROXY    .equ  0xF3F2                ; 0x8BF2 USCI A0/B0 Receive
    WDT_PROXY          .equ  0xF3F4                ; 0x8BF4 Watchdog Timer
    COMPARATORA_PROXY  .equ  0xF3F6                ; 0x8BF6 Comparator A
    TIMERB1_PROXY      .equ  0xF3F8                ; 0x8BF8 Timer B CC1-2, TB
    TIMERB0_PROXY      .equ  0xF3FA                ; 0x8BFA Timer B CC0
    NMI_PROXY          .equ  0xF3FC                ; 0x8BFC Non-maskable
    RESET_PROXY        .equ  0xF3FE                ; 0x8BFE Reset vector
    
                    .cdecls C,LIST, "msp430xG47x.h"
    ;-------------------------------------------------------------------------------
    ; The following code section contains the actual ISR implementation
    ; for all possible MSP430F5419 interrupt sources. All that is being done
    ; here is an indirect jump to the address that is stored in the
    ; main program's virtual interrupt vector table. Other than a 5 CPU
    ; cycle overhead added to each ISR call, there are no side effects of
    ; doing this.
    ; Also, interrupt vectors not implemented on the device are trapped and
    ; not forwarded to the main program.
    ;-------------------------------------------------------------------------------
                    .sect   ".brintvec"         ; Assemble to branch interrupt
                                                ; memory
    ;-------------------------------------------------------------------------------
    BASICTIMER_ISR  BR      &BASICTIMER_PROXY       ; Indirect jump using proxy
    PORT2_ISR       BR      &PORT2_PROXY            ; Indirect jump using proxy
    DAC12_ISR       BR      &DAC12_PROXY            ; Indirect jump using proxy
    PORT1_ISR       BR      &PORT1_PROXY            ; Indirect jump using proxy
    TIMERA1_ISR     BR      &TIMERA1_PROXY          ; Indirect jump using proxy
    TIMERA0_ISR     BR      &TIMERA0_PROXY          ; Indirect jump using proxy  
    SD16A_ISR       BR      &SD16A_PROXY            ; Indirect jump using proxy
    USCIAB0TX_ISR   BR      &USCIAB0TX_PROXY        ; Indirect jump using proxy
    USCIAB0RX_ISR   BR      &USCIAB0RX_PROXY        ; Indirect jump using proxy
    WDT_ISR         BR      &WDT_PROXY              ; Indirect jump using proxy
    COMPARATORA_ISR BR      &COMPARATORA_PROXY      ; Indirect jump using proxy
    TIMERB1_ISR     BR         &TIMERB1_PROXY          ; Indirect jump using proxy
    TIMERB0_ISR     BR      &TIMERB0_PROXY          ; Indirect jump using proxy
    NMI_ISR         BR      &NMI_PROXY              ; Indirect jump using proxy
    RESET_ISR       BR      &RESET_PROXY            ; Indirect jump using proxy  
    
    ;-------------------------------------------------------------------------------
    ; The following code section populates the actual MSP430F5419 interrupt
    ; vectors to point to code sections within the boot loader code. In these
    ; code sections, an indirect jump is performed and with this the interrupt
    ; requests are routed to the main program.
    ;-------------------------------------------------------------------------------
                .sect   ".mainintvec"         
            
                .word   BASICTIMER_ISR              ; 0xFFE0 Basic Timer  
                .word   PORT2_ISR                   ; 0xFFE2 Port 2
                .word   DAC12_ISR                   ; 0xFFE6 DAC
                .word   PORT1_ISR                   ; 0xFFE8 Port 1
                .word   TIMERA1_ISR                 ; 0xFFEA Timer A CC1-2, TA 
                .word   TIMERA0_ISR                 ; 0xFFEC Timer A CC0
                .word   SD16A_ISR                   ; 0xFFEE ADC SD16A
                .word   USCIAB0TX_ISR               ; 0xFFF0 USCI A0/B0 Transmit
                .word   USCIAB0RX_ISR               ; 0xFFF2 USCI A0/B0 Receive
                .word   WDT_ISR                     ; 0xFFF4 Watchdog Timer
                .word   COMPARATORA_ISR             ; 0xFFF6 Comparator A
                .word   TIMERB1_ISR                 ; 0xFFF8 Timer B CC1-2, TB
                .word   TIMERB0_ISR                 ; 0xFFFA Timer B CC0
                .word   NMI_ISR                     ; 0xFFFC Non-maskable
                .word   RESET_ISR                   ; 0xFFFE Reset vector
    ;-------------------------------------------------------------------------------
                .end
    

    Thank for your time !!

    Maxime Tardif

     

  • Maxime Tardif79507 said:

    Main App at 0x8000 to 0xF1FF
    Main App Interrupt relocated to  0xF200 to 0xF3FF
    Boot Loader 0xF400 to 0xFE00
    Boot Loader Interrupt 0xFE00 to 0xFFFF (Standard)

    Looks more logical now. The bootloader part with the 'real' interrupt vector table is now a block at the end of flash, and the applicaiton begins at start. Less chances to get confused :)

    Maxime Tardif79507 said:

    "Actually, there was no need to modify the original ASM file at all. Only the CMD file."
    I don't understand that statement. The example code interrupt proxy.asm was made for the MSP430F5419. My MSP430FG477 did not have the sames interrupt vectors adress.

    Oh, it has. The vector at 0xfffc is the same vector at 0xffc ont he othe rdevice. On all devices. The meaning of this address may change, but this only affects where the compiler will put the interrupt function address. For the bootloader, i tmakes no difference whether this ISR is placed at that location. It just forwards the first vector to the first, the second to the second, whatever it might be. And if the table has a 20th vector and the MSP has only 19, then th e20th is just unused btu doesn't hurt.

    If you check again, you'll see that you only changed comments, and label names that are not used outside the proxy module. And if you compare the resulting binary, you'll see that it is bit for bit the same.

    Maxime Tardif79507 said:
    This is my first time doing a boot loader

    Mos tpeople never work in this area. It is a rather advanced stuff, so you joined a exclusive club. :)

    Maxime Tardif79507 said:
    I let you the .cmd of my main code and the interrupt proxy.asm if you need to take a look.


    The first thing I noticed is:

    0xFF80: 00 FE 04 FE 08 FE 0C FE   10 FE 14 FE 18 FE 1C FE | ................
    0xFF90: 20 FE 24 FE 28 FE 2C FE 30 FE 34 FE 38 FE FF FF | .$.(.,.0.4.8...
    0xFFA0: ------- b l a n k ----(all 0xFF)-------

    Where's the reset vector pointing to your boot loader? It should be on 0xFFFe, but it is 0xFFFF. So no wonder the debugger cannot run the device. The device doesn't know where to start (or rather tries to start its code execution on 0xFFFE, which of course is no code)

    your MAININTVEC section has space for 64 vectors and is filled form beginning. But your vector table for this segment has only 15 setors, which are placed from the begining of the segment.  You need to pad your content of this segment, so the last (the reset) vector will end up at 0xfffe.

    Another thing:

    RESET_ISR       BR      &RESET_PROXY            ; Indirect jump using proxy  
    .word RESET_ISR ; 0xFFFE Reset vector


    The 'real' reset vector shouldn't point to the proxy. It should point to the start of your bootloader instead. And if the bootloader decides to start the application, it should do a BR &RESET_PROXY) at the end to start the application. Else the whole proxy thing makes not much sense.

  • Maxime Tardif79507 said:

    Main App at 0x8000 to 0xF1FF
    Main App Interrupt relocated to  0xF200 to 0xF3FF
    Boot Loader 0xF400 to 0xFE00
    Boot Loader Interrupt 0xFE00 to 0xFFFF (Standard)

    Looks more logical now. The bootloader part with the 'real' interrupt vector table is now a block at the end of flash, and the applicaiton begins at start. Less chances to get confused :)

    Maxime Tardif79507 said:

    "Actually, there was no need to modify the original ASM file at all. Only the CMD file."
    I don't understand that statement. The example code interrupt proxy.asm was made for the MSP430F5419. My MSP430FG477 did not have the sames interrupt vectors adress.

    Oh, it has. The vector at 0xfffc is the same vector at 0xffc ont he othe rdevice. On all devices. The meaning of this address may change, but this only affects where the compiler will put the interrupt function address. For the bootloader, i tmakes no difference whether this ISR is placed at that location. It just forwards the first vector to the first, the second to the second, whatever it might be. And if the table has a 20th vector and the MSP has only 19, then th e20th is just unused btu doesn't hurt.

    If you check again, you'll see that you only changed comments, and label names that are not used outside the proxy module. And if you compare the resulting binary, you'll see that it is bit for bit the same.

    Maxime Tardif79507 said:
    This is my first time doing a boot loader

    Mos tpeople never work in this area. It is a rather advanced stuff, so you joined a exclusive club. :)

    Maxime Tardif79507 said:
    I let you the .cmd of my main code and the interrupt proxy.asm if you need to take a look.


    The first thing I noticed is:

    0xFF80: 00 FE 04 FE 08 FE 0C FE   10 FE 14 FE 18 FE 1C FE | ................
    0xFF90: 20 FE 24 FE 28 FE 2C FE 30 FE 34 FE 38 FE FF FF | .$.(.,.0.4.8...
    0xFFA0: ------- b l a n k ----(all 0xFF)-------

    Where's the reset vector pointing to your boot loader? It should be on 0xFFFe, but it is 0xFFFF. So no wonder the debugger cannot run the device. The device doesn't know where to start (or rather tries to start its code execution on 0xFFFE, which of course is no code)

    your MAININTVEC section has space for 64 vectors and is filled form beginning. But your vector table for this segment has only 15 setors, which are placed from the begining of the segment.  You need to pad your content of this segment, so the last (the reset) vector will end up at 0xfffe.

    Another thing:

    RESET_ISR       BR      &RESET_PROXY            ; Indirect jump using proxy  
    .word RESET_ISR ; 0xFFFE Reset vector


    The 'real' reset vector shouldn't point to the proxy. It should point to the start of your bootloader instead. And if the bootloader decides to start the application, it should do a BR &RESET_PROXY) at the end to start the application. Else the whole proxy thing makes not much sense.

  • Hi,

    I also try to write custom bootloader. I created two projects with separate linker files.
    I divided memory as follows:

    0x4000 - 0xAE00 - my main program
    0xAF80 - 0xAFFF - main program interrupt vector
    0xB000 - 0xFE00    - bootloader
    0xFF80 - 0xFFFF  - bootloader interrupt vector

    Writing my main program I based on your code example. I adapted it to processor MSP4306736.
    It seems that interrup vector in main program was correctly relocated,
    but when I jump from bootloader to main program, it runs, but I dont get any interrupts form Timer0_A0.

    I dont know what is wrong with my program.
    I attach files with linker and memory dump.

    6215.data.zip

    I will be grateful for any help or suggestions.

  • eg__ said:
    but when I jump from bootloader to main program, it runs, but I dont get any interrupts form Timer0_A0.

    Assuming you correctly enable interrupts etc, you need to set up the interrupt forwarding properly.

    The boot loader table entries have to point to an ISR code. Not to another vector. This code may be an ISR of teh bootloader that checks whether the bootloader is active, or a simple indirect jump that uses the application interrupt table as source for the destination.

    Example:

    0xFF80 0xFE00          ; boot loader interrupt vector table entry
    0xFF82 0xFE04
    0xFE00 MOV &0xAF80, R0 ; 'ISR' for this entry, loading value from 0xFEFC to the PC
    0xFE04 MOV &0xAF82, R0 ; 'ISR' for this entry, loading value from 0xFEFC to the PC
    0xAD80 0x4000          ; application interrupt vector tabel entry

    0xAD82 ...
    0x4000 [...]           ; application ISR

  • Hi,

    I am trying to do the same with MSP430F2232. I have divided my flash as following:

    Main App: 0xE000 - 0xEC00

    Main Intr Vec : 0xEFE0 - 0xEFFE

    Bootloader: 0xF600 - 0xFFE0

    Bootloadr Intr : 0xFFE0 - 0xFFFE

    I have modified the asmProxy file, as : 0601.interrupt proxy.asm

    I do have some questions as I have not quite gasp the concept. I appreciate your responses to them:

    1- Do I need to make any changes to cmd file of the bootloader project aside the start and length of the flash?

    7180.bootldrCmd.txt
    /******************************************************************************/
    /* lnk_msp430f2232.cmd - LINKER COMMAND FILE FOR LINKING MSP430F2232 PROGRAMS     */
    /*                                                                            */
    /*   Usage:  lnk430 <obj files...>    -o <out file> -m <map file> lnk.cmd     */
    /*           cl430  <src files...> -z -o <out file> -m <map file> lnk.cmd     */
    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    /* These linker options are for command line linking only.  For IDE linking,  */
    /* you should set your linker options in Project Properties                   */
    /* -c                                               LINK USING C CONVENTIONS  */
    /* -stack  0x0100                                   SOFTWARE STACK SIZE       */
    /* -heap   0x0100                                   HEAP AREA SIZE            */
    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    
    
    /****************************************************************************/
    /* SPECIFY THE SYSTEM MEMORY MAP                                            */
    /****************************************************************************/
    
    MEMORY
    {
        SFR                     : origin = 0x0000, length = 0x0010
        PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
        PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
        RAM                     : origin = 0x0200, length = 0x0200
        INFOA                   : origin = 0x10C0, length = 0x0040
        INFOB                   : origin = 0x1080, length = 0x0040
        INFOC                   : origin = 0x1040, length = 0x0040
        INFOD                   : origin = 0x1000, length = 0x0040
        FLASH                   : origin = 0xF600, length = 0x09e0 /* start of bootloader 2kB*/
        /* Reserved segment definition for the main program's interrupt vectors,
     * reset vector, branch vectors. */
     //   BRINTVEC                : origin = 0xFE00, length = 0x180
    
        INT00                   : origin = 0xFFE0, length = 0x0002
        INT01                   : origin = 0xFFE2, length = 0x0002
        INT02                   : origin = 0xFFE4, length = 0x0002
        INT03                   : origin = 0xFFE6, length = 0x0002
        INT04                   : origin = 0xFFE8, length = 0x0002
        INT05                   : origin = 0xFFEA, length = 0x0002
        INT06                   : origin = 0xFFEC, length = 0x0002
        INT07                   : origin = 0xFFEE, length = 0x0002
        INT08                   : origin = 0xFFF0, length = 0x0002
        INT09                   : origin = 0xFFF2, length = 0x0002
        INT10                   : origin = 0xFFF4, length = 0x0002
        INT11                   : origin = 0xFFF6, length = 0x0002
        INT12                   : origin = 0xFFF8, length = 0x0002
        INT13                   : origin = 0xFFFA, length = 0x0002
        INT14                   : origin = 0xFFFC, length = 0x0002
        RESET                   : origin = 0xFFFE, length = 0x0002
    
         /* Reserved main interrupt vectors space. */
      //  MAININTVEC                 : origin = 0xFF80, length = 0x0080
    }
    
    /****************************************************************************/
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY                              */
    /****************************************************************************/
    
    SECTIONS
    {
        .bss        : {} > RAM                /* GLOBAL & STATIC VARS              */
        .data       : {} > RAM                /* GLOBAL & STATIC VARS              */
        .sysmem     : {} > RAM                /* DYNAMIC MEMORY ALLOCATION AREA    */
        .stack      : {} > RAM (HIGH)         /* SOFTWARE SYSTEM STACK             */
    
        .text       : {} > FLASH              /* CODE                              */
        .cinit      : {} > FLASH              /* INITIALIZATION TABLES             */
        .const      : {} > FLASH              /* CONSTANT DATA                     */
        .cio        : {} > RAM                /* C I/O BUFFER                      */
    
        .pinit      : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
        .init_array : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
        .mspabi.exidx : {} > FLASH            /* C++ CONSTRUCTOR TABLES            */
        .mspabi.extab : {} > FLASH            /* C++ CONSTRUCTOR TABLES            */
    
        .infoA     : {} > INFOA              /* MSP430 INFO FLASH MEMORY SEGMENTS */
        .infoB     : {} > INFOB
        .infoC     : {} > INFOC
        .infoD     : {} > INFOD
    
        /* MSP430 INTERRUPT VECTORS          */
        .int00       : {}               > INT00
        .int01       : {}               > INT01
        PORT1        : { * ( .int02 ) } > INT02 type = VECT_INIT
        PORT2        : { * ( .int03 ) } > INT03 type = VECT_INIT
        .int04       : {}               > INT04
        ADC10        : { * ( .int05 ) } > INT05 type = VECT_INIT
        USCIAB0TX    : { * ( .int06 ) } > INT06 type = VECT_INIT
        USCIAB0RX    : { * ( .int07 ) } > INT07 type = VECT_INIT
        TIMERA1      : { * ( .int08 ) } > INT08 type = VECT_INIT
        TIMERA0      : { * ( .int09 ) } > INT09 type = VECT_INIT
        WDT          : { * ( .int10 ) } > INT10 type = VECT_INIT
        .int11       : {}               > INT11
        TIMERB1      : { * ( .int12 ) } > INT12 type = VECT_INIT
        TIMERB0      : { * ( .int13 ) } > INT13 type = VECT_INIT
        NMI          : { * ( .int14 ) } > INT14 type = VECT_INIT
        .reset       : {}               > RESET  /* MSP430 RESET VECTOR         */ 
    }
    
    /****************************************************************************/
    /* INCLUDE PERIPHERALS MEMORY MAP                                           */
    /****************************************************************************/
    
    -l msp430f2232.cmd
    
    

    2- I have tried to program the flash with FET-PRO430, though when I try to load the second project with CCS 5.3, it erases the previously written part of the flash. Is there any setting that needs to be set so we can debug the project in CCS?

    3- This is what I have done for my main App cmd file:

    3443.AppCmd.txt
    /******************************************************************************/
    /* lnk_msp430f2232.cmd - LINKER COMMAND FILE FOR LINKING MSP430F2232 PROGRAMS     */
    /*                                                                            */
    /*   Usage:  lnk430 <obj files...>    -o <out file> -m <map file> lnk.cmd     */
    /*           cl430  <src files...> -z -o <out file> -m <map file> lnk.cmd     */
    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    /* These linker options are for command line linking only.  For IDE linking,  */
    /* you should set your linker options in Project Properties                   */
    /* -c                                               LINK USING C CONVENTIONS  */
    /* -stack  0x0100                                   SOFTWARE STACK SIZE       */
    /* -heap   0x0100                                   HEAP AREA SIZE            */
    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    
    
    /****************************************************************************/
    /* SPECIFY THE SYSTEM MEMORY MAP                                            */
    /****************************************************************************/
    
    MEMORY
    {
        SFR                     : origin = 0x0000, length = 0x0010
        PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
        PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
        RAM                     : origin = 0x0200, length = 0x0200
        INFOA                   : origin = 0x10C0, length = 0x0040
        INFOB                   : origin = 0x1080, length = 0x0040
        INFOC                   : origin = 0x1040, length = 0x0040
        INFOD                   : origin = 0x1000, length = 0x0040
        FLASH                   : origin = 0xE000, length = 0x0C00
     /* Reserved segment definition for the main program's interrupt vectors,* reset vector, branch vectors. */
        BRINTVEC                : origin = 0xFE00, length = 0x180
    
        INT00                   : origin = 0xEFE0, length = 0x0002
        INT01                   : origin = 0xEFE2, length = 0x0002
        INT02                   : origin = 0xEFE4, length = 0x0002
        INT03                   : origin = 0xEFE6, length = 0x0002
        INT04                   : origin = 0xEFE8, length = 0x0002
        INT05                   : origin = 0xEFEA, length = 0x0002
        INT06                   : origin = 0xEFEC, length = 0x0002
        INT07                   : origin = 0xEFEE, length = 0x0002
        INT08                   : origin = 0xEFF0, length = 0x0002
        INT09                   : origin = 0xEFF2, length = 0x0002
        INT10                   : origin = 0xEFF4, length = 0x0002
        INT11                   : origin = 0xEFF6, length = 0x0002
        INT12                   : origin = 0xEFF8, length = 0x0002
        INT13                   : origin = 0xEFFA, length = 0x0002
        INT14                   : origin = 0xEFFC, length = 0x0002
        RESET                   : origin = 0xEFFE, length = 0x0002
    
        /* Reserved main interrupt vectors space. */
        MAININTVEC     	        : origin = 0xFFE0, length = 0x0020
    }
    
    /****************************************************************************/
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY                              */
    /****************************************************************************/
    
    SECTIONS
    {
        .bss        : {} > RAM                /* GLOBAL & STATIC VARS              */
        .data       : {} > RAM                /* GLOBAL & STATIC VARS              */
        .sysmem     : {} > RAM                /* DYNAMIC MEMORY ALLOCATION AREA    */
        .stack      : {} > RAM (HIGH)         /* SOFTWARE SYSTEM STACK             */
    
        .text       : {} > FLASH              /* CODE                              */
        .cinit      : {} > FLASH              /* INITIALIZATION TABLES             */
        .const      : {} > FLASH              /* CONSTANT DATA                     */
        .cio        : {} > RAM                /* C I/O BUFFER                      */
    
        .pinit      : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
        .init_array : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
        .mspabi.exidx : {} > FLASH            /* C++ CONSTRUCTOR TABLES            */
        .mspabi.extab : {} > FLASH            /* C++ CONSTRUCTOR TABLES            */
    
        .infoA     : {} > INFOA              /* MSP430 INFO FLASH MEMORY SEGMENTS */
        .infoB     : {} > INFOB
        .infoC     : {} > INFOC
        .infoD     : {} > INFOD
    
        .mainintvec : {} > MAININTVEC        /* MAIN PROGRAM INT VECTOR TABLE     */
    
        .brintvec : {} > BRINTVEC            /* BRANCH INST PROGRAM INT VECTOR TABLE */
    
        /* MSP430 INTERRUPT VECTORS          */
    
        .int00       : {}               > INT00
        .int01       : {}               > INT01
        PORT1        : { * ( .int02 ) } > INT02 type = VECT_INIT
        PORT2        : { * ( .int03 ) } > INT03 type = VECT_INIT
        .int04       : {}               > INT04
        ADC10        : { * ( .int05 ) } > INT05 type = VECT_INIT
        USCIAB0TX    : { * ( .int06 ) } > INT06 type = VECT_INIT
        USCIAB0RX    : { * ( .int07 ) } > INT07 type = VECT_INIT
        TIMERA1      : { * ( .int08 ) } > INT08 type = VECT_INIT
        TIMERA0      : { * ( .int09 ) } > INT09 type = VECT_INIT
        WDT          : { * ( .int10 ) } > INT10 type = VECT_INIT
        .int11       : {}               > INT11
        TIMERB1      : { * ( .int12 ) } > INT12 type = VECT_INIT
        TIMERB0      : { * ( .int13 ) } > INT13 type = VECT_INIT
        NMI          : { * ( .int14 ) } > INT14 type = VECT_INIT
        .reset       : {}               > RESET  /* MSP430 RESET VECTOR         */
    }
    
    /****************************************************************************/
    /* INCLUDE PERIPHERALS MEMORY MAP                                           */
    /****************************************************************************/
    
    -l msp430f2232.cmd
    
    

    memory dump: 

    2063.MemView.txt
    === Information Memory Segments  0x1000 - 0x10FF ======
    
    0x1000:       ------- b l a n k ----(all 0xFF)------- 
    
    
    0x10F0: FF FF FF FF FF FF AC 8A   81 8F 85 8E 79 8D AF 86 | ............y...
    
    ========== Main Memory Segments  0xE000 - 0xFFFF ======
    
    
    0xE000: 0A 12 09 12 3F 40 00 00   3F 90 01 00 19 28 3F 40 | ....?@..?....(?@
    0xE010: 00 00 3F 90 01 00 14 28   3A 40 00 00 3A 80 00 00 | ..?....(:@..:...
    0xE020: 3A 50 03 00 0A 11 0A 11   39 40 00 00 3C 49 7F 4C | :P......9@..<IL
    0xE030: 4F 4F 0F 5F 1F 4F 00 00   3D 49 8F 12 1A 83 F6 23 | OO._.O..=I.....#
    0xE040: 3F 40 00 00 3F 90 00 00   08 24 3A 40 00 00 02 3C | ?@..?....$:@...<
    0xE050: 3F 4A 8F 12 3A 90 00 00   FB 23 30 40 AA E0 B2 40 | ?J..:....#0@...@
    0xE060: 80 5A 20 01 D2 42 FA 10   56 00 D2 42 FB 10 57 00 | .Z ..B..V..B..W.
    0xE070: 32 D2 F2 F0 DF 00 2E 00   F2 D0 20 00 2A 00 F2 F0 | 2......... .*...
    0xE080: DF 00 29 00 FF 3F 31 40   00 04 B0 12 B6 E0 0C 93 | ..)..?1@........
    0xE090: 02 24 B0 12 00 E0 0C 43   B0 12 5E E0 B0 12 BA E0 | .$.....C..^.....
    0xE0A0: 34 41 35 41 36 41 37 41   38 41 39 41 3A 41 30 41 | 4A5A6A7A8A9A:A0A
    0xE0B0: 82 43 20 01 00 13 1C 43   30 41 03 43 FF 3F FF FF | .C ....C0A.C.?..
    0xE0C0:       ------- b l a n k ----(all 0xFF)------- 
    
    
    0xEFE0: FF FF FF FF B0 E0 B0 E0   FF FF B0 E0 B0 E0 B0 E0 | ................
    0xEFF0: B0 E0 B0 E0 B0 E0 FF FF   B0 E0 B0 E0 B0 E0 86 E0 | ................
    0xF000:       ------- b l a n k ----(all 0xFF)------- 
    
    
    0xF600: 0A 12 09 12 3F 40 00 00   3F 90 01 00 19 28 3F 40 | ....?@..?....(?@
    0xF610: 00 00 3F 90 01 00 14 28   3A 40 00 00 3A 80 00 00 | ..?....(:@..:...
    0xF620: 3A 50 03 00 0A 11 0A 11   39 40 00 00 3C 49 7F 4C | :P......9@..<IL
    0xF630: 4F 4F 0F 5F 1F 4F 00 00   3D 49 8F 12 1A 83 F6 23 | OO._.O..=I.....#
    0xF640: 3F 40 00 00 3F 90 00 00   08 24 3A 40 00 00 02 3C | ?@..?....$:@...<
    0xF650: 3F 4A 8F 12 3A 90 00 00   FB 23 30 40 DE F6 B2 40 | ?J..:....#0@...@
    0xF660: 80 5A 20 01 D2 42 FA 10   56 00 D2 42 FB 10 57 00 | .Z ..B..V..B..W.
    0xF670: 32 D2 F2 F0 DF 00 2E 00   F2 D0 20 00 2A 00 F2 D0 | 2......... .*...
    0xF680: 20 00 29 00 B0 12 9E F6   7C 93 04 24 F2 F0 DF 00 |  .).....|..$....
    0xF690: 29 00 03 3C F2 D0 20 00   29 00 0C 43 30 41 0C 43 | )..<.. .)..C0A.C
    0xF6A0: 3E 40 00 E0 0F 43 3F 90   FF 07 05 34 3C EE 1F 53 | >@...C?....4<..S
    0xF6B0: 3F 90 FF 07 FB 3B 4C 4C   30 41 31 40 00 04 B0 12 | ?....;LL0A1@....
    0xF6C0: EA F6 0C 93 02 24 B0 12   00 F6 0C 43 B0 12 5E F6 | .....$.....C..^.
    0xF6D0: B0 12 EE F6 34 41 35 41   36 41 37 41 38 41 39 41 | ....4A5A6A7A8A9A
    0xF6E0: 3A 41 30 41 82 43 20 01   00 13 1C 43 30 41 03 43 | :A0A.C ....C0A.C
    0xF6F0: FF 3F FF FF FF FF FF FF   FF FF FF FF FF FF FF FF | .?..............
    0xF700:       ------- b l a n k ----(all 0xFF)------- 
    
    
    0xFFE0: FF FF FF FF E4 F6 E4 F6   FF FF E4 F6 E4 F6 E4 F6 | ................
    0xFFF0: E4 F6 E4 F6 E4 F6 FF FF   E4 F6 E4 F6 E4 F6 BA F6 | ................
    
    and I can see that the reset vector @ 0xFFFE is still pointing at the start of my bootloader main, though, shouldnt it be pointing to the main application vector table?

    Thank you in advance.

  • So, I was able to test my two projects (Booloader and main App) and am going to answer my own questions as it might be helpful to other people.

    mil meh said:
    1- Do I need to make any changes to cmd file of the bootloader project aside the start and length of the flash?

    Well, Apparently not, the only thing need to be modified is the flash location in which u want to put your bootloader.

    mil meh said:
    2- I have tried to program the flash with FET-PRO430, though when I try to load the second project with CCS 5.3, it erases the previously written part of the flash. Is there any setting that needs to be set so we can debug the project in CCS?

    I am still not sure about this part and reading through the forum, implies that there is no direct way of debugging the two projects. Though reading the memory dump can give the idea. Moreover, it might be useful to test each individual part by themselves or create a third project only for debugging to make sure you actually jump to where you are supposed to based on you interrupt type.

    mil meh said:

    3- This is what I have done for my main App cmd file:

    3443.AppCmd.txt
    /******************************************************************************/
    /* lnk_msp430f2232.cmd - LINKER COMMAND FILE FOR LINKING MSP430F2232 PROGRAMS     */
    /*                                                                            */
    /*   Usage:  lnk430 <obj files...>    -o <out file> -m <map file> lnk.cmd     */
    /*           cl430  <src files...> -z -o <out file> -m <map file> lnk.cmd     */
    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    /* These linker options are for command line linking only.  For IDE linking,  */
    /* you should set your linker options in Project Properties                   */
    /* -c                                               LINK USING C CONVENTIONS  */
    /* -stack  0x0100                                   SOFTWARE STACK SIZE       */
    /* -heap   0x0100                                   HEAP AREA SIZE            */
    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    
    
    /****************************************************************************/
    /* SPECIFY THE SYSTEM MEMORY MAP                                            */
    /****************************************************************************/
    
    MEMORY
    {
        SFR                     : origin = 0x0000, length = 0x0010
        PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
        PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
        RAM                     : origin = 0x0200, length = 0x0200
        INFOA                   : origin = 0x10C0, length = 0x0040
        INFOB                   : origin = 0x1080, length = 0x0040
        INFOC                   : origin = 0x1040, length = 0x0040
        INFOD                   : origin = 0x1000, length = 0x0040
        FLASH                   : origin = 0xE000, length = 0x0C00
     /* Reserved segment definition for the main program's interrupt vectors,* reset vector, branch vectors. */
        BRINTVEC                : origin = 0xFE00, length = 0x180
    
        INT00                   : origin = 0xEFE0, length = 0x0002
        INT01                   : origin = 0xEFE2, length = 0x0002
        INT02                   : origin = 0xEFE4, length = 0x0002
        INT03                   : origin = 0xEFE6, length = 0x0002
        INT04                   : origin = 0xEFE8, length = 0x0002
        INT05                   : origin = 0xEFEA, length = 0x0002
        INT06                   : origin = 0xEFEC, length = 0x0002
        INT07                   : origin = 0xEFEE, length = 0x0002
        INT08                   : origin = 0xEFF0, length = 0x0002
        INT09                   : origin = 0xEFF2, length = 0x0002
        INT10                   : origin = 0xEFF4, length = 0x0002
        INT11                   : origin = 0xEFF6, length = 0x0002
        INT12                   : origin = 0xEFF8, length = 0x0002
        INT13                   : origin = 0xEFFA, length = 0x0002
        INT14                   : origin = 0xEFFC, length = 0x0002
        RESET                   : origin = 0xEFFE, length = 0x0002
    
        /* Reserved main interrupt vectors space. */
        MAININTVEC     	        : origin = 0xFFE0, length = 0x0020
    }
    
    /****************************************************************************/
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY                              */
    /****************************************************************************/
    
    SECTIONS
    {
        .bss        : {} > RAM                /* GLOBAL & STATIC VARS              */
        .data       : {} > RAM                /* GLOBAL & STATIC VARS              */
        .sysmem     : {} > RAM                /* DYNAMIC MEMORY ALLOCATION AREA    */
        .stack      : {} > RAM (HIGH)         /* SOFTWARE SYSTEM STACK             */
    
        .text       : {} > FLASH              /* CODE                              */
        .cinit      : {} > FLASH              /* INITIALIZATION TABLES             */
        .const      : {} > FLASH              /* CONSTANT DATA                     */
        .cio        : {} > RAM                /* C I/O BUFFER                      */
    
        .pinit      : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
        .init_array : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
        .mspabi.exidx : {} > FLASH            /* C++ CONSTRUCTOR TABLES            */
        .mspabi.extab : {} > FLASH            /* C++ CONSTRUCTOR TABLES            */
    
        .infoA     : {} > INFOA              /* MSP430 INFO FLASH MEMORY SEGMENTS */
        .infoB     : {} > INFOB
        .infoC     : {} > INFOC
        .infoD     : {} > INFOD
    
        .mainintvec : {} > MAININTVEC        /* MAIN PROGRAM INT VECTOR TABLE     */
    
        .brintvec : {} > BRINTVEC            /* BRANCH INST PROGRAM INT VECTOR TABLE */
    
        /* MSP430 INTERRUPT VECTORS          */
    
        .int00       : {}               > INT00
        .int01       : {}               > INT01
        PORT1        : { * ( .int02 ) } > INT02 type = VECT_INIT
        PORT2        : { * ( .int03 ) } > INT03 type = VECT_INIT
        .int04       : {}               > INT04
        ADC10        : { * ( .int05 ) } > INT05 type = VECT_INIT
        USCIAB0TX    : { * ( .int06 ) } > INT06 type = VECT_INIT
        USCIAB0RX    : { * ( .int07 ) } > INT07 type = VECT_INIT
        TIMERA1      : { * ( .int08 ) } > INT08 type = VECT_INIT
        TIMERA0      : { * ( .int09 ) } > INT09 type = VECT_INIT
        WDT          : { * ( .int10 ) } > INT10 type = VECT_INIT
        .int11       : {}               > INT11
        TIMERB1      : { * ( .int12 ) } > INT12 type = VECT_INIT
        TIMERB0      : { * ( .int13 ) } > INT13 type = VECT_INIT
        NMI          : { * ( .int14 ) } > INT14 type = VECT_INIT
        .reset       : {}               > RESET  /* MSP430 RESET VECTOR         */
    }
    
    /****************************************************************************/
    /* INCLUDE PERIPHERALS MEMORY MAP                                           */
    /****************************************************************************/
    
    -l msp430f2232.cmd
    
    

    memory dump: 

    2063.MemView.txt
    === Information Memory Segments  0x1000 - 0x10FF ======
    
    0x1000:       ------- b l a n k ----(all 0xFF)------- 
    
    
    0x10F0: FF FF FF FF FF FF AC 8A   81 8F 85 8E 79 8D AF 86 | ............y...
    
    ========== Main Memory Segments  0xE000 - 0xFFFF ======
    
    
    0xE000: 0A 12 09 12 3F 40 00 00   3F 90 01 00 19 28 3F 40 | ....?@..?....(?@
    0xE010: 00 00 3F 90 01 00 14 28   3A 40 00 00 3A 80 00 00 | ..?....(:@..:...
    0xE020: 3A 50 03 00 0A 11 0A 11   39 40 00 00 3C 49 7F 4C | :P......9@..<IL
    0xE030: 4F 4F 0F 5F 1F 4F 00 00   3D 49 8F 12 1A 83 F6 23 | OO._.O..=I.....#
    0xE040: 3F 40 00 00 3F 90 00 00   08 24 3A 40 00 00 02 3C | ?@..?....$:@...<
    0xE050: 3F 4A 8F 12 3A 90 00 00   FB 23 30 40 AA E0 B2 40 | ?J..:....#0@...@
    0xE060: 80 5A 20 01 D2 42 FA 10   56 00 D2 42 FB 10 57 00 | .Z ..B..V..B..W.
    0xE070: 32 D2 F2 F0 DF 00 2E 00   F2 D0 20 00 2A 00 F2 F0 | 2......... .*...
    0xE080: DF 00 29 00 FF 3F 31 40   00 04 B0 12 B6 E0 0C 93 | ..)..?1@........
    0xE090: 02 24 B0 12 00 E0 0C 43   B0 12 5E E0 B0 12 BA E0 | .$.....C..^.....
    0xE0A0: 34 41 35 41 36 41 37 41   38 41 39 41 3A 41 30 41 | 4A5A6A7A8A9A:A0A
    0xE0B0: 82 43 20 01 00 13 1C 43   30 41 03 43 FF 3F FF FF | .C ....C0A.C.?..
    0xE0C0:       ------- b l a n k ----(all 0xFF)------- 
    
    
    0xEFE0: FF FF FF FF B0 E0 B0 E0   FF FF B0 E0 B0 E0 B0 E0 | ................
    0xEFF0: B0 E0 B0 E0 B0 E0 FF FF   B0 E0 B0 E0 B0 E0 86 E0 | ................
    0xF000:       ------- b l a n k ----(all 0xFF)------- 
    
    
    0xF600: 0A 12 09 12 3F 40 00 00   3F 90 01 00 19 28 3F 40 | ....?@..?....(?@
    0xF610: 00 00 3F 90 01 00 14 28   3A 40 00 00 3A 80 00 00 | ..?....(:@..:...
    0xF620: 3A 50 03 00 0A 11 0A 11   39 40 00 00 3C 49 7F 4C | :P......9@..<IL
    0xF630: 4F 4F 0F 5F 1F 4F 00 00   3D 49 8F 12 1A 83 F6 23 | OO._.O..=I.....#
    0xF640: 3F 40 00 00 3F 90 00 00   08 24 3A 40 00 00 02 3C | ?@..?....$:@...<
    0xF650: 3F 4A 8F 12 3A 90 00 00   FB 23 30 40 DE F6 B2 40 | ?J..:....#0@...@
    0xF660: 80 5A 20 01 D2 42 FA 10   56 00 D2 42 FB 10 57 00 | .Z ..B..V..B..W.
    0xF670: 32 D2 F2 F0 DF 00 2E 00   F2 D0 20 00 2A 00 F2 D0 | 2......... .*...
    0xF680: 20 00 29 00 B0 12 9E F6   7C 93 04 24 F2 F0 DF 00 |  .).....|..$....
    0xF690: 29 00 03 3C F2 D0 20 00   29 00 0C 43 30 41 0C 43 | )..<.. .)..C0A.C
    0xF6A0: 3E 40 00 E0 0F 43 3F 90   FF 07 05 34 3C EE 1F 53 | >@...C?....4<..S
    0xF6B0: 3F 90 FF 07 FB 3B 4C 4C   30 41 31 40 00 04 B0 12 | ?....;LL0A1@....
    0xF6C0: EA F6 0C 93 02 24 B0 12   00 F6 0C 43 B0 12 5E F6 | .....$.....C..^.
    0xF6D0: B0 12 EE F6 34 41 35 41   36 41 37 41 38 41 39 41 | ....4A5A6A7A8A9A
    0xF6E0: 3A 41 30 41 82 43 20 01   00 13 1C 43 30 41 03 43 | :A0A.C ....C0A.C
    0xF6F0: FF 3F FF FF FF FF FF FF   FF FF FF FF FF FF FF FF | .?..............
    0xF700:       ------- b l a n k ----(all 0xFF)------- 
    
    
    0xFFE0: FF FF FF FF E4 F6 E4 F6   FF FF E4 F6 E4 F6 E4 F6 | ................
    0xFFF0: E4 F6 E4 F6 E4 F6 FF FF   E4 F6 E4 F6 E4 F6 BA F6 | ................
    
    and I can see that the reset vector @ 0xFFFE is still pointing at the start of my bootloader main, though, shouldnt it be pointing to the main application vector table?

    I believe it is right, so the main interrupt vector always point to the bootloader and then bootloader passes the PC to the start of main applications:

    ex: if the program starts at 0xE000 (like in my case) and the main application reset interrupt is at 0xEFFE (again in my case), then you simply need to do :

    (*((void (*)(void))(*(unsigned int *)0xEFFE)))();

    this is what im doing to test if a program is written at my 0xE000 address:

    if(readFlash()==0xFF)   // its just for testing and no CRC is being done, where read flash just reads the flash bytes
       (*((void (*)(void))(*(unsigned int *)0xFFFE)))();            // start of boot loader
    else
        (*((void (*)(void))(*(unsigned int *)0xEFFE)))();          // start of main application

    ------------------------------------------------------------------------------

    The last but not the least, it seems like using the custom bootloader has caused my timer_A0 interrupt to happen faster and not consistent. It could be due to ~5cc delay of jumping to the actual interrupt vector table. I still need t look into it and welcome any suggestions or workarounds.



  • mil meh said:

    2- I have tried to program the flash with FET-PRO430, though when I try to load the second project with CCS 5.3, it erases the previously written part of the flash. Is there any setting that needs to be set so we can debug the project in CCS?

    I am still not sure about this part and reading through the forum, implies that there is no direct way of debugging the two projects. Though reading the memory dump can give the idea. Moreover, it might be useful to test each individual part by themselves or create a third project only for debugging to make sure you actually jump to where you are supposed to based on you interrupt type.

    [/quote]

    IIRC, you can configure the debugger to only erase teh used segments. So if the application you want to debug only uses the area 0x8000 to 0xf1ff (including its moved vector table), the remaining (and any full-segments holes inside the project) will be left untouched. The debugger will only erase those segments it needs to write the new firmware to. The default, however, is erasing the whole MSP, as this is by magnitudes faster (all segments are erased simultaneously by a mass erase, instead of each one after the other)

    mil meh said:
    I can see that the reset vector @ 0xFFFE is still pointing at the start of my bootloader main, though, shouldnt it be pointing to the main application vector table?

    No, the original reset vector must point to the bootloader, or else it will never be executed. THe bootloader then has to determine whether to do something, or to proceed program execution to the address in the 'moved' vector table, which is the entry point of the application startup code (which is not the address of main, if you use C!)

    mil meh said:
    if(readFlash()==0xFF)   // its just for testing and no CRC is being done, where read flash just reads the flash bytes
       (*((void (*)(void))(*(unsigned int *)0xFFFE)))();            // start of boot loader
    else
        (*((void (*)(void))(*(unsigned int *)0xEFFE)))();          // start of main application

    Well, actually 0xfffe should point to this test. And it will either forward to the application, through the 0xEFFE secondary reset vector, or enter the bootloader directly, not through the reset vector.

    mil meh said:
    it seems like using the custom bootloader has caused my timer_A0 interrupt to happen faster and not consistent.

    Normally not. However, your bootlaoder may do some adjustments (e.g. to the clock system or the timer config) that differ from power-on defaults, but your application simply assumes power-on defaults. And won't notice that the bootloader has changed something.

  • Thank you very much for the response. I still have some questions and appreciate if you could respond to them:

    Jens-Michael Gross said:

    if(readFlash()==0xFF)   // its just for testing and no CRC is being done, where read flash just reads the flash bytes
       (*((void (*)(void))(*(unsigned int *)0xFFFE)))();            // start of boot loader
    else
        (*((void (*)(void))(*(unsigned int *)0xEFFE)))();          // start of main application

    Well, actually 0xfffe should point to this test. And it will either forward to the application, through the 0xEFFE secondary reset vector, or enter the bootloader directly, not through the reset vector.

    [/quote]

    Well, What im doing above is to see if anything is written in my main app flash address (0xE000) and if so, I jump to secondary reset vector. I will later use msp430f2252 and will check if a new FW is written at some location and if so I will copy that to 0xE000 (in my case) and erase the image. so it will be like:

    if (new_FW @ 0xXXXX ) then

       move new_FW to 0xE000 (my case)

    either way  

     go to 0xEFFE (reset vector of main app)

    Though you said:

    Jens-Michael Gross said:
    THe bootloader then has to determine whether to do something, or to proceed program execution to the address in the 'moved' vector table, which is the entry point of the application startup code (which is not the address of main, if you use C!)

    The question is how can I make 0xFFFE point to this. I mean I know I can declare this as a function and put it on a defined address but how can I make reset vector to point to this new address instead of going to the start of the bootloader. Do i have to make like an asm file to make it branch to that address? or can I do something like:

    #pragma vector=RESET_VECTOR,

    __interrupt void ISR_Reset(void){

       and put the above code in here?
    }

    Another issue is, I realized that I in fact fail in reaching my goals as PC does go to the start of main app but then it jumps to 0xE096 which is for some reason 0x3FFF, which I believe is due to the fact that my main App interrupt vector is not properly set and im in a while loop, I see the following:

    0xEFF0: FF FF C2 E0 FF FF FF FF   FF FF FF FF FF FF 98 E0 

    and after doing :

    #pragma vector=NMI_VECTOR,WDT_VECTOR,ADC10_VECTOR,TIMERB0_VECTOR,TIMERB1_VECTOR,PORT1_VECTOR,PORT2_VECTOR,USCIAB0RX_VECTOR,

    USCIAB0TX_VECTOR
    __interrupt void ISR_trap(void){

    WDTCTL = 0; // Write to WDT with a wrong password
    }

    it changes to :

    0xEFF0: FF FF C2 E0 D0 E0 FF FF   D0 E0 D0 E0 D0 E0 98 E0

    which makes sense as 0xE0C2 is my timer_A0 ISR. So at this point I think there is something wrong with my proxy_asm file. I modified my proxy file as following:

    7752.proxy.txt
    ;*******************************************************************************
    ;   interrupt proxy.asm
    ;
    ;   This file is used to fix the interrupt table and route MSP430F5419 hardware
    ;   interrupt requests to the Main Program using proxy routines / vectors.
    ;
    ;   W. Goh
    ;   Texas Instruments Inc.
    ;   April 2010
    ;   Built with Code Composer Studio v4.2 Build: 07005
    ;*******************************************************************************
    ;-------------------------------------------------------------------------------
    ; The following code section is used to define variables to allow
    ; accessing the interrupt vectors which are defined by the main program.
    ;-------------------------------------------------------------------------------
    INT0_PROXY       .equ  0xEFE0                ; 0xEFE0 RTC
    INT1_PROXY       .equ  0xEFE2                ; 0xEFE2 Port 2
    PORT1_PROXY   	 .equ  0xEFE4                ; 0xEFE4 USCI B3 Receive/Transmit
    PORT2_PROXY  	 .equ  0xEFE6                ; 0xEFE8 USCI A3 Receive/Transmit
    INT4_PROXY  	 .equ  0xEFE8                ; 0x5C5A USCI B1 Receive/Transmit
    ADC10_PROXY  	 .equ  0xEFEA                ; 0xEFEA USCI A1 Receive/Transmit
    USCIAB0TX_PROXY  .equ  0xEFEC                ; 0x5C5E Port 1
    USCIAB0RX_PROXY  .equ  0xEFEE                ; 0x5C60 Timer1_A3 CC1-2, TA1
    TIMERA1_PROXY	 .equ  0xEFF0                ; 0x5C62 Timer1_A3 CC0
    TIMERA0_PROXY    .equ  0xEFF2                ; 0x5C64 DMA
    WDT_PROXY  	 	 .equ  0xEFF4                ; 0x5C66 USCI B2 Receive/Transmit
    INT11_PROXY  	 .equ  0xEFF6                ; 0x5C68 USCI A2 Receive/Transmit
    TIMERB1_PROXY 	 .equ  0xEFF8                ; 0x5C6A Timer0_A5 CC1-4, TA
    TIMERB0_PROXY 	 .equ  0xEFFA                ; 0x5C6C Timer0_A5 CC0
    NMI_PROXY     	 .equ  0xEFFC                ; 0x5C6E ADC
    RESET_PROXY   	 .equ  0xEFFE                ; 0xEFFE USCI B0 Receive/Transmit
    
    
                    .cdecls C,LIST, "msp430.h"
    ;-------------------------------------------------------------------------------
    ; The following code section contains the actual ISR implementation
    ; for all possible MSP430F5419 interrupt sources. All that is being done
    ; here is an indirect jump to the address that is stored in the
    ; main program's virtual interrupt vector table. Other than a 5 CPU
    ; cycle overhead added to each ISR call, there are no side effects of
    ; doing this.
    ; Also, interrupt vectors not implemented on the device are trapped and
    ; not forwarded to the main program.
                    .sect   ".brintvec"         ; Assemble to branch interrupt
                                                ; memory
    ;-------------------------------------------------------------------------------
    INT0_ISR              BR      &INT0_PROXY         ; Indirect jump using proxy
    INT1_ISR        	  BR      &INT1_PROXY         ; Indirect jump using proxy
    PORT1_ISR   		  BR      &PORT1_PROXY         ; Indirect jump using proxy
    PORT2_ISR  			  BR      &PORT2_PROXY         ; Indirect jump using proxy
    INT4_ISR        	  BR      &INT4_PROXY         ; Indirect jump using proxy
    ADC10_ISR     	      BR      &ADC10_PROXY         ; Indirect jump using proxy
    USCIAB0TX_ISR         BR      &USCIAB0TX_PROXY     ; Indirect jump using proxy
    USCIAB0RX_ISR  		  BR      &USCIAB0RX_PROXY     ; Indirect jump using proxy
    TIMERA1_ISR   		  BR      &TIMERA1_PROXY       ; Indirect jump using proxy
    TIMERA0_ISR           BR      &TIMERA0_PROXY       ; Indirect jump using proxy
    WDT_ISR     		  BR      &WDT_PROXY           ; Indirect jump using proxy
    INT11_ISR        	  BR      &INT11_PROXY         ; Indirect jump using proxy
    TIMERB1_ISR   		  BR      &TIMERB1_PROXY   	   ; Indirect jump using proxy
    TIMERB0_ISR  	      BR      &TIMERB0_PROXY       ; Indirect jump using proxy
    NMI_ISR      		  BR      &NMI_PROXY      	   ; Indirect jump using proxy
    RESET_ISR    		  BR      &RESET_PROXY         ; Indirect jump using proxy
    DUMMY_ISR        	  mov.w    #0,&WDTCTL
    ;-------------------------------------------------------------------------------
    ; The following code section populates the actual MSP430F5419 interrupt
    ; vectors to point to code sections within the boot loader code. In these
    ; code sections, an indirect jump is performed and with this the interrupt
    ; requests are routed to the main program.
    ;-------------------------------------------------------------------------------
                .sect   ".mainintvec"
    
                .word   DUMMY_ISR                  ; 0xFFD2 RTC
                .word   DUMMY_ISR                  ; 0xFFD2 RTC
                .word   PORT1_ISR            	   ; 0xFFD4 Port 2
                .word   PORT2_ISR            	   ; 0xFFD6 USCI B3 Receive/Transmit
                .word   DUMMY_ISR          		   ; 0xFFD8 USCI A3 Receive/Transmit
                .word   ADC10_ISR           	   ; 0xFFEA Timer0_A5 CC1-4, TA
                .word   USCIAB0TX_ISR              ; 0xFFEC Timer0_A5 CC0
                .word   USCIAB0RX_ISR              ; 0xFFEE ADC
                .word   TIMERA1_ISR                ; 0xFFF0 USCI B0 Receive/Transmit
                .word   TIMERA0_ISR                ; 0xFFF2 USCI A0 Receive/Transmit
                .word   WDT_ISR                    ; 0xFFF4 Watchdog Timer
                .word   DUMMY_ISR                  ; 0xFFF6 Timer0_B7 CC1-6, TB
                .word   TIMERB1_ISR                ; 0xFFF8 Timer0_B7 CC0
                .word   TIMERB0_ISR             ; 0xFFFA User Non-maskable
                .word   NMI_ISR                    ; 0xFFFC System Non-maskable
                .word   RESET_ISR                  ; 0xFFFE Reset
    ;-------------------------------------------------------------------------------
                .end
    
    , though the interrupt doesnt go where it s supposed to as it resets the uC (possibly due to writing 0 into WDCTL) and again to bootlaoder. So how can I make sure that the actual interrupt vector gets populated to point to code section whithin the bootloader code as I believe my .sevt "mainintvec" in interrupt_proxy file fails to do so.

    Thanx

  • mil meh said:
    The question is how can I make 0xFFFE point to this. I mean I know I can declare this as a function and put it on a defined address but how can I make reset vector to point to this new address instead of going to the start of the bootloader.

    Well, the typical way to do it would be to integrate this test into the bootloader. The test will either jump to the application or continue (copy the data). So 0xFFFE points to the bootloader which does the check by itself.
    If you don't do it this way, you'll have actually three projects: the checking code, the bootloader and the application.

    mil meh said:
    The question is how can I make 0xFFFE point to this. [...]how can I make reset vector to point to this new address instead of going to the start of the bootloader. Do i have to make like an asm file to make it branch to that address? or can I do something like:

    #pragma vector=RESET_VECTOR,
    __interrupt void ISR_Reset(void){

       and put the above code in here?
    }

    I don't know whether it works for IAR or CCS this way, but it is exactly how I did put my own reset handler in place with MSPGCC. (well, slightly different syntax)

    Note that this ISR cannot exit. There is no return address on the stack. In fact, the stack isn't initialized at this point and the stack pointer likely points to 0x0000, causing trouble if you want to put something on stack or use local variables.

    Your proxy file looks as if it could do what it should.

    However, I noticed that the comments won't match the labels.:

    " .word   ADC10_ISR                  ; 0xFFEA Timer0_A5 CC1-4, TA"

    The address info in the comments matches the position of the entry (assuming that the size of .mainintvec and the number of vectors match, so RESET_ISR ends up at 0xFFFE), but the labels make the CPU jumping to the wrong proxy then.

  • Jens-Michael Gross said:

    Your proxy file looks as if it could do what it should.

    However, I noticed that the comments won't match the labels.:

    " .word   ADC10_ISR                  ; 0xFFEA Timer0_A5 CC1-4, TA"

    Yeah, I didnt change the comments but the labels are correct, however for some reason, i'm unable to branch to secondary table. I'm thinking of using an alternative and manually make the intr vectors jump to my secondary intr vector table in bootloader, like:


    #pragma vector=TIMERA0_VECTOR
    __interrupt void timera0_ISR(void){

    (*((void (*)(void))(*(unsigned int *)0xEFF2)))();   // where 0xEFF2 is where my timer_A0 ISR located in main application.
    }

    The above works partially as it jumps to application's timer's ISR but after it goes back to bootloader which resets the main application. Therefore,  Im still trying to get use of proxy file if I find out wuts wrong with it! Like, do I need to include the asm file anywhere or the linker knows wut it is automatically? Because when I check the map file i see:

    BRINTVEC 0000fe00 00000022 00000000 00000022 RWIX
    MAININTVEC 0000ffe0 00000020 00000000 00000020 RWIX

    which means I defined them but never used them!!

  • mil meh said:
    I'm thinking of using an alternative and manually make the intr vectors jump to my secondary intr vector table in bootloader, like:
    #pragma vector=TIMERA0_VECTOR
    __interrupt void timera0_ISR(void){
    (*((void (*)(void))(*(unsigned int *)0xEFF2)))();   // where 0xEFF2 is where my timer_A0 ISR located in main application.
    }

    That's a bad idea. THis will generate a whole ISR that calls an ISR. You cannot call an ISR. An ISR ends with an RTI whcih expects the status register on stack. But you cannot put the status register on stack yourself. Not where you would need it.
    Also, even if this were possible, the compiler will generate framing code. Since you call a function, the processor registers used for funciton parameter passing need to be preserved on stack. So you waste a lot of processor scycles and additional stack space.

    mil meh said:
    do I need to include the asm file anywhere

    You need to add it to the project source file settings, so it is processed by the assembler and included into the build by the linker.

  • Jens-Michael Gross said:
    You need to add it to the project source file settings, so it is processed by the assembler and included into the build by the linker.

    I've been searching the project properties up and down and still couldnt find anything to help me solve the issue. I have looked over the properties of the the example project and there s nothing set to read the asm. so any help will be appreciated in this regard.

  • I think i found my own answer:

    Its in Project Properties -> Build -> MSP430 Compiler -> Processor Options -> Silicon version :application binary interface : coffabi

    According to Compiler manual:

    "COFF ABI :

    COFF ABI is the only ABI supported by older compilers. To generate object files compatible with older
    COFF ABI object files, you must use COFF ABI (--abi=coffabi, the default). This option must also be  

    when assembly hand-coded assembly source files intended to be used in a COFF ABI application."

    It works as expected now.However, now I need to think of a way of using the bootloader as whats happening now is: the main application points all the main interrupt to my secondary table and they do the trick but it means that bootloader is useless.

    I think, now I know wuat Jens-Michael meant by having 0xFFFE always point to bootloader, which will decide if it needs to jump to main app or nor. So here is what i changed in interrupt_proxy. asm

      .word   0xf6b6                ; where 0xf6b6 is the start of bootlader. where it will jump to main app if there exists any.


    Now, whuts happening is as follows:

    When i debug the main application, it takes a while and then it shows:

    Can't find a source file at "/tmp/TI_MKLIB3cHxjO/SRC/boot.c"
    Locate the file or edit the source lookup path to include its location.

    Though, after this message I can start the debug and it works just fine. I think the problem is it takes along time for the uC to set up that it shows the message. I used to have the same problem with msp430f5419 which in that case I added : WDTCTL = WDTPW + WDTHOLD; in pre_init.c file. I did the same for this uC and named it boot.c. The error doesnt get generated and works just fine.

    However, when I debug my LED which is blinking by every interrupt that I get from TimerA0 is way faster than when I program the flash. So, I assume Im not totally out of the woods but hopefully will fix this bug and report the solution here.

  • So, I'll post my last thoughts on this subject. Unfortunately, I wasnt able to use COFFABI as my program wouldnt fit in the uC that I chose. So, I came up with a better solution, I stuck to the previous eabi settings which reduced the code size, but as I mentioned before, I couldnt use the asm file with the project. So, wut I did is, instead of creating a secondary table for all the interrupt, I created another reset vector which would be only pointing to the start of my bootloader, while my main application reset vector is pointing to the start of the main app. Hence, all the interrupts are at their default location and only the RESET vector has different address.

    RESET : origin = 0xFE9E, length = 0x0002   // main app reset vector

    RESET_env : origin = 0xFFFE, length = 0x0002   // default reset

    Then I placed this segment in the code:

    #pragma DATA_SECTION( az , ".reset_env" );
    const unsigned short az = 0xFB44;     // reset to start of bootloader

    It should be noted that the compiler most likely ignore the above code due to optimization, hence, one need to use param az somewhere in the code. So upon startup, PC goes to 0xFB44, where my bootloader is in which I check for new FW and after copying the new FW. I jump to the main application reset vector(0xFE9E, in my case).

     




  • Hi,

    Following this topic ive created a bootloader and main application with the bootloader jumping to the main app and visa versa. 

    The problem im having is with using the proxy asm example, as the Main application is in the 20bit Flash memory region the ASM proxy example doesnt work. I dont really want to move the main application to the 16bit area. Does anybody have any ideas on how to resolve?

    Thanking you in advance.

    D

    Ive totally separated the flash memory region for the two applications as shown below.

    ----------MSP430F5228------------------------------------------------------------------

    Main App = 0x10000-0x2437F

    Main App Interrupt Vec table = 0x24380 - 0x243FF

    ----------------------------------------------------------------------------

    Bootloader App = 0x4400 - 0xFDFF

    Bootloader App Interrupt Vec table = 0xFF80 - 0xFFFF

    ----------------------------------------------------------------------------

  • Des said:
    The problem im having is with using the proxy asm example, as the Main application is in the 20bit Flash memory region the ASM proxy example doesnt work. I dont really want to move the main application to the 16bit area. Does anybody have any ideas on how to resolve?

    The addresses stored in the vector table at FF80-FFFF can only be 16-bit addresses. As such, if you want to access code that is in 20-bit upper memory, you need an additional jump table in 16-bit memory that includes the "long" jumps to your 20-bit addresses.

  • Anybody got any examples as this sounds like assembler not my strong point :)

    D

  • As the smallest block of Flash you can clear is 512bytes.

    1: The upper 512byte memory that have IRQ vectors should be fixed and never cleared.
        I has a list of addresses to fixed IRQ service locations, these fixed locations has a rewritable list of re-jumps to new   location due to new firmware will compile in to different lengths and segment addresses etc.

    2: You need to take care of if a crash happens right between clearing this table and a new one is reloaded does not hang the BSL.

    It could probably be 99% fool proof, I'm not sue if 100% is doable until I think about it some more.

    My simple NMI UART BSL, simple writes back the RST and NMI vector right away (points to the BSL) after doing a mass-erase and pray that nothing happens during those uS when in a limbo state.
    And the BLS simple don't write to memory that are not $ffff when it's block filling in the rest of the vector table.

  • For the main application i have successfully mapped the interrupt vectors to RAM (reserved by *.xcl file) and proven the code runs in the 16bit Flash area using the example http://processors.wiki.ti.com/index.php/MSP430_FAQ#Is_there_a_way_to_re-allocate_the_interrupt_vector_on_MSP430.3F. Happy days.

    Im still having a problem with the application when it is pushed up to the 20bit flash area. The application runs, but as soon as one of the interrupts fires the application fails.

    1. Any suggestions?

    2. Ive found no reference to how a typical *xcl file is set up for a bootloader and main application. Does anybody have and IAR examples?

    Thanking you in advance.

    D

    PS. Also the main application uses printf statement, would this cause any problems with an application running in 20bit flash region?

  • If your ISR is located above 64k (has a 20-bit address), then you need to generate a stub that resides in lower 64k (16-bit address) and does a jump to the upper address location. The vector table can only point to code in the lower 64k. Of course the stub can also jump to an ISR in the lower 64k, so if you use this approach, it is universal. But does cost some additional clock cycles.

    You can create your secondary interrupt table as an array of 32 bit address values. The real vector table points to an array of indirect jump instructions in the lower 64k (can be fused together with the vector table to the flash segment 0x0FE00-.0x0FFFF) which do an indirect jump using the (twice as large) secondary vector table. You won’t declare the ISR then with the vector pragma (the interrupt attribute is still needed), but rather manually insert their function name into the array that forms the secondary vector table.

  • ..interesting. Ive already implemented the secondary interrupt table (32bit) but its held in RAM using SYSRIVECT. Ive made sure that a segment in RAM is clear and the secondary Interrupt table mapped to it.

    My thoughts were that leaving the original vector table in flash with size (0xFF80 - FFFF) (16bit) would allow the bootloader application to function correctly then mapping int vectors to RAM would allow the main application to run (which it does but the interrupt doesnt work - or course), its always the last bit that fails lol

    Any other ideas?

    Des

  • is SYSRIVECT only compatible with 16bit flash memory space?

     

    D

  • The secondary interrupt table is the very same as the primary one – only the address it is read from is changed to the end of ram instead of end of lower 64k. So it makes no difference – it still points to lower 64k only and your ISRs must begin there.

  • ...does this mean that the lower 64k of flash of the MSP430F5228 can only contain ISR.

    Also is SYSRIVECT (used to map interrupt vectors to ram) compatible with upper 20bit flash memory? Nothing ive read so far tells me it isnt but all tests have worked on applications in the 16bit area and not 20bit.

    Is there anyway of having it placed in the upper 20bit flash segment and executing ISR's from there? 

    Im looking to put together a bootloader application in 16bit flash and  main application in the 20bit flash area. Has anybody succeed in this? The MSP430 architecture is proven playful to say the least.

    Any views would be grateful.

    D

  • Yes, the entry point of an ISR needs to be in the lower 64k. Always. No exception. However, it may then branch to code in the extended memory area. That’s why I suggested the vectors pointing to a fixed location with an indirect jump, while the jump utilized 20/32 bit addresses from a custom jumptable (a function-pointer table that points to the ISRs). However, there is one problem: the compiler/linker will automatically put all ISRs with the interrupt keyword into lower 64k. And without this keyword, the compiler won’t generate the proper entry and exit code (like saving R12-R15, and doing a RETI instead of a RETA at the end). You’d have to manipulate the linker script to allow ISRs going into upper memory, while the jumps are fixed in lower memory.
    Instead of a jump, you may declare the ISR just containing an (indirect) call to the real ISR which turns into a normal function then. But this raises another problem: since the ISR is a normal function now, you’ll add execution time for call and return, and the compiler will need to save R12 to R15 before (and restore them after) the call, even if not needed. This significantly increases the ISR latency and execution overhead. It’s your choice which way to go.

  • Jens-Michael Gross said:
    Instead of a jump, you may declare the ISR just containing an (indirect) call to the real ISR which turns into a normal function then.

    If you go this route, I believe that means that you lose the capability to use the intrinsics that modify the SR (to exit LPM, for instance). Or you then have to do something crafty like putting that part in the 16-bit code section.

  • Hi All,

    Thank you all for your comments, 

    Ive managed to get this working after a bit of playing. It looks like (as suggested) the ISR need to be within the 16bit flash segment. With this said ive insured that the bootloader occupies a 20k area of 16 bit flash, and the rest assigned to the main application spread over 16 to 20bit flash. The main application uses RAM vector mapping with ISR defined in 16 bit flash for main application. Magic :)

    Des

  • You’re right, if you use a function call inside an ISR; you cannot modify the stored status (e.g. for exiting LPM) inside the called function.
    As I said the called function is a normal function then, and therefore cannot use the “exit” intrinsic.
    So this way may be a bit more convenient, as it can be done in pain C, but limits the compatibility regarding these special features.
    (that's a problem you also had with the ISR stubs generated by GRACE - I don't know whether this has changed since the early versions)

  • Jens-Michael Gross said:
    However, there is one problem: the compiler/linker will automatically put all ISRs with the interrupt keyword into lower 64k. And without this keyword, the compiler won’t generate the proper entry and exit code (like saving R12-R15, and doing a RETI instead of a RETA at the end). You’d have to manipulate the linker script to allow ISRs going into upper memory, while the jumps are fixed in lower memory.

    Looking at the TI MSP430 compiler there are two aspects for interrupts:

    a) The #pragma vector is what places the function in the lower 64K.

    b) The __interrupt keyword is what causes the compiler to use the RETI instruction.

    Therefore, with a interrupt function which is to be called via an indirect jump table, the __interrupt vector should be used, but with no #pragma vector. This is shown in the MSPBoot example applications.

  • I'm not sure whether #pragma or __interrupt will cause the funciton to be placed in the lower 64k. The #pragma for sure causes the ISR address being written into the vector table - it generates the table entry.
    The __interrupt will cause all registers to be considered clobbered on use (on normal functions, the registers used for parameter passing and return are not saved and restored) and it will generate a RETI instead of RET/RETA. It also allows the use of the _ON_EXIT intrinsics in this function.
    But it makes sense to have th e#pragma causing the 16bit placement too, since an interrupt function may well be in upper memory as long as it doesn't need to be called through the vector table. E.g. an ISR in lower 64k may jump (not call!) to different "ISRs" in upper memory, and everything, including the intrinsics, will still work perfectly.
  • Will it work for msp430f5528? I tried it, but couldn't succeeded, my device always enter into BSL mode. I work with CCSv6.
  • IIRC, the device enters BSL mode (or goes into LPM4) if 0xFFFE contains 0xFFFF, that means. there is no reset vector to start an application.
    However, Williams answer was from 2010 and some things have changed since.
    Wat exactly did you try?

**Attention** This is a public forum