ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

esp-iot-solution USB UF2 OTA 示例深度解析:用虚拟 U 盘拖拽固件完成 OTA 升级

esp-iot-solution USB UF2 OTA 示例深度解析:用虚拟 U 盘拖拽固件完成 OTA 升级 物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载本文围绕 esp-iot-solution 中的usb_uf2_ota示例系统讲解如何借助 Microsoft 提出的 UF2 文件格式与 USB MSCMass Storage Class能力把支持 USB-OTG 的 ESP 芯片变成一个虚拟 U 盘用户只需把.uf2格式固件拖拽进磁盘即可完成 OTA 升级。读完本文你将掌握示例的构建烧录流程、分区表设计、esp_tinyuf2组件 API 用法、idf.py uf2-ota命令以及uf2conv.py转换工具并了解该方案在 NVS 读写、USB 日志控制台与 Bootloader 层面的扩展玩法。UF2 虚拟磁盘拖拽升级示意UF2 与 MSC为什么拖拽就能升级UF2USB Flashing Format是 Microsoft 为 PXT 项目开发的一种文件格式特别适合通过 MSCMass Storage Class即 U 盘对微控制器进行烧录。其核心思路是把固件镜像切分成带地址信息的 512 字节块block每个块自身携带该写到哪个 Flash 地址的元数据因此宿主端PC只需像拷贝普通文件一样把.uf2文件复制到 U 盘设备端就能依据块内地址信息把固件逐块写入指定分区。esp-iot-solution 的 esp_tinyuf2 组件正是 TinyUF2 针对带 USB-OTG 的 ESP 芯片ESP32-S2 / ESP32-S3 / ESP32-P4的增强实现在拖拽刷写之上还叠加了三项能力通过虚拟 USB 驱动器进行 OTA 升级将 NVS 键值对导出为虚拟 U 盘中的ini文件修改ini文件内容后写回 NVS实现免串口配置。而 usb_uf2_ota 示例就是这套机制最直接的落地演示设备上电后枚举为一个名为ESP32S2-UF2/ESP32S3-UF2的 U 盘拖入升级固件后自动完成分区写入并重启。示例工程结构一览先看示例的完整文件布局便于后续逐项展开examples/usb/device/usb_uf2_ota/ ├── main/ │ ├── CMakeLists.txt # 注册主源文件 │ ├── Kconfig.projbuild # 开发板选择菜单 │ ├── idf_component.yml # 声明依赖 esp_tinyuf2 组件 │ └── usb_uf2_ota_main.c # 示例主程序 ├── CMakeLists.txt # 顶层工程文件 ├── README.md # 官方使用说明 ├── partitions_factory_two_ota_4m.csv ├── partitions_factory_two_ota_8m.csv ├── partitions_two_ota_4m.csv ├── partitions_two_ota_8m.csv ├── pytest_usb_uf2_ota.py # 自动化测试 ├── sdkconfig.ci.esp32s3_usb_otg └── sdkconfig.defaults其中顶层 CMakeLists.txt 是标准的 IDF 工程骨架project(usb_uf2_ota)主程序的组件清单 idf_component.yml 通过override_path将esp_tinyuf2指向仓库内的本地组件dependencies: idf: 4.4 esp_tinyuf2: version: * override_path: ../../../../../components/usb/esp_tinyuf2这意味着本示例要求 IDF 版本不低于 4.4且直接复用仓库内 components/usb/esp_tinyuf2 组件的源码便于调试与学习。构建与烧录在终端中执行PORT为设备串口例如/dev/ttyUSB0idf.py -p PORT flash monitor该命令会依次完成编译、烧录并打开串口监视器退出监视器按Ctrl-]。第一次烧录必须走传统串口方式因为此时设备尚未具备 UF2 能力烧录完成后后续固件升级即可完全脱离串口工具改用拖拽方式。示例通过 Kconfig.projbuild 提供开发板选择菜单支持三种目标板且随IDF_TARGET自动切换默认项ESP32 S3 USB OTGIDF_TARGET_ESP32S3默认ESP32 S3 GENERICIDF_TARGET_ESP32S3ESP32 S2 GENERICIDF_TARGET_ESP32S2。CI 配置 sdkconfig.ci.esp32s3_usb_otg 中即包含CONFIG_ESP32_S3_USB_OTGy。当选中该板卡时主程序会在启动阶段将 GPIO18 拉低usb_uf2_ota_main.c用于配合 ESP32-S3-USB-OTG 开发板的硬件接线。分区表OTA 方案的基础与任何 OTA 方案一样UF2 OTA 也要求至少存在两个 OTA 应用分区。示例为不同 Flash 容量准备了四张分区表其中 partitions_two_ota_4m.csv4MB Flash如下# Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, , 0x4000, otadata, data, ota, , 0x2000, phy_init, data, phy, , 0x1000, ota_0, app, ota_0, , 1500K, ota_1, app, ota_1, , 1500K,nvs存储 NVS 键值数据otadataOTA 数据分区记录当前/下一个启动的应用槽位phy_init射频校准数据ota_0/ota_1两个对等的应用槽位供升级时交替写入。对应的 8MB 版本 partitions_two_ota_8m.csv 将每个应用槽位扩大到 3500K而 partitions_factory_two_ota_4m.csv 额外保留了 1MB 的factory出厂分区构成factory ota_0 ota_1布局。默认配置 sdkconfig.defaults 做了如下设置CONFIG_ESPTOOLPY_FLASHSIZE_4MBy CONFIG_ESPTOOLPY_FLASHSIZE_DETECTy CONFIG_PARTITION_TABLE_CUSTOMy CONFIG_PARTITION_TABLE_CUSTOM_FILENAMEpartitions_two_ota_4m.csv CONFIG_PARTITION_TABLE_MD5y CONFIG_ENABLE_UF2_USB_CONSOLEy即默认按 4MB Flash、自定义分区表partitions_two_ota_4m.csv构建并开启 UF2 USB 控制台日志同时输出到 USB 串口。如果你使用 8MB Flash 的模组将sdkconfig.defaults中的分区表文件名替换为partitions_two_ota_8m.csv即可。主程序解析安装、等待、重启整个示例逻辑非常精简全部集中在 usb_uf2_ota_main.c 中核心调用链如下/* 升级完成回调通知 main 任务 */ static void uf2_update_complete_cb() { TaskHandle_t main_task_hdl xTaskGetHandle(main); xTaskNotifyGive(main_task_hdl); } void app_main(void) { /* 1. 初始化目标板 IOESP32-S3-USB-OTG 拉低 GPIO18 */ /* 2. 安装 UF2 OTA */ tinyuf2_ota_config_t config DEFAULT_TINYUF2_OTA_CONFIG(); config.complete_cb uf2_update_complete_cb; config.if_restart false; /* 关闭自动重启改为手动控制 */ esp_tinyuf2_install(config, NULL); /* 3. 阻塞等待 UF2 升级完成事件 */ ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ESP_LOGI(TAG, Firmware update complete); /* 4. 5 秒倒计时后卸载 UF2 并重启到新固件 */ for (int i 5; i 0; i--) { ESP_LOGI(TAG, Restarting in %d seconds..., i); vTaskDelay(1000 / portTICK_PERIOD_MS); } esp_tinyuf2_uninstall(); ESP_LOGI(TAG, Restarting now); esp_restart(); }这里的关键点是配置结构体tinyuf2_ota_config_t与默认宏DEFAULT_TINYUF2_OTA_CONFIG()它们定义在组件头文件 components/usb/esp_tinyuf2/esp_tinyuf2.h 中#define DEFAULT_TINYUF2_OTA_CONFIG() \ { \ .subtype ESP_PARTITION_SUBTYPE_ANY, \ .label NULL, \ .if_restart true \ }各字段语义如下字段说明subtype目标分区子类型设为ESP_PARTITION_SUBTYPE_ANY时默认写入esp_ota_get_next_update_partition()返回的下一个 OTA 槽位label分区标签如需写入指定名称的分区如factory可在此指定if_restartUF2 刷写完成后是否自动重启到新分区complete_cb升级完成后的用户回调update_complete_cb_t类型示例将if_restart设为false改为在回调中通过 FreeRTOS 任务通知唤醒main任务再自行倒计时、esp_tinyuf2_uninstall()恢复 USB 设备状态并esp_restart()重启——展示了接管重启时机的典型用法如果你不关心时序细节保留默认的if_restart true即可让组件全自动完成升级重启。esp_tinyuf2_install()的第二个参数是 NVS 配置tinyuf2_nvs_config_t传NULL表示不启用 NVS 的 ini 导出功能。完整 API 还包括esp_tinyuf2_uninstall()卸载 tinyuf2将 USB 恢复为默认状态受限于 tinyusb 不支持 teardown内存不会释放esp_tinyuf2_current_state()查询当前状态TINYUF2_STATE_NOT_INSTALLED/TINYUF2_STATE_INSTALLED/TINYUF2_STATE_MOUNTEDesp_restart_from_tinyuf2()重启系统并将复位原因置为UF2_RESET_REASON_VALUE默认0xF2供 Bootloader 判断是否进入 UF2 模式。menuconfig 关键配置项执行idf.py menuconfig进入Component config → TinyUF2 Config可调优以下参数定义于 components/usb/esp_tinyuf2/Kconfig配置项含义默认值取值范围USB Virtual Disk size(MB)虚拟 U 盘在文件管理器中显示的大小8 MB4–32Max APP size(MB)允许的最大应用大小4 MB2–8Flash cache size(KB)缓存待写入 bin 片段的 Flash 缓存大小32 KB4–64USB Device VIDUSB 厂商 ID0x303AEspressif—USB Device PIDUSB 产品 ID0x8000Espressif 测试 PID—USB Disk Name虚拟 U 盘卷标ESP32S2-UF2/ESP32S3-UF2/ESP32P4-UF2—USB Device Manufacture制造商字符串Espressif—Product Name产品名ESP TinyUF2—Product ID序列号12345678—Product URL会生成index文件放入 U 盘点击可打开网页https://products.espressif.com/—UF2 NVS ini file size保存 NVS 键值对的 ini 文件大小512256–2048Enable USB Console For log日志输出到 USB 串口默认输出 UART关闭—OTA Factory Only限制 OTA 只写factory分区关闭—OTA Reset Reason ValueUF2 OTA 复位的复位原因值0xF2—其中虚拟磁盘大小与最大 APP 大小决定了拖拽升级时设备端预留的写入/缓存空间需要与你的分区表实际容量匹配Kconfig 中ENABLE_UF2_FLASHING会自动在 ESP32-S2 / ESP32-S3 / ESP32-P4 上默认开启并联动选中 TinyUSB从配置层面保证了组件只在支持 USB-OTG 的芯片上启用。拖拽升级完整的实战流程按官方 README 的步骤一次完整的拖拽升级分为四步首次烧录用idf.py -p PORT flash monitor烧入第一个支持 TinyUF2 的固件插入 USB把ESP32S3或 ESP32-S2 等设备通过 USB 接入 PC文件管理器中会出现新磁盘卷标为ESP32S2-UF2/ESP32S3-UF2对应 Kconfig 中的UF2_VOLUME_LABEL生成升级固件运行idf.py uf2-ota将后续版本的固件生成/转换为 UF2 格式详见下一节拖拽升级把.uf2格式固件直接拖入磁盘升级自动进行。从组件文档docs/zh_CN/usb/usb_device/esp_tinyuf2.rst可以确认idf.py uf2-ota是组件通过工程钩子注入的新命令编译完成后会在project目录下生成${PROJECT_NAME}.uf2文件idf.py uf2-ota重要提示UF2 OTA 要能连续使用更新后的应用中必须同样启用 tinyuf2——否则升级完成后新固件不再提供虚拟 U 盘也就无法进行下一轮拖拽升级。这是整个方案能否链式迭代的关键约束。将现有 bin 转换为 UF2 格式如果手头已有现成的应用 bin例如 CI 产出的固件无需重新编译工程可直接使用组件自带的转换脚本 components/usb/esp_tinyuf2/utils/uf2conv.pyfamily id 定义在 utils/uf2families.json# 按芯片家族名指定推荐 uf2conv.py your_firmware.bin -c -b 0x00 -f ESP32S3 # 或直接指定 family id 魔数 uf2conv.py your_firmware.bin -c -b 0x00 -f 0xc47e5767-c转换convert为 UF2 格式-b指定基地址tinyuf2 将把它作为写入 OTA 分区的偏移量-ffamily idESP32S2/ESP32S3均有对应魔数。升级成功的日志表现拖拽升级完成后串口/USB 控制台会输出与官方 README 一致的信息节选I (8456) esp_image: segment 0: paddr00010020 vaddr3f000020 size0857ch ( 34172) map I (8496) esp_image: segment 4: paddr00038270 vaddr40027cd4 size05be4h ( 23524) I (8556) uf2_example: Firmware update complete I (8556) uf2_example: Restarting in 5 seconds... I (9556) uf2_example: Restarting in 4 seconds... I (10556) uf2_example: Restarting in 3 seconds... I (13556) uf2_example: Restarting now可以看到esp_image逐段校验并映射新固件镜像随后uf2_example打印Firmware update complete倒计时 5 秒后esp_restart()重启进入新固件——这正是主程序中回调 ulTaskNotifyTake 倒计时逻辑的外在表现。自动化测试验证虚拟磁盘真的出现示例自带 pytest 用例 pytest_usb_uf2_ota.py覆盖 ESP32-S2 与 ESP32-S3 两个目标测试流程值得借鉴pytest.mark.target(esp32s2) pytest.mark.target(esp32s3) pytest.mark.env(usb-otg_camera) def test_usb_uf2_ota(dut: Dut)- None: usb_name Espressif ESP TinyUF2 dut.expect(rTUF2: Enable USB console, log will be output to USB, timeout5) time.sleep(3) assert check_usb_device(usb_name), fUSB disk with name {usb_name} not found on the test machine它先等待设备打印Enable USB console日志确认 UF2 功能已装载随后通过宿主机lsusb检查是否枚举出名为Espressif ESP TinyUF2的 USB 设备若系统缺lsusb用例会自动安装usbutils后重试。这也从侧面印证了虚拟 U 盘在系统层面的真实存在。进阶玩法NVS 导出、USB 控制台与 Bootloader UF2esp_tinyuf2不止于 OTA围绕虚拟磁盘还能扩展出多类实用能力1. NVS 键值导出与回写安装时传入tinyuf2_nvs_config_t默认宏DEFAULT_TINYUF2_NVS_CONFIG()指向nvs分区的tuf2命名空间即可把 NVS 键值导出为磁盘中的ini文件修改保存后写回 NVSnvs_modified_cb回调会在 NVS 被修改后通知应用。结合menuconfig的UF2 ini file hide NVS value与 APIesp_tinyuf2_add_key_hidden(password)还能将敏感键值以****遮蔽后导出最多隐藏键数由UF2_INI_NVS_HIDDEN_MAX_NUM控制默认 32。2. USB 日志控制台开启Enable USB Console For log即示例 sdkconfig 中的CONFIG_ENABLE_UF2_USB_CONSOLEy后日志改由 USB 串口输出为无 UART 引出的量产/调试场景提供了便捷通道——pytest 正是依赖这条日志来判断 UF2 装载成功。3. Bootloader 级 UF2 下载模式组件文档还描述了将带 UF2 功能的特殊 APP bin 隐藏进 Bootloader的方案需开启CONFIG_ENABLE_BOOTLOADER_UF2与CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED可实现三种进入 UF2 下载模式的途径当factory/test/ota分区无固件时自动进入、手动拉低BOOT_UF2引脚进入、或在用户 APP 中调用esp_restart_from_tinyuf2()主动进入。需要注意bootloader_uf2.bin必须烧录在CONFIG_MMU_PAGE_SIZEESP32-S2/S3/P4 默认 64KB对齐的地址上并同步扩大CONFIG_PARTITION_TABLE_OFFSET以容纳新增的 bin。总结usb_uf2_ota示例展示了 UF2 MSC 这一零上位机、免串口的 OTA 形态在 ESP 芯片上的完整落地一次串口烧录建立能力之后所有升级都简化为生成 .uf2 文件 拖入磁盘。其工程结构清晰、配置项完备且依托 esp_tinyuf2 组件还能进一步解锁 NVS 免串口配置、USB 日志控制台与 Bootloader 级恢复模式非常适合量产维护、现场升级和用户体验优先的消费类产品场景。建议动手实践时从 4MB 分区的默认配置起步逐步尝试 NVS ini 导出与uf2conv.py的 bin 转换流程完整打通构建 → 转换 → 拖拽 → 重启的全链路。赞分享物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载相关推荐ESP MSC OTA基于 USB Mass Storage 的 U 盘 OTA 升级方案esp-iot-solution 组件实战指南ESP MSC OTA基于 USB Mass Storage 的 U 盘 OTA 升级方案esp iot solution 组件实战指南 导读 esp_m物联网嵌入式驱动开发硬件开发esp_tinyuf2 组件实战基于 USB 虚拟磁盘实现 UF2 OTA 升级与 NVS 配置管理ESP IoT Solutionesp_tinyuf2 组件实战基于 USB 虚拟磁盘实现 UF2 OTA 升级与 NVS 配置管理ESP IoT Solution 本文系统讲解 ESP物联网嵌入式驱动开发硬件开发ESP32 USB Host MSC OTA 实战指南基于 esp-iot-solution 实现 U 盘固件升级ESP32 USB Host MSC OTA 实战指南基于 esp iot solution 实现 U 盘固件升级 导读 本文以 examples/usb/h物联网嵌入式驱动开发硬件开发上一篇终极指南Cert-Manager动态准入控制Webhook配置与测试详解下一篇raylib-games跨平台部署终极教程Windows、Linux、Web、Android全平台实战指南 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表