• 正文
  • 相关推荐
申请入驻 产业图谱

STM32MP1 自举程序编程:USB DFU/USART 协议全解析

9小时前
115
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

STM32MP1 系列(MP15x/MP13x)自举程序通过 USB DFU(Device Firmware Upgrade)和 USART 协议,实现非易失性存储器(NVM)的嵌入式编程,支持外部 Flash(NAND/NOR/eMMC/SD)、OTP、PMIC NVM 等器件的固件下载与烧录。本文基于 AN5275 应用笔记,拆解两种协议的核心配置、编程序列、指令集与实操要点,覆盖 “从复位编程” 和 “从 U-Boot 编程” 两大场景,助力快速落地编程服务。

资料获取:STM32MP1 系列自举程序中使用的 USB DFU/USART 协议

1. 协议核心概述

1.1 核心用途与支持范围

  • 嵌入式编程服务:通过 STM32CubeProgrammer 工具,经 USB/USART 接口将二进制文件写入 NVM,涉及 ROM 代码、TF-A(FSBL)、U-Boot(SSBL)三级协同;
  • 支持 NVM 类型:外部 Flash(NAND/NOR/eMMC/SD 卡)、片上 OTP、PMIC(如 STPMIC1)的 NVM;
  • 适配系列:STM32MP15x(ROM 代码与 TF-A 共享 USB 描述符)、STM32MP13x(FSBL 阶段需重新枚举 USB)。

1.2 编程序列两大核心场景

  • 场景 1:从复位编程(首次烧录):通过启动引脚选择外设,ROM 代码加载 TF-A→TF-A 初始化 DDR 并加载 U-Boot→U-Boot 解析布局文件并编程 NVM;
  • 场景 2:从 U-Boot 编程(固件更新):已烧录器件通过按键、控制台指令或 Linux 重启模式进入编程模式,直接由 U-Boot 提供编程服务。

1.3 关键概念:阶段 ID(Phase ID)

阶段 ID 用于标识待下载的分区,是协议通信的核心标识,关键 ID 含义如下:

  • 0x00:布局文件(TSV 格式,定义分区列表);
  • 0x01:FSBL(TF-A),由 ROM 代码加载;
  • 0x03:SSBL(U-Boot,含 FIP 映像),由 TF-A 加载;
  • 0x10~0xF0:用户分区(uImage、dtb、rootfs 等);
  • 0xF1:虚拟分区(用于 GetPhase/SetOffset 指令);
  • 0xF2:OTP 分区;
  • 0xF4:PMIC NVM 分区;
  • 0xFE:操作结束;
  • 0xFF:复位(错误时返回)。

2. USART 协议详解:串口编程实现

2.1 核心配置(ROM 代码默认设置)

  • 波特率:115200;
  • 数据格式:8 位数据位 + 1 位起始位 + 1 位停止位 + 偶校验(EVEN);
  • 连接触发:ROM 代码扫描所有 USART_RX 引脚,接收 0x7F 数据帧后建立连接。

2.2 主循环与通信流程

  1. 主机发送 0x7F 触发 USART 连接;
  2. 主机通过 Get 指令获取支持的指令列表,再通过 GetPhase 获取当前阶段 ID;
  3. 按阶段 ID 下载对应映像(TF-A→U-Boot→布局文件→用户分区);
  4. 每包数据含校验和(字节异或),器件返回 ACK(0x79)、NACK(0x1F)或 ABORT(0x5F)响应;
  5. 所有分区下载完成后,发送 0xFE 标识操作结束,器件复位。

2.3 核心指令集(关键指令详解)

指令代码 指令名称 核心功能 响应格式要点
0x00 Get 获取自举程序版本与支持指令 含 ACK + 版本号 + 指令代码列表 + 尾 ACK
0x02 Get ID 获取芯片 ID 0x0500(MP15x)/0x0501(MP13x)
0x03 Get Phase 获取下一个分区 ID 含阶段 ID + 下载地址(0xFFFFFFFF 表示写入 NVM) + 附加信息
0x31 Download 下载映像到 RAM/NVM 含数据包编号 + 数据块(最大 256 字节) + 校验和
0x12 Read Partition 读取分区数据 需指定分区 ID 与偏移量,返回最多 256 字节
0x21 Start 跳转到 RAM 执行代码或刷新 NVM 地址为 0xFFFFFFFF 时完成 NVM 写入

3. USB DFU 协议详解:高速编程实现

3.1 协议基础(基于 DFU v1.1)

  • 核心差异:DFU_DETACH 在 dfuIDLE 状态可接受,返回 appIDLE 模式;不支持 STM32 MCU 的 DFUSE 扩展;
  • 核心优势:传输速率高于 USART,适合大容量映像(如 rootfs)烧录;
  • 枚举特点:通过 “替代设置” 映射分区,每个替代设置对应一个阶段 ID。

3.2 关键概念:替代设置与虚拟分区

  • 替代设置:USB 枚举时,每个分区对应一个替代设置,字符串描述符含分区 ID、大小、类型(E = 可写,A = 可读);
  • 虚拟分区 0xF1:用于核心指令交互,支持:
    • DFU_UPLOAD:获取 GetPhase 结果(阶段 ID、下载地址、偏移);
    • DFU_DOWNLOAD:SetOffset(设置分区偏移)、Start(跳转到指定地址执行)。

3.3 编程序列(以 MP15x 为例)

  1. 器件上电,ROM 代码初始化 USB 并枚举为 DFU v1.1 设备;
  2. 主机通过替代设置 1 下载 TF-A(阶段 ID=0x01),器件进入 dfuMANIFESTSYNC 状态;
  3. TF-A 启动后恢复 USB 连接(无需重新枚举),主机下载 U-Boot(阶段 ID=0x03);
  4. U-Boot 初始化后,主机下载布局文件(阶段 ID=0x00),器件重新枚举并列出所有分区替代设置;
  5. 按替代设置依次下载用户分区,每完成一个分区执行 DFU 表现(刷新 NVM);
  6. 发送 0xFE 结束操作,器件复位。

3.4 核心指令交互(基于虚拟分区 0xF1)

指令类型 核心功能 数据格式
DFU_UPLOAD GetPhase:获取当前阶段 ID 响应含阶段 ID + 下载地址 + 偏移 + 附加信息
DFU_DOWNLOAD SetOffset:设置分区偏移 数据含阶段 ID(0x00~0xF0) + 分区偏移(4 字节)
DFU_DOWNLOAD Start:执行代码 数据含 0xFF + 目标地址(4 字节)

4. 实操关键要点与避坑指南

4.1 布局文件(TSV 格式)

  • 核心作用:定义分区列表,含阶段 ID、映像路径、目标 NVM、起始地址、大小;
  • 示例字段:PhaseID ImagePath NVMTarget Address Size
  • 必须与阶段 ID 一一对应,否则会导致烧录失败。

4.2 映像预处理要求

  • 加 STM32 头文件:MP15x 用版本 1(256 字节),MP13x 用版本 2(512 字节);
  • 签名要求:封闭器件需用 SigningTool 签名,否则 ROM 代码拒绝执行;
  • 校验要求:所有传输数据含异或校验和,主机需确保数据包完整性。

4.3 错误处理与兼容性

  • 响应含义:ACK(0x79)= 成功,NACK(0x1F)= 数据错误(可重试),ABORT(0x5F)= 不可恢复错误(需复位);
  • 系列差异:MP13x 在 ROM 代码与 TF-A 之间需重新枚举 USB,MP15x 无需;
  • 调试技巧:通过 STM32CubeProgrammer 的 “-d” 选项指定映像,“-c” 指定通信接口usart/usb)。

4.4 特殊分区操作

  • OTP(阶段 ID=0xF2):仅支持特定字节写入,需通过 USART 的 Download 指令(数据包编号 = 0xF2)或 USB 替代设置 0xF2 操作;
  • PMIC NVM(阶段 ID=0xF4):需确保 PMIC 与 MCU 通信正常,仅支持特定型号(如 STPMIC1)。

STM32MP1 的 USB DFU/USART 协议是自举程序编程的核心,核心逻辑可概括为 “阶段 ID 标识分区 + 三级自举协同 + 校验保障完整性”:

  1. USART 协议适合小容量映像、无 USB 接口场景,配置简单但速率较低;
  2. USB DFU 协议适合大容量烧录,速率快但需关注枚举与替代设置;
  3. 实操中需重点关注布局文件正确性、映像签名与校验,以及 MP15x/MP13x 的系列差异。

两种协议均兼容 STM32CubeProgrammer 工具,无需手动编写复杂通信代码,按阶段 ID 顺序下载即可完成 NVM 编程。

相关推荐