杰理 SDK 文档中心
首页
首页
  • fw-Bootloader:JL 系列定制 Bootloader

    • Bootloader 架构与芯片适配
    • uboot 升级协议与流程
    • 上位机升级工具
    • 编译环境与快速开始
  • ac792n-ota-loader:AC792N 系列 OTA Loader

    • 工程结构与公共运行时框架
    • SD 卡与 USB 基础升级通道
    • 安全升级通道(SD/USB)
    • 用户自定义升级通道(UART/USB HID)
    • LVGL 图形化升级界面与模拟器
  • ac791n-ota-loader:AC791N 系列 OTA Loader

    • uboot 应用框架与 WiFi 示例
    • 升级通道变体(AP/STA/USB HID)
    • 网络与系统库依赖

上位机升级工具

上位机升级工具是运行在 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-uartWindows串口 UARTQt 图形界面源码(Qt/C++ 工程)
win-usb_hidWindowsUSB HID无图形界面(命令行演示)源码(C++ 工程)
android-usb_hidAndroidUSB 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: 提示成功/失败

流程要点:

  1. 参数配置在前:COM 口、波特率、秘钥、升级文件是启动升级的前置条件,缺失时协议无法建立。
  2. 线程解耦:升级线程与串口线程通过 blockingqueue 通信,串口 IO 的阻塞不会冻结 UI。
  3. 请求-应答驱动:每一帧"上位机 → 设备"都对应一次"设备 → 上位机"回复,协议是严格同步的握手式交互。
  4. 结束校验:固件传输完毕后设备校验,上位机以设备回复作为"升级完成"的最终依据。

配置选项

上位机工具的配置分散在「UI 参数」与「编译期常量」两层。依据官方使用说明整理如下:

配置项工具类型说明
COM 口win-uart运行期(UI)串口号,如 COM3;须与设备实际挂载端口一致
波特率win-uart运行期(UI)串口波特率;须与设备端 uboot 串口参数一致
秘钥(key)win-uart运行期(UI)升级鉴权密钥,用于协议鉴权阶段
升级文件win-uart运行期(UI)待烧录固件文件路径(如 uboot/应用固件镜像)
usb_vidwin-usb_hid编译期USB 厂商 ID,须与设备端 uboot 工程一致(使用说明#L46)
usb_pidwin-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
Prev
uboot 升级协议与流程
Next
编译环境与快速开始