ESC
输入关键词搜索文章标题和内容

嵌入式MCU烧录原理深度解析

本文由 linuxROS 整理发布,首发于 linuxros.cn,转载请注明出处。

嵌入式MCU烧录原理深度解析

MCU存储架构、SWD与串口两种烧录路径、Bootloader工作机制、MCUboot安全启动流程、常见问题排查,一文讲透烧录全链路。


一、原理简析

1.1 单片机存储"三件套"

单片机内部有三种存储器,各司其职:

  • Flash:程序代码的长期仓库,断电不丢失,按扇区擦写
  • RAM:运行时的临时工作台,断电即空,随机读写速度快
  • ROM:出厂固化的系统存储器,内置Bootloader,用户不可改

烧录的本质就是:把二进制文件从PC写入Flash的指定地址。

flowchart TB A["单片机存储系统"] --> B["Flash<br/>长期仓库"] A --> C["RAM<br/>临时工作台"] A --> D["ROM<br/>出厂配送中心"] B --> E["存程序代码·断电不丢"] C --> F["存变量堆栈·断电即空"] D --> G["存Bootloader·出厂固化"] style A fill:#E3F2FD style B fill:#E8F5E9 style C fill:#FFF8E1 style D fill:#F3E5F5 style E fill:#E8F5E9 style F fill:#FFF8E1 style G fill:#F3E5F5
存储器 特点 用途
Flash 掉电不丢失,按扇区擦写 程序代码、常量
RAM 掉电丢失,随机读写 变量、堆栈
ROM 出厂固化,用户不可改 Bootloader

1.2 两种烧录路径

二进制文件进入Flash有两条路:

来自 linuxros.cn · linuxROS
flowchart TB A["PC上的二进制文件"] --> B["路径一:SWD调试接口"] A --> C["路径二:串口/USB"] B --> D["ST-Link / J-Link"] D --> E["直接操作Flash"] C --> F["Bootloader中转"] F --> E E --> G["Flash中程序代码"] style A fill:#E3F2FD style B fill:#E8F5E9 style C fill:#FFF8E1 style D fill:#E8F5E9 style F fill:#FFF8E1 style E fill:#F3E5F5 style G fill:#E8F5E9
方式 接口 优点 缺点 适用场景
ST-Link/J-Link SWD/SWIM 速度快,可在线调试 需专用下载器 开发调试
串口/USB UART/USB DFU 无需下载器,成本低 需配置Boot引脚 量产、OTA升级

二、实操步骤

2.1 SWD方式烧录(开发调试首选)

使用ST-Link或J-Link通过SWD接口直接访问Flash,无需Bootloader参与:

# OpenOCD 烧录命令示例
openocd -f interface/stlink.cfg -f target/stm32f1x.cfg \
  -c "program firmware.bin verify reset exit 0x08000000"

2.2 串口Bootloader烧录(量产常用)

利用ROM中出厂固化的Bootloader,通过串口协议完成烧录:

# stm32flash 开源工具烧录命令
stm32flash -w firmware.bin -v -g 0x08000000 /dev/ttyUSB0

关键前提:必须将BOOT0拉高,使CPU从系统存储器启动。

2.3 Boot引脚配置

BOOT0 BOOT1 启动区域 说明
0 X Flash 正常运行用户程序
1 0 系统存储器 进入Bootloader模式
1 1 SRAM 调试用,极少使用

三、开源烧录工具选型

工具 接口 特点
stm32flash UART/I2C 跨平台命令行,GPL-2.0,量产首选
MCU-Flash-Tools UART/USB Python单脚本,支持STM32/CH32/AVR
stm32-dfu-bootloader USB DFU 支持固件验证、安全启动
MCUboot 多种 安全Bootloader,签名验证+OTA
wolfBoot 多种 轻量安全启动,加密签名

四、核心流程图

串口Bootloader烧录完整流程

flowchart TB A(["🔴 开始烧录"]) --> B["配置BOOT0=1<br/>BOOT1=0"] B --> C["按下复位键"] C --> D{"CPU读取<br/>Boot引脚"} D -->|"BOOT0=1"| E["从ROM启动<br/>Bootloader"] D -->|"BOOT0=0"| F["从Flash启动<br/>用户程序直接运行"] subgraph BL["📡 Bootloader工作阶段"] E --> G["初始化串口/USB外设"] G --> H["等待上位机发送指令"] H --> I["接收二进制数据包"] end subgraph FLASH["💾 Flash写入阶段"] I --> J["擦除Flash目标扇区"] J --> K["逐页写入Flash"] K --> L{"CRC校验通过?"} L -->|"是 ✅"| M["设回BOOT0=0"] L -->|"否 ❌"| N{"重试次数超限?"} N -->|"否"| J N -->|"是"| O(["🔴 烧录失败"]) end M --> P["复位启动"] P --> Q(["🟢 用户程序运行"]) F --> Q style A fill:#E3F2FD,stroke:#1565C0 style B fill:#E3F2FD,stroke:#1565C0 style C fill:#E3F2FD,stroke:#1565C0 style D fill:#FFF8E1,stroke:#F57F17 style E fill:#F3E5F5,stroke:#6A1B9A style F fill:#C8E6C9,stroke:#2E7D32 style BL fill:#F3E5F5,stroke:#6A1B9A,stroke-dasharray:5 5 style G fill:#E1BEE7,stroke:#6A1B9A style H fill:#E1BEE7,stroke:#6A1B9A style I fill:#E1BEE7,stroke:#6A1B9A style FLASH fill:#E3F2FD,stroke:#1565C0,stroke-dasharray:5 5 style J fill:#BBDEFB,stroke:#1565C0 style K fill:#BBDEFB,stroke:#1565C0 style L fill:#FFF8E1,stroke:#F57F17 style N fill:#FFF8E1,stroke:#F57F17 style M fill:#E8F5E9,stroke:#2E7D32 style P fill:#E8F5E9,stroke:#2E7D32 style Q fill:#C8E6C9,stroke:#2E7D32 style O fill:#FFEBEE,stroke:#C62828

MCUboot安全启动流程

MCUboot是Zephyr/Mynewt等RTOS官方推荐的安全Bootloader,支持签名验证和OTA升级:

flowchart TB A(["🔴 上电复位"]) --> B["MCUboot启动<br/>初始化Flash与加密模块"] B --> C["检查镜像元数据<br/>判断Swap类型"] C --> D{"Slot1有<br/>待升级固件?"} D -->|"有"| E["执行镜像交换<br/>Slot1→Slot0"] D -->|"无"| F{"验证Slot0<br/>签名SHA-256"} E --> F F -->|"验证通过 ✅"| G["跳转到Slot0<br/>用户程序入口"] F -->|"验证失败 ❌"| H(["🔴 启动失败<br/>系统挂起"]) G --> I(["🟢 用户程序运行"]) I --> J{"应用确认<br/>img_confirmed?"} J -->|"是"| K(["✅ 升级永久生效"]) J -->|"否<br/>下次重启"| L["MCUboot自动<br/>回滚到旧版本"] L --> G style A fill:#E3F2FD,stroke:#1565C0 style D fill:#FFF8E1,stroke:#F57F17 style F fill:#FFF8E1,stroke:#F57F17 style J fill:#FFF8E1,stroke:#F57F17 style B fill:#F3E5F5,stroke:#6A1B9A style C fill:#F3E5F5,stroke:#6A1B9A style E fill:#E3F2FD,stroke:#1565C0 style G fill:#E8F5E9,stroke:#2E7D32 style I fill:#C8E6C9,stroke:#2E7D32 style K fill:#C8E6C9,stroke:#2E7D32 style L fill:#FFF9C4,stroke:#F57F17 style H fill:#FFEBEE,stroke:#C62828

五、常见问题解决

问题 原因 解决方案
烧录后程序不运行 BOOT0未切回0 烧录完成后将BOOT0接低电平再复位
串口无法连接Bootloader 波特率不匹配 stm32flash默认57600,Bootloader支持自动检测
链接后文件比源码大很多 链接器引入库文件 检查map文件,裁剪未使用的库函数
Flash写入失败 扇区未擦除 Flash必须先擦除再写入,按扇区操作

六、总结

烧录的本质是把二进制数据写入Flash指定地址,两条路径各有适用场景:SWD接口适合开发调试,串口Bootloader适合量产和OTA升级。开源生态提供了丰富的工具链——从轻量的stm32flash到支持安全启动的MCUboot,开发者可按需选用。

版权声明

作者linuxROS
协议本作品采用 CC BY-NC-SA 4.0 许可协议:署名-非商业性使用-相同方式共享
关注欢迎关注微信公众号 linuxROS,获取更多机器人 / 嵌入式 / Linux 干货
返回首页