1. 课程导入

各位同学好,欢迎来到这门实战课。我是你们的讲师,一个在嵌入式领域摸爬滚打了十几年的老工程师。

咱们这门课,讲的是 Bootloader IAP 编程与固件升级。说白了,就是怎么让你的单片机产品在出厂之后,还能通过串口、USB 或者网络来更新程序。这可不是什么花哨的功能,而是工业级产品的标配。我当年做第一个量产项目时,就因为没设计升级功能,产品发出去后发现有 bug,结果只能一家一家去现场拆机烧录……那滋味,真不好受。

所以,从这节课开始,我会把 IAP 的原理、双区备份的策略、串口烧录的协议,一步步带着你实现出来。咱们不玩虚的,直接上代码、上电路。

1.1 什么是 Bootloader?

Bootloader,就是芯片上电后第一个运行的程序。它的任务很简单:决定接下来跑哪个应用程序。

你可以把它想象成电脑的 BIOS。BIOS 先检查硬盘,然后引导操作系统。单片机的 Bootloader 也一样,它检查串口有没有升级指令,如果有,就接收新固件并写入 Flash;如果没有,就直接跳转到用户程序。

核心要点: Bootloader 本身也是一个独立的程序,存储在 Flash 的起始地址(比如 0x08000000)。它和用户程序共享同一颗芯片,但互不干扰。

1.2 IAP 原理:在运行中升级

IAP(In-Application Programming)是 Bootloader 的灵魂。它允许应用程序在运行时,通过某种通信接口(串口、SPI、CAN 等)接收数据,然后调用芯片内部的 Flash 擦写函数,把数据写入指定的 Flash 区域。

为什么会需要 IAP?因为传统的 ISP(In-System Programming)需要硬件工具(如 J-Link、ST-Link)才能烧录。而 IAP 只需要一根串口线,甚至可以通过无线模块远程升级。你想想看,产品已经卖到客户手里了,总不能让人家拆机接烧录器吧?

IAP 的流程大致是这样的:

  1. Bootloader 启动,检查升级标志或串口指令。
  2. 如果有升级请求,Bootloader 擦除用户程序区。
  3. 通过串口接收固件数据包,逐页写入 Flash。
  4. 校验完成后,跳转到用户程序入口。
  5. 如果没有升级请求,直接跳转。

1.3 双区备份策略:给自己留条后路

升级最怕什么?怕写到一半断电,或者数据传错了。结果就是——芯片变砖。

双区备份就是为了解决这个问题。我们把 Flash 分成三个区域:

  • Bootloader 区:固定不变,负责启动和升级。
  • App A 区:当前运行的程序。
  • App B 区:备份区,存放上一次稳定的固件。

升级时,新固件写入 App B 区。写入完成后,校验通过,才把 App B 标记为有效,下次启动从 B 区运行。如果升级失败,Bootloader 检测到校验错误,自动回滚到 App A 区。这样,就算升级过程中断电,设备也能正常启动。

我的经验: 我曾经在一个项目中偷懒,只用了单区升级。结果客户升级时网络闪断,设备直接变砖,售后成本高得吓人。从那以后,双区备份成了我所有项目的标配。

下面这张图展示了双区备份的 Flash 布局和升级流程:

双区备份 Flash 布局与升级流程 Bootloader 区 0x08000000 - 0x0800FFFF App A 区(运行中) 0x08010000 - 0x0803FFFF App B 区(备份) 0x08040000 - 0x0806FFFF 上电 检查升级标志 串口指令 / GPIO 有升级请求 擦除 App B 区 接收新固件 校验 & 标记有效 CRC / MD5 成功 跳转 App B 运行新固件 校验失败 → 回滚 App A

1.4 开发板选型与资料准备

本课程选用 STM32F103C8T6 作为主控芯片。为什么选它?因为它是市面上最普及的 Cortex-M3 芯片,资料多、价格便宜、Flash 容量适中(64KB),非常适合做 IAP 教学。

你需要准备以下硬件和软件:

类别 项目 说明
硬件 STM32F103 最小系统板 淘宝 10 元左右,带 USB 转串口
硬件 USB 转 TTL 模块 CH340G 或 CP2102,用于串口通信
硬件 杜邦线 + 面包板 连接调试用
软件 Keil MDK 或 IAR EWARM 二选一,本课程以 Keil 为例
软件 STM32CubeMX 生成初始化代码
软件 串口调试助手 推荐 SSCOM 或 MobaXterm
软件 ST-Link Utility 或 J-Flash 用于首次烧录 Bootloader
注意: 如果你用的是其他型号的 STM32,比如 F4 或 G0 系列,原理完全一样,只是 Flash 地址和页大小不同。我会在课程中标注出差异点。

1.5 Keil / IAR 环境配置

我个人习惯用 Keil,因为它的调试器集成度高,工程管理也顺手。但 IAR 的编译器优化更好,适合对代码体积有要求的项目。这里我以 Keil 为例,带你走一遍配置流程。

1.5.1 安装与激活

去 Keil 官网下载 MDK-ARM 最新版,安装后使用注册机激活。注意,Keil 的 License 是绑定电脑的,换了电脑需要重新激活。

1.5.2 新建工程

  1. 打开 Keil,点击 Project → New μVision Project。
  2. 选择芯片型号:STM32F103C8。
  3. 在弹出的 Manage Run-Time Environment 中,勾选 CMSIS → CORE 和 Device → Startup。
  4. 点击 OK,工程就建好了。

1.5.3 配置 Flash 下载算法

这一步很关键。因为 Bootloader 和用户程序分别占用不同的 Flash 区域,我们需要告诉烧录器不要覆盖 Bootloader。

  1. 点击 Project → Options for Target(或快捷键 Alt+F7)。
  2. 切换到 Target 标签页,设置 IROM1 的起始地址和大小。比如用户程序从 0x08010000 开始,大小 0x30000。
  3. 切换到 Utilities 标签页,点击 Settings,在 Flash Download 中勾选 Erase Full Chip 或 Erase Sectors。建议选 Erase Sectors,只擦除用户程序区。
避坑指南: 我曾经因为忘记修改 IROM1 的起始地址,结果烧录用户程序时把 Bootloader 覆盖了,导致芯片变砖。后来我养成了一个习惯:每次新建工程,第一件事就是检查 Target 页面的地址配置。

1.5.4 生成 .hex 文件

在 Output 标签页,勾选 Create HEX File。这样编译后会自动生成 .hex 文件,方便串口烧录。

1.6 串口调试助手使用

串口调试助手是 IAP 调试的必备工具。它负责把 PC 上的固件文件通过串口发送给 Bootloader。

我推荐使用 SSCOM,因为它支持:

  • 自定义波特率(我们常用 115200 或 921600)
  • 文件发送(直接选择 .bin 或 .hex 文件)
  • HEX 显示和发送
  • 自动发送(用于测试)

基本设置步骤:

  1. 打开 SSCOM,选择正确的 COM 口(在设备管理器中查看)。
  2. 设置波特率 115200,数据位 8,停止位 1,无校验。
  3. 点击 打开串口。
  4. 在 Bootloader 启动后,串口会打印提示信息,比如 "Waiting for firmware..."。
  5. 点击 发送文件,选择编译好的 .bin 文件,点击发送。
注意: 串口通信的波特率越高,传输越快,但误码率也会增加。如果传输过程中经常出现校验错误,可以适当降低波特率,比如降到 57600 或 38400。