目标机集成与 Boot 部署指南
本文档指导用户完成目标机(MCU)的首次部署,包括 Bootloader 烧写、APP 集成 emXCP 库、以及首次部署后的日常使用方式。
一、Boot 功能准备概述
为什么需要首次部署?
程序加载功能依赖 Bootloader + APP 双区结构:
MCU Flash 布局(STM32F407,1MB):
┌──────────────────────────────────────────────────────────┐
│ 0x08000000: emeboot (Bootloader) - 64KB │ ← 上电首先运行
│ └── 启动决策、APP有效性检查、UDS刷写服务 │
├──────────────────────────────────────────────────────────┤
│ 0x08010000: 状态区 (Sector 4) - 64KB │ ← 启动标志、分区信息
│ └── 存储"进Bootloader"标志位等 │
├──────────────────────────────────────────────────────────┤
│ 0x08020000: APP (用户程序) - 384KB │ ← emeboot跳转到这里
│ └── 用户的实际应用程序(mtrDrv样例或自有APP) │
├──────────────────────────────────────────────────────────┤
│ 0x08080000: Bank B (备分区) - 384KB │ ← 双分区回滚(可选)
└──────────────────────────────────────────────────────────┘
核心原理:
1. MCU 上电后,emeboot 先运行
2. emeboot 检查 APP 是否有效
3. 若 APP 有效 → emeboot 跳转到 APP 运行
4. 若 APP 无效或存在"进Bootloader"标志 → emeboot 停留等待 UDS 刷写
为什么不能直接用程序加载?
- 出厂 MCU Flash 是空的,没有 Bootloader
- 没有 Bootloader,UDS 服务不可用
- 必须先用 Keil + DAP 调试器 将 emeboot 烧写一次
- 之后所有 APP 升级都可以通过串口完成
准备 Boot 功能的三个关键点
| 关键点 | 说明 | 如果忽略会怎样 |
|---|---|---|
| 1. 全片擦除 | Keil 只擦除当前扇区,老代码会残留 | 烧写后仍执行老代码,APP 无法正常运行 |
| 2. VECT_TAB_OFFSET | APP 不在 Flash 起始地址,需告知 CPU 向量表位置 | emeboot 正常但 APP 无法运行(死机) |
| 3. 波特率一致 | XCP 和 UDS 共用同一串口,波特率必须相同(固定 115200) | 通信失败,程序加载卡在 0% |
二、首次部署步骤
提示:首次部署是一次性操作,之后日常开发中不再需要 DAP 调试器。
2.1 前提条件清单
请确认以下条件满足后再开始:
| 条件 | 检查方法 | 备注 |
|---|---|---|
| Keil MDK-ARM 已安装 | 打开 Keil,版本 ≥ 5.x | 需安装 STM32F4xx_DFP pack |
| DAP 调试器连接 | Keil → Debug → Settings 可识别设备 | ST-Link / J-Link 均可 |
| emeboot 工程文件 | 项目提供的 emeboot.uvprojx | Bootloader 工程 |
| APP 工程文件 | 项目提供的 mtrDrv.uvprojx | 参考样例 |
| 串口终端工具 | 串口助手、Tera Term 等 | 波特率固定 115200 |
2.2 步骤 0:全片擦除(⚠️ 必须!)
为什么必须全片擦除?
- Keil 烧写时只擦除当前工程占用的扇区
- 若目标板之前烧写过其他程序,老代码会残留
- 残留代码可能导致启动异常或执行错误逻辑
操作步骤:
- 打开任意一个 Keil 工程(emeboot 或 APP)
- 确保 DAP 调试器已连接到板子 SWD 接口
- Keil 菜单栏:Flash → Erase
- 在弹出对话框中选择 Erase Full Chip
- 点击 Start 按钮
- 等待擦除完成(输出窗口显示 "Erase Done")
重要:即使是全新的板子,也建议执行一次全片擦除,确保 Flash 状态干净。
2.3 步骤 1:烧写 emeboot(Bootloader)
打开项目提供的 emeboot.uvprojx 工程文件。
关键配置检查:
- 打开 emeboot 工程
- Target 配置(Options for Target → Target):
| 项目 | 值 | 说明 |
|---|---|---|
| IROM1 | Start=0x08000000, Size=0x10000 | Bootloader 区起始地址,64KB |
| IRAM1 | Start=0x20000000, Size=0x20000 | 主 RAM,128KB |
| IRAM2 | Start=0x10000000, Size=0x10000 | CCM RAM,64KB |
-
C/C++ 配置(Options for Target → C/C++):
- Define 必须含:TARGET_STM32, STM32F407xx, USE_HAL_DRIVER
- ⚠️ 不要定义 VECT_TAB_OFFSET(emeboot 在 Flash 起始地址,使用默认值 0x00) -
编译:按 F7 → 确认 0 Error, 0 Warning
- 烧写:Flash → Download → 确认输出:
Erase Done. Programming Done. Verify OK.
2.4 步骤 2:烧写 APP(用户程序)
打开项目提供的 mtrDrv.uvprojx(样例)或用户自有 APP 工程文件。
关键配置检查:
- 打开 APP 工程
- Target 配置(Options for Target → Target):
| 项目 | 值 | 说明 |
|---|---|---|
| IROM1 | Start=0x08020000, Size=0x60000 | APP 区起始地址,384KB ⚠️ 必须与 emeboot 配合 |
- C/C++ 配置(Options for Target → C/C++):
- Define 末尾添加:, VECT_TAB_OFFSET=0x20000
- ⚠️ 必须添加此宏,否则 APP 启动后会死机
示例:TARGET_STM32, STM32F407xx, USE_HAL_DRIVER, VECT_TAB_OFFSET=0x20000
- 编译:按 F7 → 确认 0 Error
- 烧写:Flash → Download → 确认输出:
Erase Done. Programming Done. Verify OK.
2.5 步骤 3:验证部署成功
复位设备并观察串口日志
- 复位设备(按板子复位键,或 Keil 中 Debug → Reset)
- 打开串口终端,波特率设置为 115200
- 观察启动日志:
正确的 emeboot → APP 启动日志:
[INF] === emeboot init start ===
[INF] HAL drivers registered OK
[INF] boot_decision initialized OK
[INF] No boot request flag (BKP0R=0x00000000)
[INF] === emeboot decision start ===
[INF] decision: action=1, target_bank=0, app_address=0x08020000
[INF] Jumping to APP at 0x08020000 ...
↑ 跳转成功,APP 开始运行
[APP 日志...] ← APP 正常启动输出
如果看到以下日志则表示异常:
- No valid APP found → APP 未正确烧写或向量表无效
- 日志输出后死机 → APP 的 VECT_TAB_OFFSET 配置错误
- 乱码 → 波特率不匹配(确认终端波特率为 115200)
EmeyeStudio 连接测试
- 打开 EmeyeStudio
- 配置串口设备(COM 口、波特率 115200)
- 点击 连接 XCP
- 确认连接成功(状态栏显示"已连接")
程序加载完整流程测试
- EmeyeStudio → 工具 → 程序加载
- 选择一个固件文件(.bin/.hex/.elf/.axf)
- 点击 加载
- 观察完整流程:
- ✅ XCP 进 Bootloader → 设备重启 → UDS 刷写 → 完成 → 自动重连 XCP - 再次观察串口终端,确认新 APP 正常启动
部署成功标志:
- ✅ 串口日志显示 emeboot → APP 正常跳转
- ✅ EmeyeStudio XCP 连接成功
- ✅ 程序加载完整流程正常执行
三、emXCP 库集成说明
APP 运行时需集成 emXCP 库,并支持"进 Bootloader"自定义 XCP 命令,以便 EmeyeStudio 在程序加载时触发设备从 APP 切换到 Bootloader 模式。
emXCP 库的完整集成说明(缓冲区分配、初始化、中断调用、内存要求、API 参考等)请参阅:
在目标机集成中,只需确认 APP 工程正确引入了 emXCP 库,并响应进 Bootloader 的自定义 XCP 命令即可。
四、常见问题排查
| 现象 | 原因 | 解决方法 |
|---|---|---|
| 烧写后仍执行老代码 | 未全片擦除,老代码残留 | Flash → Erase → Erase Full Chip |
| emeboot 烧写后设备无响应 | VECT_TAB_OFFSET 被错误设为 0x20000 | emeboot 工程不要定义 VECT_TAB_OFFSET |
| APP 在 0x08020000 不运行 | VECT_TAB_OFFSET 未设为 0x20000 | APP 工程 Define 中添加 VECT_TAB_OFFSET=0x20000 |
| emeboot 日志乱码 | 波特率不匹配 | 确认串口终端波特率为 115200 |
| emeboot 跳转 APP 后死机 | APP 向量表无效或 VTOR 设置错误 | 检查 APP 的 IROM1 起始地址和 VECT_TAB_OFFSET |
| 程序加载卡在 0% | 设备未进入 Bootloader 模式 | 确认 APP 集成了 XCP 进 Bootloader 命令 |
| 首次连接 XCP 或 UDS 失败 | Sector 4 残留旧动态波特率配置 | 执行一次全片擦除后重新烧写 emeboot 与 APP |