上位机升级工具
上位机升级工具是运行在 PC/Android 端、通过串口(UART)或 USB HID 与设备端 uboot 升级程序交互,完成固件烧录/升级的桌面应用集合。本页聚焦 fw-Bootloader/update_tools/ 下的三款开放源码工具(win-uart、win-usb_hid、android-usb_hid)以及配套的升级协议与使用说明文档。
Purpose and Scope
本页介绍杰理(Jieli)fw-Bootloader 工程配套的 PC 端(上位机)升级工具:包括工具的定位、目录结构、三种工具(串口 / Windows USB HID / Android USB HID)的差异与使用方式、以及上位机与设备端 uboot 之间的升级协议流程。
本页不涉及(这些内容属于同仓库的其他主题):
- 设备端 uboot 升级程序的实现(
ac791n-ota-loader、ac792n-ota-loader等 OTA loader 工程),可参考其各自的 README。 - 设备端
update_main.c/dev_update.c等固件侧升级逻辑。 fw-Bootloader工程本身的构建与烧录流程,参见 fw-Bootloader/README.md。
Overview
在嵌入式设备量产与售后维修场景中,设备端 uboot 会进入"升级模式"等待接收固件数据;上位机工具负责与它建立通信链路、鉴权、分包发送固件并确认升级结果。仓库中上位机工具开放了三种形态:
| 工具 | 运行平台 | 通信方式 | 界面 | 形态 |
|---|---|---|---|---|
| win-uart | Windows | 串口 UART | Qt 图形界面 | 源码(Qt/C++ 工程) |
| win-usb_hid | Windows | USB HID | 无图形界面(命令行演示) | 源码(C++ 工程) |
| android-usb_hid | Android | USB HID(OTG) | Android 图形界面 | 预编译 APK + 工程源码包 |
官方说明明确写道:"上位机工具有 win-uart, win-usb_hid, android-usb_hid 三种,放在 fw-Bootloader\update_tools\tools 路径下,开放源码。"(见 uboot升级使用说明v1.1.2.md#L164)。
三款工具面向同一套设备端升级协议(详见 fw-Bootloader/doc/uboot升级协议流程v1.1.2.md),核心流程一致:配置通信参数 → 点击升级 → 握手鉴权 → 分包传输固件 → 设备校验 → 完成重启。选择哪种工具取决于现场环境:产线常用串口;无串口线缆时可选用 USB HID;Android 手机可作为便携升级终端。
Architecture
flowchart TD
subgraph sg_PC_Tools["PC 端工具 (fw-Bootloader/update_tools)"]
WinUart["win-uart<br/>Qt 串口升级工具"]
WinHid["win-usb_hid<br/>命令行 USB HID 工具"]
end
subgraph sg_Android_Tools["Android 端工具"]
AndroidHid["android-usb_hid<br/>USB HID (OTG) 升级 APP"]
end
subgraph sg_Protocol["升级协议 (doc 文档定义)"]
Proto["uboot升级协议流程v1.1.2<br/>上位机参数 / 设备回复 / sdk_id 鉴权"]
end
subgraph sg_Device["设备端"]
Uboot["uboot 升级模式<br/>(等待固件数据)"]
Flash["Flash 固件分区写入"]
end
WinUart -->|"串口 UART 数据帧"| Proto
WinHid -->|"USB HID 中断传输"| Proto
AndroidHid -->|"USB HID (OTG)"| Proto
Proto -->|"协议指令"| Uboot
Uboot -->|"校验通过后写入"| Flash
Doc["uboot升级使用说明v1.1.2<br/>(使用手册)"]
Doc -.->|"指导"| WinUart
Doc -.->|"指导"| WinHid
Doc -.->|"指导"| AndroidHid
架构说明:
- win-uart:仓库中的主演示工具,Qt 工程(
UBootSerialUpdateDemo.pro),包含mainwindow(界面)、updatethread(升级流程线程)、physerialthread(物理串口读写线程)与blockingqueue(线程间数据队列),体现"UI 线程 / 升级逻辑线程 / 串口 IO 线程"分层。 - win-usb_hid:基于
hidapi.h的最小演示程序(main.cpp),无图形界面,用于验证 USB HID 升级通路;其usb_vid/usb_pid必须与设备端 uboot 工程配置保持一致。 - android-usb_hid:Android 手机通过 OTG 连接设备升级,仓库中提供预编译 APK(
UbootUpdate_1.0.0_20221219.2-debug.apk)与源码压缩包(UbootUpdate_20221219.zip)。 - 升级协议:由文档定义"上位机 → 设备"的参数帧与"设备 → 上位机"的回复帧,包含
sdk_id鉴权字段,三种工具共用该协议,因此可互相替换。 - 设备端:上位机只负责按协议发送与校验,真正写入 Flash 由设备端 uboot 完成——上位机与设备端职责边界清晰。
工具清单与目录结构
上位机工具全部位于 fw-Bootloader/update_tools/ 下,实际文件布局如下(依据仓库目录列表):
fw-Bootloader/update_tools/
├── android-usb_hid/
│ ├── UbootUpdate_1.0.0_20221219.2-debug.apk # 预编译 APK
│ └── UbootUpdate_20221219.zip # 工程源码压缩包
├── win-uart/ # 串口升级 Demo(Qt)
│ ├── UBootSerialUpdateDemo.pro # qmake 工程文件
│ ├── main.cpp # 程序入口
│ ├── mainwindow.cpp / mainwindow.h / mainwindow.ui # 主界面(UI)
│ ├── updatethread.cpp / updatethread.h # 升级流程线程
│ ├── comm/
│ │ ├── commcmd.h # 通信命令定义
│ │ └── physerialthread.cpp / physerialthread.h # 物理串口线程
│ ├── utils/
│ │ ├── blockingqueue.h # 线程安全阻塞队列
│ │ └── utils.cpp / utils.h # 通用工具
│ └── README.md # 工程说明
└── win-usb_hid/ # USB HID 升级 Demo
├── UbootHid.pro # qmake 工程文件
├── main.cpp # 程序入口
└── hidapi.h # HID 访问库头文件
工程自述见 win-uart/README.md#L1-L4:"UBoot Serial Update Demo,用于演示自定义 uboot 升级流程。"
说明:由于本页源码阅读预算有限,以下对
win-uart/win-usb_hid内部模块行为的描述基于文件命名与官方文档推断;如需逐行分析,请直接阅读上述源码文件。
win-uart:串口升级工具(Qt)
win-uart 是仓库中最完整的串口升级演示,工程文件 UBootSerialUpdateDemo.pro 表明其为 Qt/C++ 工程。从文件划分可以看出典型的"三线程 + 一队列"结构:
mainwindow(UI 层):负责参数录入(串口号、波特率、秘钥、升级文件路径)与按钮交互,对应使用说明中 "PC 上位机设置好相应的参数(com口,波特率,秘钥,升级文件);点击 Start Update 即可开始升级" 的操作路径(见 uboot升级使用说明v1.1.2.md#L239-L240)。updatethread(升级流程线程):承载升级协议状态机,向串口线程下发要发送的帧,并解析设备回复决定下一步动作。physerialthread(串口 IO 线程):封装对物理串口的打开、读写与关闭,避免阻塞 UI。blockingqueue(线程安全队列):用于 UI/升级线程与串口线程之间的数据交接,是典型的"生产者-消费者"解耦设计。commcmd.h:集中定义上位机与设备约定的命令字/帧格式,是与协议文档对应的代码体现。
win-usb_hid:USB HID 升级工具
win-usb_hid 只包含 main.cpp 与 hidapi.h,官方说明指出 "win-USB_HID 升级上位机说明如下:(暂时没有图形界面)"(见 uboot升级使用说明v1.1.2.md#L184),即它是最小化的控制台演示程序,通过 hidapi 以 HID 中断传输方式与设备通信。
关键约束——VID/PID 一致性:"选择 usb_hid 升级模式时,uboot 工程的 usb_vid,usb_pid 与 usb_hid 上位机的 usb_vid,usb_pid 需要保持一致。"(见 uboot升级使用说明v1.1.2.md#L46);修改方法见该文档图示("打开 pc_demo\usb_hid\main.cpp 查看",uboot升级使用说明v1.1.2.md#L55)。这要求上位机与设备端 uboot 工程在 USB 枚举参数上保持同源配置,否则设备无法被识别为升级设备。
android-usb_hid:Android 升级 APP
android-usb_hid 目录提供 UbootUpdate_1.0.0_20221219.2-debug.apk(预编译调试版)与 UbootUpdate_20221219.zip(工程源码包)。官方说明描述其使用方式:"将小机与手机连接后,打开 APP,显示 Device:online 表示连接成功"(见 uboot升级使用说明v1.1.2.md#L216-L217)。它通过手机 USB OTG 口直连设备,适合产线/售后场景下的便携升级。
升级协议流程
上位机与设备端之间的交互协议由 uboot升级协议流程v1.1.2.md 定义,协议帧按方向分为两类:
- 上位机参数帧(方向:上位机 → 设备):携带上位机侧参数,文档示例字段包括
sdk_id(说明为"上位机 sdk id",见 uboot升级协议流程v1.1.2.md#L105-L111),用于标识上位机 SDK 版本/身份。 - 设备回复帧(方向:设备 → 上位机):设备对每条命令/参数帧的应答,携带执行结果,上位机据此推进流程或报错(见 uboot升级协议流程v1.1.2.md#L85 与 uboot升级协议流程v1.1.2.md#L118)。
三款上位机工具均实现该协议,因此协议是工具的"通用语言";win-uart/comm/commcmd.h 即是对协议命令字的代码化定义。
核心流程
一次典型的串口升级过程(win-uart 视角)如下:
sequenceDiagram
participant U as 用户
participant W as win-uart (Qt UI)
participant T as updatethread (升级线程)
participant S as physerialthread (串口线程)
participant D as 设备 uboot
U->>W: 配置 COM 口 / 波特率 / 秘钥 / 升级文件
U->>W: 点击 Start Update
W->>T: 启动升级线程
T->>S: 投递"打开串口"任务 (blockingqueue)
S-->>T: 串口打开结果
T->>S: 发送握手/鉴权帧 (含 sdk_id)
S->>D: 串口数据帧
D-->>S: 设备回复帧
S-->>T: 解析后的回复
T->>S: 按协议分包发送固件数据
S->>D: 固件帧
D-->>S: 每包/整包确认
S-->>T: 进度更新
T-->>W: 升级进度信号
W-->>U: 界面进度显示
T->>S: 发送结束/校验命令
D-->>T: 校验通过
T-->>W: 升级完成
W-->>U: 提示成功/失败
流程要点:
- 参数配置在前:COM 口、波特率、秘钥、升级文件是启动升级的前置条件,缺失时协议无法建立。
- 线程解耦:升级线程与串口线程通过
blockingqueue通信,串口 IO 的阻塞不会冻结 UI。 - 请求-应答驱动:每一帧"上位机 → 设备"都对应一次"设备 → 上位机"回复,协议是严格同步的握手式交互。
- 结束校验:固件传输完毕后设备校验,上位机以设备回复作为"升级完成"的最终依据。
配置选项
上位机工具的配置分散在「UI 参数」与「编译期常量」两层。依据官方使用说明整理如下:
| 配置项 | 工具 | 类型 | 说明 |
|---|---|---|---|
| COM 口 | win-uart | 运行期(UI) | 串口号,如 COM3;须与设备实际挂载端口一致 |
| 波特率 | win-uart | 运行期(UI) | 串口波特率;须与设备端 uboot 串口参数一致 |
| 秘钥(key) | win-uart | 运行期(UI) | 升级鉴权密钥,用于协议鉴权阶段 |
| 升级文件 | win-uart | 运行期(UI) | 待烧录固件文件路径(如 uboot/应用固件镜像) |
| usb_vid | win-usb_hid | 编译期 | USB 厂商 ID,须与设备端 uboot 工程一致(使用说明#L46) |
| usb_pid | win-usb_hid | 编译期 | USB 产品 ID,须与设备端 uboot 工程一致(使用说明#L46) |
| sdk_id | 全部工具 | 协议字段 | 上位机 SDK 标识,随鉴权帧发送(协议流程#L110-L111) |
注意:
usb_vid/usb_pid的修改位于上位机源码(文档指明查看pc_demo\usb_hid\main.cpp),需重新编译后生效;UI 参数则在运行时填写,无需重新编译。
使用示例
以下示例均摘自仓库内实际文档/工程,用于说明工具的启动与关键交互方式。
示例 1:win-uart 工程自述
UBoot Serial Update Demo
用于演示自定义 uboot 升级流程
来源:win-uart/README.md#L1-L4——本工程定位为"自定义 uboot 升级流程"的演示程序,开发者可在此基础上适配自有协议。
示例 2:串口升级操作步骤(摘自官方使用说明)
6. PC 与小机通过串口连接,小机上电,触发升级后进入升级模式等待升级(串口升级或 USB_HID 升级);
7. PC 上位机设置好相应的参数(com口,波特率,秘钥,升级文件);
8. 点击 Start Update 即可开始升级;
来源:uboot升级使用说明v1.1.2.md#L238-L240——步骤 6 描述设备侧前置条件(进入升级模式),步骤 7-8 描述上位机侧操作,两者缺一不可。
示例 3:USB HID 升级的 VID/PID 一致性约束
选择 usb_hid 升级模式时,uboot 工程的 usb_vid,usb_pid 与 usb_hid 上位机的 usb_vid,usb_pid 需要保持一致。
来源:uboot升级使用说明v1.1.2.md#L46——这是 USB HID 升级能否被系统识别为升级设备的关键前提,也是排障时首先要核对的两项参数。
示例 4:Android 端连接成功判定
将小机与手机连接后,打开 APP,显示 Device:online 表示连接成功;
来源:uboot升级使用说明v1.1.2.md#L216-L217——android-usb_hid 以 Device:online 作为设备枚举/连接成功的判定标识。
示例 5:协议帧方向定义
- 上位机参数
- 方向:上位机->设备
- 设备回复参数
- 方向:设备->上位机
来源:uboot升级协议流程v1.1.2.md#L71-L72 与 uboot升级协议流程v1.1.2.md#L84-L85——协议所有命令均按"上位机参数帧 → 设备回复帧"成对设计。
失败模式、边界情况与并发
依据源码结构(updatethread / physerialthread / blockingqueue)与官方文档,可归纳以下风险点:
- VID/PID 不匹配(USB HID):上位机与设备端 uboot 的
usb_vid/usb_pid不一致时,设备无法被识别,表现为连接失败。排查顺序:核对两端 VID/PID → 重编译上位机 → 重新插拔枚举。 - 串口参数不匹配:COM 口选错、波特率与设备端不一致,表现为打开失败或通信乱码/超时。这是串口升级最常见的失败原因,需在 UI 中逐项核对。
- 设备未进入升级模式:上位机参数全部正确但无回复,往往是设备端未触发升级模式(文档步骤 6 的前置条件未满足)。
- 鉴权失败:秘钥或
sdk_id不符时,设备在鉴权阶段拒绝后续传输;上位机应给出明确失败提示,避免继续发包。 - 线程并发与队列阻塞:
win-uart中升级线程与串口线程通过blockingqueue交接数据。若设备长时间无回复,串口读操作会阻塞在队列消费侧——设计上应配合超时机制避免升级线程永久挂起;blockingqueue的线程安全实现决定了多线程读写的数据完整性。 - 传输中断:升级过程中拔线/断电会导致设备停留在半写入状态,通常需重新进入升级模式重传,上位机应支持失败后重试。
性能与运维注意
- 传输瓶颈在串口波特率:串口升级速度受波特率上限约束,大固件升级耗时较长;USB HID 中断传输吞吐高于低速串口,适合大镜像场景。
- 升级文件完整性:升级前应校验固件文件(大小/校验值),避免将损坏镜像发往设备。
- 现场操作规范:参照使用说明步骤 6-8,先接线、上电、进入升级模式,再启动上位机升级,可最大限度避免握手超时。
- 工具选型建议:产线固定工位用 win-uart 或 win-usb_hid;售后/外场用 android-usb_hid 便携方案。
扩展点
- 自定义协议适配:
win-uart/comm/commcmd.h是命令字定义集中处,修改协议帧格式时优先改此处,再同步设备端update_main.c等实现。 - 新增升级模式:可参照
win-usb_hid的最小实现(main.cpp+hidapi.h)与win-uart的完整 Qt 结构,派生新的上位机形态。 - SDK 标识扩展:
sdk_id字段用于标识上位机版本,可扩展为携带更多元信息(如固件类型、版本号),但需设备端协议同步升级。 - 批量/产线自动化:win-uart 的 UI 层与
updatethread分层清晰,可在不修改升级逻辑的前提下,将 UI 替换为命令行/脚本驱动,实现批量烧录。
Related Links
- uboot升级使用说明v1.1.2.md——上位机工具使用手册(界面、参数、操作步骤)
- uboot升级协议流程v1.1.2.md——上位机与设备的协议帧定义
- win-uart/README.md——串口升级 Demo 工程说明
- win-uart/UBootSerialUpdateDemo.pro——Qt 工程文件
- win-usb_hid/main.cpp——USB HID 上位机入口(VID/PID 修改处)
- fw-Bootloader/README.md——fw-Bootloader 工程总览
- 设备端升级实现(独立主题):
ac791n-ota-loader、ac792n-ota-loader工程下的update_main.c/dev_update.c