This thread has been locked.

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

Custom BSL development

Other Parts Discussed in Thread: CC430F5137, MSP430F5438, MSP430F5418A

I'm starting development on a bootloader for the CC430F5137. There's a bunch of articles all over the place so I thought I would summarize the steps that I took and ask a few simple questions.

  1. There is some sample bootloader code in here for the MSP430F5438, which has CCS support (super important for poor folks like me who use CCS)
  2. This has the explanations on the memory mapping in the linker file lnk_msp430f5418a.cmd, which explains what ZArea means.
  3. I modified the linker file to suit the CC430F5137, namely, I changed the RAM size and then the size of FLASH2. The file is as follows:
  4. /* ============================================================================ */
    /* Copyright (c) 2013, Texas Instruments Incorporated                           */
    /*  All rights reserved.                                                        */
    /*                                                                              */
    /*  Redistribution and use in source and binary forms, with or without          */
    /*  modification, are permitted provided that the following conditions          */
    /*  are met:                                                                    */
    /*                                                                              */
    /*  *  Redistributions of source code must retain the above copyright           */
    /*     notice, this list of conditions and the following disclaimer.            */
    /*                                                                              */
    /*  *  Redistributions in binary form must reproduce the above copyright        */
    /*     notice, this list of conditions and the following disclaimer in the      */
    /*     documentation and/or other materials provided with the distribution.     */
    /*                                                                              */
    /*  *  Neither the name of Texas Instruments Incorporated nor the names of      */
    /*     its contributors may be used to endorse or promote products derived      */
    /*     from this software without specific prior written permission.            */
    /*                                                                              */
    /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" */
    /*  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,       */
    /*  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      */
    /*  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
    /*  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,       */
    /*  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,         */
    /*  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; */
    /*  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,    */
    /*  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR     */
    /*  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,              */
    /*  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                          */
    /* ============================================================================ */
    
    /******************************************************************************/
    /* lnk_msp430f5418a.cmd - LINKER COMMAND FILE FOR LINKING MSP430F5418A 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 = 0x1C00, length = 0x0FFC
        INFOA                   : origin = 0x1980, length = 0x0080
        INFOB                   : origin = 0x1900, length = 0x0080
        INFOC                   : origin = 0x1880, length = 0x0080
        INFOD                   : origin = 0x1800, length = 0x0080
        ZAREA                   : origin = 0x1000, length = 0x0010
        BSL430_VERSION_VENDOR   : origin = 0x1010, length = 0x0001
        BSL430_VERSION_CI       : origin = 0x1011, length = 0x0001
        BSL430_VERSION_API      : origin = 0x1012, length = 0x0001
        BSL430_VERSION_PI       : origin = 0x1013, length = 0x0001
        ZAREA_CODE              : origin = 0x1014, length = 0x002E
        FLASH                   : origin = 0x1042, length = 0x07AE
        BSLSIG                  : origin = 0x17F0, length = 0x000C
        JTAGLOCK_KEY            : origin = 0x17FC, length = 0x0004
        FLASH2                  : origin = 0x8000, length = 0x7F80
        INT00                   : origin = 0xFF80, length = 0x0002
        INT01                   : origin = 0xFF82, length = 0x0002
        INT02                   : origin = 0xFF84, length = 0x0002
        INT03                   : origin = 0xFF86, length = 0x0002
        INT04                   : origin = 0xFF88, length = 0x0002
        INT05                   : origin = 0xFF8A, length = 0x0002
        INT06                   : origin = 0xFF8C, length = 0x0002
        INT07                   : origin = 0xFF8E, length = 0x0002
        INT08                   : origin = 0xFF90, length = 0x0002
        INT09                   : origin = 0xFF92, length = 0x0002
        INT10                   : origin = 0xFF94, length = 0x0002
        INT11                   : origin = 0xFF96, length = 0x0002
        INT12                   : origin = 0xFF98, length = 0x0002
        INT13                   : origin = 0xFF9A, length = 0x0002
        INT14                   : origin = 0xFF9C, length = 0x0002
        INT15                   : origin = 0xFF9E, length = 0x0002
        INT16                   : origin = 0xFFA0, length = 0x0002
        INT17                   : origin = 0xFFA2, length = 0x0002
        INT18                   : origin = 0xFFA4, length = 0x0002
        INT19                   : origin = 0xFFA6, length = 0x0002
        INT20                   : origin = 0xFFA8, length = 0x0002
        INT21                   : origin = 0xFFAA, length = 0x0002
        INT22                   : origin = 0xFFAC, length = 0x0002
        INT23                   : origin = 0xFFAE, length = 0x0002
        INT24                   : origin = 0xFFB0, length = 0x0002
        INT25                   : origin = 0xFFB2, length = 0x0002
        INT26                   : origin = 0xFFB4, length = 0x0002
        INT27                   : origin = 0xFFB6, length = 0x0002
        INT28                   : origin = 0xFFB8, length = 0x0002
        INT29                   : origin = 0xFFBA, length = 0x0002
        INT30                   : origin = 0xFFBC, length = 0x0002
        INT31                   : origin = 0xFFBE, length = 0x0002
        INT32                   : origin = 0xFFC0, length = 0x0002
        INT33                   : origin = 0xFFC2, length = 0x0002
        INT34                   : origin = 0xFFC4, length = 0x0002
        INT35                   : origin = 0xFFC6, length = 0x0002
        INT36                   : origin = 0xFFC8, length = 0x0002
        INT37                   : origin = 0xFFCA, length = 0x0002
        INT38                   : origin = 0xFFCC, length = 0x0002
        INT39                   : origin = 0xFFCE, length = 0x0002
        INT40                   : origin = 0xFFD0, length = 0x0002
        INT41                   : origin = 0xFFD2, length = 0x0002
        INT42                   : origin = 0xFFD4, length = 0x0002
        INT43                   : origin = 0xFFD6, length = 0x0002
        INT44                   : origin = 0xFFD8, length = 0x0002
        INT45                   : origin = 0xFFDA, length = 0x0002
        INT46                   : origin = 0xFFDC, length = 0x0002
        INT47                   : origin = 0xFFDE, length = 0x0002
        INT48                   : origin = 0xFFE0, length = 0x0002
        INT49                   : origin = 0xFFE2, length = 0x0002
        INT50                   : origin = 0xFFE4, length = 0x0002
        INT51                   : origin = 0xFFE6, length = 0x0002
        INT52                   : origin = 0xFFE8, length = 0x0002
        INT53                   : origin = 0xFFEA, length = 0x0002
        INT54                   : origin = 0xFFEC, length = 0x0002
        INT55                   : origin = 0xFFEE, length = 0x0002
        INT56                   : origin = 0xFFF0, length = 0x0002
        INT57                   : origin = 0xFFF2, length = 0x0002
        INT58                   : origin = 0xFFF4, length = 0x0002
        INT59                   : origin = 0xFFF6, length = 0x0002
        INT60                   : origin = 0xFFF8, length = 0x0002
        INT61                   : origin = 0xFFFA, length = 0x0002
        INT62                   : origin = 0xFFFC, length = 0x0002
        RESET                   : origin = 0xFFFE, length = 0x0002
    }
    
    /****************************************************************************/
    /* 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             */
    
    	.ZAREA      : {} > ZAREA
    	.BSL430_VERSION_VENDOR : {} > BSL430_VERSION_VENDOR
    	.BSL430_VERSION_CI     : {} > BSL430_VERSION_CI
    	.BSL430_VERSION_API    : {} > BSL430_VERSION_API
    	.BSL430_VERSION_PI     : {} > BSL430_VERSION_PI
    	.ZAREA_CODE : {} > ZAREA_CODE
    	.BSLSIG     : {} > BSLSIG
    	.JTAGLOCK_KEY : {} > JTAGLOCK_KEY
    
        .text       : {}>> FLASH | FLASH2     /* CODE                              */
        .text:_isr  : {} > FLASH              /* ISR CODE SPACE                    */
    #ifdef __LARGE_DATA_MODEL__
        .cinit      : {} > FLASH | FLASH2     /* INITIALIZATION TABLES             */
        .const      : {} > FLASH | FLASH2     /* CONSTANT DATA                     */
    #else
        .cinit      : {} > FLASH              /* INITIALIZATION TABLES             */
        .const      : {} > FLASH              /* CONSTANT DATA                     */
    #endif
        .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
        .int02       : {}               > INT02
        .int03       : {}               > INT03
        .int04       : {}               > INT04
        .int05       : {}               > INT05
        .int06       : {}               > INT06
        .int07       : {}               > INT07
        .int08       : {}               > INT08
        .int09       : {}               > INT09
        .int10       : {}               > INT10
        .int11       : {}               > INT11
        .int12       : {}               > INT12
        .int13       : {}               > INT13
        .int14       : {}               > INT14
        .int15       : {}               > INT15
        .int16       : {}               > INT16
        .int17       : {}               > INT17
        .int18       : {}               > INT18
        .int19       : {}               > INT19
        .int20       : {}               > INT20
        .int21       : {}               > INT21
        .int22       : {}               > INT22
        .int23       : {}               > INT23
        .int24       : {}               > INT24
        .int25       : {}               > INT25
        .int26       : {}               > INT26
        .int27       : {}               > INT27
        .int28       : {}               > INT28
        .int29       : {}               > INT29
        .int30       : {}               > INT30
        .int31       : {}               > INT31
        .int32       : {}               > INT32
        .int33       : {}               > INT33
        .int34       : {}               > INT34
        .int35       : {}               > INT35
        .int36       : {}               > INT36
        .int37       : {}               > INT37
        .int38       : {}               > INT38
        .int39       : {}               > INT39
        .int40       : {}               > INT40
        RTC          : { * ( .int41 ) } > INT41 type = VECT_INIT
        PORT2        : { * ( .int42 ) } > INT42 type = VECT_INIT
        .int43       : {}               > INT43
        .int44       : {}               > INT44
        USCI_B1      : { * ( .int45 ) } > INT45 type = VECT_INIT
        USCI_A1      : { * ( .int46 ) } > INT46 type = VECT_INIT
        PORT1        : { * ( .int47 ) } > INT47 type = VECT_INIT
        TIMER1_A1    : { * ( .int48 ) } > INT48 type = VECT_INIT
        TIMER1_A0    : { * ( .int49 ) } > INT49 type = VECT_INIT
        DMA          : { * ( .int50 ) } > INT50 type = VECT_INIT
        .int51       : {}               > INT51
        .int52       : {}               > INT52
        TIMER0_A1    : { * ( .int53 ) } > INT53 type = VECT_INIT
        TIMER0_A0    : { * ( .int54 ) } > INT54 type = VECT_INIT
        ADC12        : { * ( .int55 ) } > INT55 type = VECT_INIT
        USCI_B0      : { * ( .int56 ) } > INT56 type = VECT_INIT
        USCI_A0      : { * ( .int57 ) } > INT57 type = VECT_INIT
        WDT          : { * ( .int58 ) } > INT58 type = VECT_INIT
        TIMER0_B1    : { * ( .int59 ) } > INT59 type = VECT_INIT
        TIMER0_B0    : { * ( .int60 ) } > INT60 type = VECT_INIT
        UNMI         : { * ( .int61 ) } > INT61 type = VECT_INIT
        SYSNMI       : { * ( .int62 ) } > INT62 type = VECT_INIT
        .reset       : {}               > RESET  /* MSP430 RESET VECTOR         */ 
    }
    
    /****************************************************************************/
    /* INCLUDE PERIPHERALS MEMORY MAP                                           */
    /****************************************************************************/
    
    -l cc430f5137.cmd
    

Questions:

  1. In the linker file, FLASH starts at 0x1042 and FLASH2 starts at 0x8000 on the MSP430F5438. Does this mean that FLASH is used for the bootloader and FLASH2 is used for the actual application? If so, does FLASH2 = 32kB or FLASH + FLASH2 = 32kB (FLASH on CC430F5137 is 32kB)
  2. I assume that flashing the bootloader is no different from flashing user application code and that you build the application and hit the Debug button in CCS and that will download the BSL to the CC430. Is this a valid assumption?
  3. What happens if there is a bug in the custom bootloader that I made? If so, doesn't that mean that the CC430 is completely bricked? I don't believe there is any way to reflash a BSL, is there? Or in other words, since the TI BSL that accepts SBW is gone, I will not be able to reflash the CC430 via SBW any more?

  • Hi Kenny,

    Kenny Tay1 said:
    In the linker file, FLASH starts at 0x1042 and FLASH2 starts at 0x8000 on the MSP430F5438. Does this mean that FLASH is used for the bootloader and FLASH2 is used for the actual application?

    In theory, yes. To accomplish this, you'll need to create two separate projects in CCS with individual linker files (one project for the BSL code, another project for the application code) that maps the memory accordingly.

    Kenny Tay1 said:
    If so, does FLASH2 = 32kB or FLASH + FLASH2 = 32kB (FLASH on CC430F5137 is 32kB)

    Here, FLASH2 equals 32640 bytes (in Main memory), and FLASH equals 1966 bytes (in BSL memory).

    Kenny Tay1 said:
    I assume that flashing the bootloader is no different from flashing user application code and that you build the application and hit the Debug button in CCS and that will download the BSL to the CC430. Is this a valid assumption?

    Yes, assuming the linker files have been modified correctly in both CCS projects.

    Kenny Tay1 said:
    What happens if there is a bug in the custom bootloader that I made? If so, doesn't that mean that the CC430 is completely bricked? I don't believe there is any way to reflash a BSL, is there? Or in other words, since the TI BSL that accepts SBW is gone, I will not be able to reflash the CC430 via SBW any more?

    Sort of. You can reflash the BSL through JTAG if it's unlocked. If JTAG is locked, you can unlock it by writing 0x00 to the JTAGLOCK_KEY addresses (0x17FC to 0x17FF). Now, you'll be able to reflash the BSL flash and/or main flash. Also, take a look at Section 1.5.1 in the Creating a Custom Flash-Based Bootstrap Loader (BSL) app note.

    Regards,

    James

    MSP Customer Applications

  • So, am I right to say that the JTAG/SBW interfaces are able to access FLASH regardless of the bootloader? Or in other words, if JTAG is unlocked, one can write directly to FLASH via JTAG/SBW?

    I had another follow up question. Does port remapping work in the BSL? I have pins 2.0 and 2.1 mapped to UART RX and UART TX respectively but the target CC430F5137 does not respond to the UART messages coming from my Launchpad BSL interface (verified that UART RX on the target is seeing some 0's and 1's).

    Also, is there any way to single step through the BSL? It doesn't seem possible because that would require multiple devices to be attached to the SBW interface.
  • Well, as expected, remapping pins does work in the bootloader (after all, why shouldn't it?). The reason why I didn't receive any UART messages was because I had thought that UART was through the USCI instead of through the timer, which is embarrassing on my part :|

    Also, was able to single step through the BSL since loading the BSL automatically starts the main() function in the BSL.
  • I started on a custom Boot Loader for the x2xxx family like G2553
    You use a custom version of linker file, so intvec is moved further down.
    You add bootloader.c in your project and just compile as normal.

    The real reset vector goes through a firmware check and uart-out that it will  now run main()
    All uart_rx irq bytes always goes through the bootloader before it rejumps to users RX ISR.

    It will check uart byte by byte if the 32byte key matches and all times, no need to do a special toggle pin invoke.
    When a match it will erase all of flash except the last upper 512byte block where boot loader resides.
    It will then uart-out that it's ready for firmware at a rate of once every ~28sec.

      if (*(int*)0xFDFE != 0xffff){
        TXSTRING("Run main, send password at anytime to erase\r\n");
        asm (" BR &0xFDFE"); 
      }     
      TXSTRING("Ready for Firmware\r\n");  
      BCSCTL3 |= LFXT1S_2;                  // aclk = vloclk
      BCSCTL1 |= DIVA_3;                    // aclk divided by 8
      WDTCTL = WDTPW+WDTCNTCL+WDTSSEL;      // aclk sourced ~28sec
      __bis_SR_register(LPM3_bits);         // trap it
    }

**Attention** This is a public forum