DFU
+ -

DFU RUNTIME和DFU MODE的区别

2026-10-23 本文链接为:http://www.usbzh.com/article/detail-1815.html ,欢迎转载,转载请附上本文链接。

DFU 实现原理

dfu 功能分为两个模式: runtime 模式与 dfu 模式

  1. runtime 模式: 正常工作状态,此时需要host设备发送detach命令使设备转换成dfu模式
  2. dfu 模式 : 升级状态,host设备可以读写相应分区的数据来升级设备
  • DFU Runtime → 应用固件 :设备的”门铃”,负责把主机引导到升级流程。
  • DFU Mode → Bootloader :设备的”施工队”,负责真正接收并烧写新固件。

二者通过 DETACH + 复位/跳转衔接,构成完整的 USB 固件升级链路。

dfu 具体工作流程如下:

  1. host设备给device设备发送准备升级固件命令
  2. device 在接收到命令时会卸载所有已经加载的驱动,并切换到DFU 模式
  3. host 给device发起usb reset
  4. device 发送DFU 模式下的描述符,进行重新枚举识别
  5. host 给设备发送需要升级的固件
  6. host 收到设备端数据处理成功的信息,给device发送转换模式的命令
  7. device 重新切换到 runtime 模式
  8. host 发起usb reset,并重新识别device设备

DFU模式与runtime模式的客制化流程:

  1. device 正常启动到linux,配置相关的usb device驱动使设备处于runtime模式
  2. 当用户需要升级firmware时,需要通过host端软件发送runtime模式detach命令(DFU-util -e)
  3. 当device 接收到detach命令,会通过fw_setenv工具配置uboot环境变量enter_dfu_mode为1,并重启
  4. device 重启进入uboot过程中会读取enter_dfu_mode变量的值,当为1时,执行相应的dfu命令(例dfu 0 ram 0)
    进入dfu模式并等待升级
  5. 用户通过DFU-util工具发送firmware 到对应配置分区
  6. device 收到数据包并写入相应配置分区
  7. 当升级完毕,用户使用DFU-util工具重启device
  8. device 收到重启命令,配置环境变量enter_dfu_mode为0,并重启进入linux,配置模式为runtime
    用户配置dfu流程:
  9. 编译生成fw_setenv,以便支持linux下配置uboot环境变量
    i. 使用uboot编译生成fw_setenv,并拷贝到linux 文件系统中的/etc目录
    make env; ln -sf fw_printenv fw_setenv
    ii. 配置fw_env.config,并拷贝到linux 文件系统中/etc目录
  10. linux的配置以支持usbcam以及dfu
  11. uboot的配置以支持dfu功能
  12. 设置uboot环境变量
    i. 分区表变量 dfu_alt_info
    ii. 缓存大小配置 dfu_bufsiz
维度 DFU Runtime DFU Mode
协议号 DFU_PROTOCOL_RT (0x01) DFU_PROTOCOL_DFU (0x02)
描述符 单接口,固定 18 字节(9+9) 多 alternate setting 接口(每个 alt = 一个分区,如 Flash/EEPROM)
状态机 无(始终报告 APP_IDLE) 完整 11 状态(IDLE→DNLOAD→DNBUSY→MANIFEST→…)
支持的请求 仅 DETACH、GETSTATUS(+SET_INTERFACE) 全量 DETACH/DNLOAD/UPLOAD/GETSTATUS/CLRSTATUS/GETSTATE/ABORT
功能定位 正常运行阶段,引导切入 DFU Mode 下载模式,真正收发固件
描述符结构不同
  • TDFU Runtime 只有 1 个接口,后面跟 1 个功能描述符。
  • DFU Mode 用 _TUD_DFU_ALT_1 ... _TUD_DFU_ALT_8 宏展开出多个 alternate setting(最多 8 个),每个 alt 对应一个可升级分区。

    alt是通过接口描述符的alt实现的,只是DFU走的是控制端点,故各个接口描述符下并无端点描述符。

一、DFU Runtime —— 部署在「正常运行的应用固件」里

部署位置

Runtime 接口跟着应用固件一起烧进去,是设备每天正常工作的那段代码里附带的一个”小尾巴”。它只占极小开销(一个接口描述符 + 极简的请求处理),不影响应用正常运行。

作用场景

当设备正在正常跑业务(比如鼠标在移动、U 盘在读数据、传感器在采集)时,它对外暴露 Runtime 接口,向主机宣告:”我支持固件升级,随时可以把我切进升级模式“。

典型例子

  • 一个正常工作的键盘/鼠标/传感器设备,其应用固件里带 Runtime 接口。
  • 主机运行 dfu-util -l 时,能列出设备处于 Runtime 状态。
  • 用户想升级时,执行 dfu-util -e 发 DETACH,Runtime 触发 tud_dfu_runtime_reboot_to_dfu_cb(),应用复位并跳到 bootloader。

关键点:应用固件本身不参与烧写,它只负责”听到命令 → 跳转”。


二、DFU Mode —— 部署在「Bootloader(引导加载程序)」里

部署位置

DFU Mode 接口烧在 Bootloader 里,这是一段独立的、通常常驻在 Flash 起始地址或专用区域的小程序。设备复位/跳转后,由 Bootloader 接管,此时对外暴露的是 DFU Mode 接口。

作用场景

设备进入 Bootloader 后,应用已不在运行,Bootloader 专门负责”接收新固件 → 擦写 Flash → 校验 → 跳转到新固件”。这是真正的升级执行阶段。

典型例子

  • 设备复位后 Bootloader 启动,主机用 dfu-util -d cafe -a 0 -D new_firmware.bin 下发新固件。
  • Bootloader 的 tud_dfu_download_cb() 把数据块逐块写入 Flash,tud_dfu_manifest_cb() 做校验,最后复位运行新固件。

关键点:Bootloader 专注升级,不跑业务。


三、两者的衔接关系(完整升级流程)

┌─────────────────────────────────────────────────────────────┐
│                        同一颗 MCU                           │
│                                                             │
│  ┌───────────────┐    DETACH     ┌───────────────────────┐  │
│  │   应用固件     │  ─────────▶  │      Bootloader       │  │
│  │  (正常运行)    │   复位/跳转   │      (升级模式)        │  │
│  │               │              │                        │  │
│  │ DFU Runtime   │              │      DFU Mode          │  │
│  │ 接口 (0x01)   │              │      接口 (0x02)        │  │
│  │ 只负责引导     │              │ 完整状态机 + 收发固件    │  │
│  └───────────────┘              └───────────┬────────────┘   │
│         ▲                                   │ 烧写完成复位    │
│         └────────── 运行新固件 ◀────────────┘                │
└─────────────────────────────────────────────────────────────┘
  1. 设备正常跑 应用固件(带 Runtime)。
  2. 主机发 DETACH,Runtime 回调触发复位/跳转。
  3. Bootloader 接管,暴露 DFU Mode。
  4. 主机下发新固件,Bootloader 烧写。
  5. 烧写完成,复位运行新的应用固件(新固件里依然带 Runtime,循环往复)。

四、应用场景对照表

场景 用的是 部署在哪 谁在跑
设备正常工作、等待升级指令 Runtime 应用固件 应用
实际接收/写入新固件 DFU Mode Bootloader Bootloader
只想”宣布可升级”、不写 Flash Runtime 应用固件 应用
需要多分区(Flash+EEPROM)分别升级 DFU Mode(多 alt) Bootloader Bootloader
只想读回固件(备份/校验) DFU Mode(UPLOAD) Bootloader Bootloader

五、特殊情况:两者也能”物理上在一起”

虽然典型做法是分开放(应用=Runtime,Bootloader=DFU Mode),但规范也允许两者共存于同一配置:

  • 某些设备在应用固件里同时声明 Runtime 接口和 DFU Mode 接口(不同接口号),主机通过 SET_INTERFACE 或选接口切换,无需复位。
  • 这种做法的好处是”不跳 Bootloader 也能升级”,但代价是应用固件要自己实现 Flash 烧写逻辑(即上一轮说的 download_cb/manifest_cb 那一堆),且升级期间应用自身还在内存里,有一定风险(比如自毁正在运行的程序)。

因此工程上更主流、更安全的是分开部署:应用固件只带 Runtime,Bootloader 专门带 DFU Mode。


一句话总结

  • DFU Runtime → 应用固件:设备的”门铃”,负责把主机引导到升级流程。
  • DFU Mode → Bootloader:设备的”施工队”,负责真正接收并烧写新固件。
本文链接为:http://www.usbzh.com/article/detail-1815.html ,欢迎转载,转载请附上本文链接。

HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936     USB技术交流3:1031974172

0 篇笔记 写笔记

USB-C/TYPE-C的角色分类及定义
USB总线是一个主从总线,在一条USB总线中,只能有一个USB主机,其余设备都是从机。USB总线中两个设备通过USB总线连接之前,其主从关系是一般是确定的(OGT除外)。如USB的下行端口(DownStreaming Face Port,DFP)一般为主机,而而USB的上行端口(UpStreami......
DFU 术语
缩写英文中文DFUDevice Firmware Upgrade设备固件更新FirmwareExecutable software stored in a write-able, nonvolatile memory on a USB device存储在USB设备上......
DFU 介绍
购买了 USB 设备的用户需要能够在制造商提供的改进版本中升级这些设备的固件。DFU就是完成该任务的机制。任何类型的 USB 设备都可以通过支持本文档中指定的要求来利用此功能。本文档重点介绍为已在现场部署的设备安装产品增强功能和补丁。固件升级功能的其他潜在用途超出了本文档的范围。由于设备同时......
DFU 固件更新过程
完成实现固件升级可以分为4个不同阶段。1.枚举:设备把自身的一些特性告知主机,嵌入在设备正常运行描述符中的一个DFU类接口描述符和相关的函数符能够完成这个目的,并且能够为通过控制管道的类专用的请求提供目标。2.DFU枚举:主机和设备同意开始固件升级,主机向设备发出USB复位,设备发出第二个描述符......
DFU 类特定请求
DFU类特定请求用于完成升级操作。 下表总结了 DFU 类特定的请求。RequestRequest codeRequest descriptionDFU_DETACH0X00请求设备离开DFU模式,进入应用程序DFU_DNLOAD0x01请求Host主机端数据发送......
DFU 运行时接口描述符
因为DFU仅使用控制端点故不存在端点描述符。 这样主机提供了足够的信息来识别设备能够执行固件升级操作。 它还提供了通过默认控制管道启动此类操作的方法。DFU 类接口通常是为每个运行时配置枚举的最后一个接口。但是,并不要求此接口占据任何特定位置。DFU 接口描述符格式偏移字段长度值描......
DFU 运行时功能描述符(Device Firmware Update Functional Descriptor)
运行时DFU功能描述符全称Run-Time DFU Functional Descriptor或 Device Firmware Update Functional Descriptor。描述符对于运行时和 DFU 模式描述符集是相同的运行时DFU 功能描述符格式偏移字段长度值描述......
DFU 模式配置描述符
DFU模式配置描述符与USB规范描述的标准配置描述符相同,但bNumInterfaces字段必须包值01h。偏移量名称大小说明0bLength1描述符长度(9字节)1bDescriptorType1描述符类型(配置描述符为0x02)2wTotalLe......
DFU 运行时
在正常运行时操作期间,设备会公开其正常的描述符集。但是,在每个支持DFU的运行时配置中插入了以下附加描述符:运行时DFU特定类接口描述符运行时功能描述符运行时描述符集公开设备的正常运行时设备描述符和配置描述符。支持DFU的每个配置的配置描述符的bNumInterfaces字段增加1,以适应运行......
DFU运行时设备示例
DFU运行时(RUNTIME)的测试示例来源于tinyusb使用示例,创建的描述符如下: ---------------- Interface Descriptor -----------------bLength : 0x09 (9 bytes......
DFU RUNTIME和DFU MODE的区别
DFU 实现原理dfu 功能分为两个模式: runtime 模式与 dfu 模式runtime 模式: 正常工作状态,此时需要host设备发送detach命令使设备转换成dfu模式dfu 模式 : 升级状态,host设备可以读写相应分区的数据来升级设备DFU Runtime → 应......
DFU-UTIL
dfu-util 是开源的,采用 GPLv2 许可证。它是一个命令行工具,用于在主机(PC)端实现 USB DFU 协议,以便向设备下载或上传固件.源码:https://dfu-util.sourceforge.net/git clone git://git.code.sf.net/p/dfu......
DFU Mode
DFU Mode 是 TinyUSB DFU 的核心,实现了完整的 DFU 1.1 状态机。相比 Runtime 的”极简”(无状态、只处理 2 个请求),DFU Mode 要处理全部 7 个类请求,并驱动 11 个状态的流转。请求处理要点SET_INTERFACE切换 alt......
DFU Mode设备实例
描述符 ------------------ Configuration Descriptor -------------------bLength : 0x09 (9 bytes)bDescriptorType : 0x02 (Con......
DFU GetStatus
GetStatus是DFU的类请求 CTL a1 03 0000 0000 0006 get status6 IN 00 01 00 00 04 00 ...... ......
关注公众号
  • HID人机交互
  • Linux&USB
  • UAC音频
  • CDC
  • TYPE-C
  • USB规范
  • USB大容量存储
  • USB百科
  • USB周边
  • UVC摄像头
  • Windows系统USB
  • USB资源
  • 音视频博客
  • 取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

    打开支付宝扫一扫,即可进行扫码打赏哦

    您的支持,是我们前进的动力!