ZHCABY5D December   2022  – September 2025 MSPM0C1105 , MSPM0C1106 , MSPM0G1105 , MSPM0G1106 , MSPM0G1107 , MSPM0G1505 , MSPM0G1506 , MSPM0G1507 , MSPM0G3105 , MSPM0G3106 , MSPM0G3107 , MSPM0G3505 , MSPM0G3506 , MSPM0G3507 , 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.   摘要
  3.   商标
  4. 1简介
    1. 1.1 引导加载程序概念
    2. 1.2 MSPM0 引导加载程序结构
      1. 1.2.1 基于 ROM 的 BSL
      2. 1.2.2 带有基于闪存的插件接口的基于 ROM 的 BSL
      3. 1.2.3 基于闪存的辅助 BSL
    3. 1.3 MSPM0 BSL 功能和演示摘要
  5. 2BSL 主机实现摘要
  6. 3非主闪存中的 BSL 配置(配置 NVM)
    1. 3.1 非主闪存简介
    2. 3.2 示例 – 使用 Sysconfig 禁用 PA18 BSL 调用引脚
  7. 4引导加载程序主机
    1. 4.1 MCU 主机代码简介
      1. 4.1.1 硬件连接
      2. 4.1.2 TXT 到头文件的转换
      3. 4.1.3 使用演示的分步操作
    2. 4.2 PC 主机示例
      1. 4.2.1 准备映像文件和密码文件
      2. 4.2.2 使用 GUI 的步骤
  8. 5引导加载程序目标
    1. 5.1 基于 ROM 的默认 BSL
      1. 5.1.1 UART 接口
      2. 5.1.2 I2C 接口
    2. 5.2 基于闪存的插件接口演示
      1. 5.2.1 UART 接口
        1. 5.2.1.1 使用演示的分步操作
        2. 5.2.1.2 如何调试插件接口代码
      2. 5.2.2 I2C 接口
      3. 5.2.3 SPI 接口
      4. 5.2.4 CAN 接口
    3. 5.3 辅助 BSL 演示
      1. 5.3.1 基于闪存的辅助 BSL 从 0x1000 开始
      2. 5.3.2 基于闪存的辅助 BSL 从 0x0000 开始
        1. 5.3.2.1 MSPM0C 基于闪存的 0x0 地址 BSL 演示
        2. 5.3.2.2 实时固件更新
  9. 6常见问题
    1. 6.1 链接器文件修改
    2. 6.2 由 CCS 恢复出厂设置以恢复器件
  10. 7参考资料
  11. 8修订历史记录

MSPM0C 基于闪存的 0x0 地址 BSL 演示

由于 MSPMC 器件没有基于 ROM 的 BSL,因此器件必须使用基于闪存的 BSL,并且每次上电或复位时它必须从 0x0 地址开始运行调用检测代码。

在此演示中,当器件上电或复位时,器件将首先进入辅助 BSL 代码,在 BSL 复位处理程序中,器件将检测 BSL 调用条件(空白检测、GPIO 调用或软件调用),以决定是需要保持在 BSL 代码中以进行固件更新,还是通过将 PC 设置为应用程序的起始地址来进入应用程序代码。对于此演示,请勿包含应用程序代码 CRC 校验,您可以参阅 MSP430FRBoot – 适用于 MSP430™ FRAM 大型存储器模型器件的主存储器引导加载程序和无线更新 应用手册。

目前在此演示中使用以下代码在复位处理程序 ISR 中将 PC 设置为应用程序起始地址。

 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(); }

还有另一种简单的方法可以执行如下跳转(APP_AREA_START_ADDR 是保存中断向量表的应用程序区域起始地址,移位 4 个字节即可获取复位处理程序地址)

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

如果出现一些跳转问题,请尝试以下汇编代码;如果引导代码和应用程序代码共享某些 SRAM 区域,此汇编代码会先清除 RAM,然后跳转到应用程序的起始地址。

 __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"
 );

如果器件支持 ECC SRAM,可添加 ECC 的定义。在此演示中,应用程序起始地址保存在地址 0x7004,根据您的应用程序起始地址对此进行更改。

如果在外设初始化之后放置跳转(在执行 main() 函数之前不调用跳转函数),这里有几点需要注意:

  • 不要在 ISR 中跳转(复位处理程序 ISR 除外)。
  • 禁用全局中断(可以使用此函数 __disable_irq; 并需要通过调用 __enable_irq; 在应用程序代码中将此启用)→ 复位已使用的所有外设 → 清除所有待处理的 NVIC IRQ(调用此 API NVIC_ClearPendingIRQ(IRQn_Type IRQn))→ 如果需要,清除 RAM → 跳转到应用程序代码起始地址。