# 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字节) ```c 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优先选择已确认的固件 5. **降级保护**:如果新固件启动失败,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