编辑 | blame | 历史 | 原始文档

STM32H743 Flash区域重新规划说明

Flash区域分配(双Bank架构)

Bank1 (0x08000000 - 0x080FFFFF, 1MB)

区域 起始地址 结束地址 大小 用途 说明
Boot区 0x08000000 0x0001FFFF 128KB Bootloader 裸机Boot程序,负责APP选择和跳转
参数表区 0x08020000 0x0803FFFF 128KB Flash参数 存储Boot标记、系统参数等
路径文件区 0x08040000 0x0805FFFF 128KB 路径数据 存储割草路径文件
保留区 0x08060000 0x0807FFFF 128KB 保留 预留扩展空间
APP1区 0x08080000 0x080BFFFF 256KB APP固件 应用程序1(主固件)
APP2区 0x080C0000 0x080FFFFF 256KB APP固件 应用程序2(备份/新固件)

Bank2 (0x08100000 - 0x081FFFFF, 1MB)

区域 起始地址 结束地址 大小 用途 说明
OTA下载区 0x08100000 0x0813FFFF 256KB 加密固件 OTA下载的加密固件临时存储
OTA解密区 0x08140000 0x0817FFFF 256KB 解密固件 解密后的固件临时存储
用户数据区 0x08180000 0x081FFFFF 512KB 用户数据 可用于存储日志、配置等

Boot标记结构体

存储位置

  • APP1标记: 0x08020000 (参数表区起始)
  • APP2标记: 0x08020020 (偏移32字节)

数据结构 (32字节)

typedef struct {
    uint32_t u32Magic;           // 魔术字:0x424F4F54 ("BOOT")
    uint32_t u32Version;         // 标记版本号
    uint32_t u32AppAddress;      // APP启动地址(0x08080000或0x080C0000)
    uint32_t u32AppSize;         // APP固件大小(字节)
    uint32_t u32AppCRC;          // APP固件CRC32校验和
    uint32_t u32AppVersion;      // APP固件版本号
    uint8_t  u8ActiveFlag;       // 激活标志:1=已激活,0=未激活
    uint8_t  u8ConfirmFlag;      // 确认标志:1=APP已确认启动,0=未确认
    uint8_t  u8Reserved[2];      // 保留字段
    uint32_t u32BootMarkCRC;     // 本结构体的CRC32
} BootMark_t;

Bootloader启动流程

1. 上电复位 → Bootloader (0x08000000)
   ↓
2. 读取APP1和APP2的Boot标记
   ↓
3. 验证标记有效性(Magic + CRC)
   ↓
4. 选择APP规则:
   - 优先级1:u8ActiveFlag=1 且 u8ConfirmFlag=1
   - 优先级2:版本号更高(u32AppVersion)
   ↓
5. 设置VTOR寄存器到APP地址
   ↓
6. 跳转到APP的Reset Handler
   ↓
7. 如果跳转失败,延迟3秒后尝试另一个APP
   ↓
8. 两次尝试都失败 → LED快速闪烁(错误状态)

OTA升级流程

APP端操作流程

1. HTTP下载加密固件 → 0x08100000 (Bank2 OTA下载区)
   ↓
2. AES-256-CBC解密 → 0x08140000 (Bank2 OTA解密区)
   ↓
3. 校验和验证(文件末尾:[4字节CRC][0x0D][0x0A])
   ↓
4. 校验成功 → 调用OTA_UpdateBootMark()
   ↓
5. 判断当前APP(通过VTOR寄存器)
   - 当前=APP1 → 目标=APP2 (0x080C0000)
   - 当前=APP2 → 目标=APP1 (0x08080000)
   ↓
6. 擦除目标APP区域(256KB)
   ↓
7. 复制解密固件到目标APP区域
   ↓
8. 写入新的Boot标记:
   - u32AppAddress = 目标地址
   - u32AppSize = 固件大小
   - u32AppCRC = 固件CRC32
   - u32AppVersion = 当前版本+1
   - u8ActiveFlag = 1 (激活)
   - u8ConfirmFlag = 0 (未确认)
   ↓
9. 提示用户重启
   ↓
10. 系统重启 → Bootloader选择新APP启动

APP编译配置

APP工程链接脚本 (STM32H743.sct)

LR_IROM1 0x08080000 0x00040000  {    ; APP编译地址:固定0x08080000
  ER_IROM1 0x08080000 0x00040000  {
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00020000  {
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x24000000 0x00080000  {
   .ANY (+RW +ZI)
  }
}

Bootloader工程链接脚本 (STM32H743_Boot.sct)

LR_IROM1 0x08000000 0x00020000  {    ; Boot区:128KB
  ER_IROM1 0x08000000 0x00020000  {
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00020000  {
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x24000000 0x00080000  {
   .ANY (+RW +ZI)
  }
}

重要说明

  1. APP编译地址固定:所有APP固件编译到0x08080000,通过Bootloader的VTOR重定位支持在不同地址运行

  2. 双APP冗余:系统始终保留两个APP副本,OTA升级时写入另一个区域,避免单点故障

  3. 版本号管理:每次OTA成功后,版本号自动+1,Bootloader优先选择高版本

  4. 安全机制

  • 新固件首次启动时u8ConfirmFlag=0(未确认)
  • APP需主动调用BootMark_Write()设置u8ConfirmFlag=1(确认启动成功)
  • Bootloader优先选择已确认的固件
  1. 降级保护:如果新固件启动失败,Bootloader会自动切换回旧固件

工程文件修改清单

Bootloader工程 (STM32H743_Boot)

  • ✅ 修改链接脚本:128KB Boot区域
  • ✅ 新增BootMark.c/h:Boot标记管理模块
  • ✅ 简化main.c:裸机Boot逻辑(删除FreeRTOS)
  • ✅ 删除APL下所有应用层文件(除BootMark外)
  • ✅ 删除FML下网络、GPS、运动控制等模块
  • ✅ 保留HAL库、MCUFlash、Uart(调试用)

APP工程 (STM32H743)

  • ✅ 修改链接脚本:APP编译地址改为0x08080000
  • ✅ 复制BootMark.c/h到APL文件夹
  • ✅ OTAUpgrade.c添加OTA_UpdateBootMark()函数
  • ✅ OTA校验成功后自动调用OTA_UpdateBootMark()

使用步骤

首次烧录

  1. 编译Bootloader工程 → 生成STM32H743_Boot.bin
  2. 使用ST-Link烧录Bootloader到0x08000000
  3. 编译APP工程 → 生成STM32H743.bin
  4. 使用ST-Link烧录APP到0x08080000
  5. 手动创建APP1的Boot标记(或通过调试命令)

OTA升级

  1. APP通过HTTP下载加密固件
  2. 自动解密、校验、写入另一个APP区域
  3. 自动更新Boot标记
  4. 重启系统 → Bootloader选择新APP启动

回滚操作

如果新固件有问题,Bootloader会自动在3秒后切换回旧固件。


创建时间: 2025-12-21
版本: v1.0
作者: AI Assistant