SLAAE88D December   2022  – September 2025 MSPM0C1105 , MSPM0C1106 , MSPM0G1105 , MSPM0G1106 , MSPM0G1107 , MSPM0G1505 , MSPM0G1506 , MSPM0G1507 , MSPM0G3105 , MSPM0G3106 , MSPM0G3107 , MSPM0G3505 , MSPM0G3506 , MSPM0G3507 , MSPM0H3216 , MSPM0L1105 , MSPM0L1106 , MSPM0L1227 , MSPM0L1227-Q1 , MSPM0L1228 , MSPM0L1228-Q1 , MSPM0L1303 , MSPM0L1304 , MSPM0L1304-Q1 , MSPM0L1305 , MSPM0L1305-Q1 , MSPM0L1306 , MSPM0L1306-Q1 , MSPM0L1343 , MSPM0L1344 , MSPM0L1345 , MSPM0L1346 , MSPM0L2227 , MSPM0L2227-Q1 , MSPM0L2228 , MSPM0L2228-Q1

 

  1.   1
  2.   Abstract
  3.   Trademarks
  4. 1 Introduction
    1. 1.1 Bootloader Concept
    2. 1.2 MSPM0 Bootloader Structure
      1. 1.2.1 ROM-Based BSL
      2. 1.2.2 ROM-Based BSL With Flash-Based Plug-In Interface
      3. 1.2.3 Flash-Based Secondary BSL
    3. 1.3 MSPM0 BSL Features and Demos Summary
  5. 2BSL Host Implementation Summary
  6. 3BSL Configuration in Non-Main (Configuration NVM)
    1. 3.1 Non-Main Introduction
    2. 3.2 Example – Disable PA18 BSL Invoke Pin With Sysconfig
  7. 4Bootloader Host
    1. 4.1 MCU Host Code Introduction
      1. 4.1.1 Hardware Connection
      2. 4.1.2 TXT to Header File Conversion
      3. 4.1.3 Step-by-Step Using the Demo
    2. 4.2 PC Host Example
      1. 4.2.1 Prepare the Image File and Password File
      2. 4.2.2 Steps to Using the GUI
  8. 5Bootloader Target
    1. 5.1 Default ROM-Based BSL
      1. 5.1.1 UART Interface
      2. 5.1.2 I2C Interface
    2. 5.2 Flash-Based Plug-In Interface Demos
      1. 5.2.1 UART Interface
        1. 5.2.1.1 Step by Step Using the Demo
        2. 5.2.1.2 How to Debug the Plug-In Interface Code
      2. 5.2.2 I2C Interface
      3. 5.2.3 SPI Interface
      4. 5.2.4 CAN Interface
    3. 5.3 Secondary BSL Demo
      1. 5.3.1 Flash-Based Secondary BSL Start From 0x1000
      2. 5.3.2 Flash-Based Secondary BSL Start From 0x0000
        1. 5.3.2.1 Flash-Based 0x0 Address BSL Demo for MSPM0C
        2. 5.3.2.2 Live Firmware Update
  9. 6Common Questions
    1. 6.1 Linker File Modification
    2. 6.2 Factory Reset by CCS to Recover Device
  10. 7References
  11. 8Revision History

Flash-Based 0x0 Address BSL Demo for MSPM0C

Due to MSPMC device does not have the ROM based BSL, the device must use flash based BSL and must be started from 0x0 address to run the invoke detection code every time when power up or reset.

In this demo, when device power up or reset, the device goes into secondary BSL code first, in BSL reset handler the device can detect the BSL invoke conditions (blank detection, GPIO invoke or software invoke) to decide if need to stay in the BSL code to do firmware update, or go into application code by setting PC to application's start address. For this demo, do not include application code CRC check, you can refer to the MSP430FRBoot – Main Memory Bootloader and Over-the-Air Updates for MSP430™ FRAM Large Memory Model Devices, application note.

Currently in this demo using, the following code is used to set the PC of application's start address in reset handler ISR.

 uint32_t *appResetHandler = (uint32_t *) (MAIN_APP_START_ADDR + VTOR_RESET_HANDLER_OFFSET);
 appPointer FlashBSL_applicationStart = (appPointer) * (appResetHandler);
 /* Before branch check if the address of reset handler is a valid Flash address */
 if ((*((uint32_t *) MAIN_APP_RESET_VECTOR_ADDR) >= MAIN_APP_START_ADDR) &&
 (*((uint32_t *) MAIN_APP_RESET_VECTOR_ADDR) < (MAIN_APP_START_ADDR + DEVICE_FLASH_SIZE))) {
 FlashBSL_applicationStart(); }

There is another simple way to do the jump as below(APP_AREA_START_ADDR is the application's area start address that saved the interrupt vector table, shift 4 bytes to get the reset handler address)

/*! Jumps to application using the reset vector address */
#define TI_MSPBoot_APPMGR_JUMPTOAPP()     {((void (*)()) (*(uint32_t *)(APP_AREA_START_ADDR + 4))) ();}

If there are some jumping issue, please try the assembly code below that clear the RAM before jump to application's start address if the boot code and application code are sharing some SRAM area.

 __asm(
#if defined(__GNUC__)
 ".syntax unified\n" /* Load SRAMFLASH register*/
#endif
 "ldr r4, = 0x41C40018\n" /* Load SRAMFLASH register*/
 "ldr r4, [r4]\n"
 "ldr r1, = 0x03FF0000\n" /* SRAMFLASH.SRAM_SZ mask */
 "ands r4, r1\n" /* Get SRAMFLASH.SRAM_SZ */
 "lsrs r4, r4, #6\n" /* SRAMFLASH.SRAM_SZ to kB */
#if defined ECC
 "ldr r1, = 0x20300000\n" /* Start of ECC-code */
 "adds r2, r4, r1\n" /* End of ECC-code */
 "movs r3, #0\n"
 "init_ecc_loop: \n" /* Loop to clear ECC-code */
 "str r3, [r1]\n"
 "adds r1, r1, #4\n"
 "cmp r1, r2\n"
 "blo init_ecc_loop\n"
#endif 
 "ldr r1, = 0x20200000\n" /* Start of NON-ECC-data */
 "adds r2, r4, r1\n" /* End of NON-ECC-data */
 "movs r3, #0\n"
 "init_data_loop:\n" /* Loop to clear ECC-data */
 "str r3, [r1]\n"
 "adds r1, r1, #4\n"
 "cmp r1, r2\n"
 "blo init_data_loop\n"
 //Jump to Reset_Handler
 "ldr r0, = 0x7004\n" //FLASH_SBSL_INTVEC in .cmd file+ 4
 "ldr r0, [r0]\n"
 "blx r0\n"
 );

Add define of ECC if the device support ECC SRAM. For this demo the application start address is saved at address 0x7004, change this based on your application start address.

If you put the jump after peripheral initialization (not call the jump function before execute main() function), few points here need to take care:

  • Do not jump in the ISR(except reset handler ISR) .
  • Disable global interrupt(can use this function __disable_irq; and need to enable this in application's code by call __enable_irq;) → reset all peripherals that been used → clear all pending NVIC IRQs (call this API NVIC_ClearPendingIRQ(IRQn_Type IRQn) ) → clear the RAM if needed → jump to application code start address.