杰理 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)
    • 网络与系统库依赖

工程结构与公共运行时框架

本文档介绍杰理科技(Jieli)开源聚合仓库 gitee-repos-Other 的工程组织方式,以及 fw-Bootloader(JL 系列定制 user boot 固件)所承载的公共运行时框架——包括多芯片工程目录规范、编译入口、升级模式(串口 / USB_HID)、调试打印、升级触发机制与工具链约束。

Purpose and Scope

本页覆盖以下内容:

  • 仓库顶层组织:gitee-repos-Other 聚合仓库包含哪些子仓库(fw-Bootloader、ac792n-ota-loader),以及它们与杰理 SDK 的关系。
  • fw-Bootloader 工程结构:user_boot/cpu/<cpu>/<cpu>_uboot.cbp 的工程入口规范、app/src/user.c 的运行时配置位置,以及依赖的命名规则库文件(lib.a)与子仓库。
  • 公共运行时机制:升级模式选择(USB_MODE 宏)、调试打印(__DEBUG、isd_config.ini、uart_init)、升级触发方式(I/O 口检测与 SDK 软件复位 USE_UPGRADE_MAGIC)、工具链与编译环境(Codeblock / Make)、产物 uboot.boot 的部署流程。

以下内容不属于本页边界,留给兄弟页面:

  • AC792N 的 OTA Loader 具体实现细节:见 ac792n-ota-loader 对应页面。
  • uboot 升级协议的逐包格式与状态机(数据包结构、命令字、时序细节):见 uboot 升级协议流程 相关页面。
  • 各芯片 SDK 自身的应用层框架(非 boot 部分)不在本仓库内,仅通过本页的 SDK ↔ BootLoader 对应表建立索引。

Overview

杰理芯片的固件体系中,user boot(uboot) 是介于芯片 ROM 启动与 SDK 应用之间的引导固件。它的核心职责是:在设备上电或复位后,根据触发条件(I/O 电平或 SDK 软件复位 magic 字)决定是进入升级流程还是直接跳转到 SDK 应用;若进入升级流程,则通过串口或 USB_HID 与上位机通信,完成固件数据的接收、CRC 校验与烧写。

fw-Bootloader 仓库即为此公共运行时框架的参考实现,关键设计要点如下:

  1. 一仓多芯片:同一个仓库通过 user_boot/cpu/<cpu> 目录隔离不同芯片系列的工程,例如 bd19(AC693N)、br23(AC635N/AC695X)、br25(AC636N/AC696X)、br30(AC697N/AC897N)、br34(AC638N/AD698N)、sh54(AD14N/AD104N)、sh55(AD15N/AD105N)、wl82(AC791N)、br28(AC701N)。选择工程时只需按芯片型号打开对应的 .cbp 文件(Codeblock 工程)。
  2. 双编译环境:同时支持 Codeblock(.cbp 工程文件)与 Make 环境,便于不同工作流接入。
  3. 编译时配置驱动运行时:升级模式(USB_MODE)、调试打印(__DEBUG)、软件复位触发(USE_UPGRADE_MAGIC)均通过编译宏在构建期决定,使同一套源码可以产出不同运行形态的 boot 固件。
  4. 依赖外部库与子仓库:user boot 并非完全独立,需要结合"对应命名规则的库文件(lib.a)"和对应的子仓库一起编译,这是仓库 README 中明确声明的约束。

该框架的典型使用场景:产品量产固件需要定制串口升级或 USB_HID 升级;调试阶段需要开启打印定位 boot 行为;整机升级触发既可以是硬件按键(I/O 检测),也可以是 SDK 运行时发起软复位。

Architecture

下图展示聚合仓库的顶层组织、fw-Bootloader 的工程结构,以及公共运行时框架各机制之间的关系:

flowchart TD
    subgraph sg_Repo["gitee-repos-Other(聚合仓库)"]
        FB["fw-Bootloader<br/>JL 系列定制 user boot"]
        OL["ac792n-ota-loader<br/>AC792N OTA Loader"]
    end

    subgraph sg_Boot["fw-Bootloader 工程结构"]
        CB["user_boot/cpu/&lt;cpu&gt;/&lt;cpu&gt;_uboot.cbp<br/>Codeblock 工程入口"]
        UC["app/src/user.c<br/>ut_device_mode(tx, rx, bud)"]
        LIB["命名规则 lib.a 库文件<br/>+ 对应子仓库"]
    end

    subgraph sg_Runtime["公共运行时机制"]
        MODE["升级模式<br/>USB_MODE=0 串口 / USB_MODE=1 USB_HID"]
        TRIG["触发方式<br/>I/O 电平检测 / USE_UPGRADE_MAGIC 软复位"]
        DBG["调试打印<br/>__DEBUG + uart_init(uttx, ut_buad)"]
    end

    FB --> CB
    CB --> UC
    CB --> LIB
    CB --> MODE
    MODE --> TRIG
    MODE --> DBG
    TRIG --> DBG

架构分层说明:

  • 聚合仓库层:gitee-repos-Other 只做整理与索引,包含两个与 boot 体系直接相关的子仓库;fw-Bootloader 面向 JL 全系列芯片的 user boot,ac792n-ota-loader 则面向 AC792N 的 OTA 引导场景,两者各自独立演进。
  • 工程结构层:fw-Bootloader 以 user_boot/cpu/<cpu> 作为芯片工程隔离边界,.cbp 是编译入口;app/src/user.c 是运行时外设配置(串口引脚与波特率)的集中位置;lib.a 库与子仓库提供芯片底层驱动与协议栈。
  • 运行时机制层:升级模式决定 boot 启动后使用哪条外设通路;触发方式决定从 SDK 应用进入升级流程的路径;调试打印贯穿两条通路,方便定位问题。

工程结构详解

仓库顶层组织

根目录 README.md 以表格形式声明了聚合仓库包含的子仓库:

目录说明
fw-BootloaderJL 系列定制 Bootloader
ac792n-ota-loaderJL AC792N系列定制 ota-loader

设计意图:杰理将不属于主要 SDK 分类的仓库统一收敛到 gitee-repos-Other,通过 README 建立索引。读者应依据目标芯片与场景选择子仓库——全系列通用 boot 能力看 fw-Bootloader,AC792N 专属 OTA 场景看 ac792n-ota-loader。

fw-Bootloader 工程结构

fw-Bootloader/README.md 明确了该仓库的定位:JL 系列 user boot 固件程序,包含 user boot release 版本代码,支持自定义串口升级和 usb_hid 升级,且"线下线上支持同步发布"。

关键工程约束(README 原文要点):

本工程提供的例子,需要结合对应命名规则的库文件(lib.a) 和对应的子仓库进行编译。

这意味着 fw-Bootloader 本身不携带芯片底层库,必须与命名匹配的 lib.a 静态库及配套子仓库协同编译——这是理解该工程"结构上分层、编译上聚合"的核心。boot 的特殊性(直接操作 Flash 与硬件)决定了库必须精确匹配芯片系列,因此库文件命名规则与芯片 cpu 目录一一对应。

SDK 与 BootLoader 系列对应关系

fw-Bootloader/README.md 给出了完整的 SDK 型号 → BootLoader 工程目录映射:

SDK型号BootLoader 对应
AC693N/AC693Xbd19
AC635N/AC695X/AC695Nbr23
AC636N/AC696X/AC696Nbr25
AC697N/AC897Nbr30
AC638N/AD698Nbr34
AD14N/AD104Nsh54
AD15N/AD105Nsh55
AC791Nwl82
AC701Nbr28

工程入口规则:user_boot\cpu\<cpu>\<cpu>_uboot.cbp。README 给出的示例:SDK型号使用的是AC701N, 使用user_boot\cpu\br28\br28_uboot.cbp作为工程入口;升级使用说明文档也以 AC632N 为例,指出需要打开 fw-Bootloader-main\user_boot\cpu\bd19\bd19_uboot.cbp。这一"按 cpu 目录选工程"的约定是公共运行时框架扩展多芯片的基础——新增芯片系列只需新增一个 cpu 目录与对应 .cbp 工程,运行时框架代码按宏与库区分行为。

编译环境与产物

fw-Bootloader/README.md 说明 SDK 同时支持 Codeblock 与 Make 编译环境:

  • Codeblock 编译:进入对应工程目录,找到后缀为 .cbp 的文件,双击打开即可编译。
  • 产物部署:生成的 uboot.boot 需要添加到原 SDK 下载目录调试(流程见升级使用说明文档)。
  • 工具链:与标准 SDK 一致;若遇到 "错误: uboot.boot数据的CRC校验错误" 或 "生成失败,无效的F文件" 等错误,需要更新最新的工具(文档指向杰理工具下载页)。

公共运行时机制

升级模式选择(USB_MODE 宏)

uboot 升级支持两种模式,通过编译期 #defines 切换(见 升级使用说明):

  • 串口升级模式:在 Project build options → Compiler settings → #defines 中添加 USB_MODE=0。串口的 TX 脚、RX 脚、波特率由 app\src\user.c 中的 ut_device_mode(tx, rx, bud) 函数设置。
  • USB_HID 升级模式:在 #defines 中添加 USB_MODE=1。此时 uboot 工程的 usb_vid、usb_pid 必须与 usb_hid 上位机的 usb_vid、usb_pid 保持一致,否则设备无法被上位机识别;上位机的 VID/PID 在 pc_demo\usb_hid\main.cpp 中修改。

设计意图:用编译宏而非运行时配置来决定升级通路,可以在不增加 boot 体积与运行分支的前提下,为不同产品线产出定制化的最小 boot 固件;同时将"外设引脚"与"协议栈"两件事解耦——引脚配置留在 user.c,协议栈由库提供。

调试打印配置

调试打印的使能与配置同样采用"宏 + 配置源"组合(见 升级使用说明):

  • 使能:在 #defines 中添加 __DEBUG 宏。
  • 方法一(配置文件):使用 isd_config.ini 配置文件中的引脚和波特率配置;在 main 函数中调用 uart_init(uttx, ut_buad) 应用配置。
  • 方法二(代码直设):直接在代码中设置打印脚和波特率(文档示例:PA5,1000000 波特率)。

升级触发方式

升级触发有两条路径(见 升级使用说明):

  1. I/O 口检测触发:进入 uboot 后,在 main 函数中通过检测某个 I/O 的电平状态,决定是否跳转到升级流程。典型用于量产/售后模式:按键或治具拉低引脚进入升级。
  2. SDK 软件复位触发:在 user.h 中使能 USE_UPGRADE_MAGIC 宏;随后在 SDK 工程(任意位置)添加 magic 字写入代码,实现 SDK 运行时主动发起软复位并携带"进入升级"的标记。uboot 复位后读到该标记即进入升级流程。

设计意图:两种触发方式覆盖了"外部强制"与"软件主动"两类升级场景。I/O 检测不依赖 SDK 状态,适合设备死机、无法进入应用时的兜底恢复;magic 字方案由 SDK 控制升级时机,适合 OTA/在线升级流程,二者互为补充。

工具链与常见构建错误

fw-Bootloader/README.md 提示:使用的工具链与标准 SDK 一致。构建期可能出现以下典型错误,均指向工具版本问题:

  • 错误: uboot.boot数据的CRC校验错误 —— 生成的 boot 数据 CRC 校验不通过。
  • 生成失败,无效的F文件,请重新选择系统找不到指定的文件 —— 工具链或文件路径异常。

处理方式:更新到最新的工具(杰理官方工具文档),而不是修改工程代码。这反映了 boot 构建链对工具版本的高度敏感:CRC 由构建工具生成,工具过旧会导致校验算法或烧录格式不匹配。

核心流程

升级流程总览

下图将"触发 → 引导 → 模式选择 → 协议交互 → 校验烧写 → 复位"的完整控制流串起来:

flowchart TD
    Start([上电 / 复位]) --> Trigger{"触发源判断"}
    Trigger -->|"I/O 电平检测"| IO["main() 检测 I/O 电平状态"]
    Trigger -->|"SDK 软件复位 magic"| SDK["USE_UPGRADE_MAGIC + nvram_list 写入"]
    IO --> Boot["进入 uboot 引导"]
    SDK --> Boot
    Boot --> Mode{"升级模式"}
    Mode -->|"USB_MODE=0"| UART["串口升级<br/>ut_device_mode(tx, rx, bud)"]
    Mode -->|"USB_MODE=1"| HID["USB_HID 升级<br/>VID/PID 与上位机一致"]
    UART --> Proto["升级协议交互<br/>(上位机 ↔ uboot)"]
    HID --> Proto
    Proto --> CRC{"CRC 校验"}
    CRC -->|"通过"| Flash["烧写固件到 Flash"]
    CRC -->|"失败"| Err["报错:uboot.boot CRC 校验错误"]
    Flash --> Reboot([重启进入 SDK 应用])
    Err --> Reboot

流程要点:

  1. 触发源判断是 uboot 运行时第一个决策点:I/O 电平路径由硬件决定,magic 路径由 SDK 软件决定;二者最终汇合到"进入 uboot 引导"。
  2. 升级模式在编译期由 USB_MODE 固定,运行时只走一条外设通路,不存在运行时切换。
  3. CRC 校验是烧写前的最后一道闸门,校验失败即报错(对应 README 中提到的工具链错误信息),避免将损坏数据写入 Flash。
  4. 无论升级成功与否,最终都复位进入 SDK 应用——boot 不常驻业务逻辑,保证系统启动路径简洁。

升级交互时序

下图描述一次典型升级中 SDK 应用、uboot、上位机与 Flash 的交互顺序:

sequenceDiagram
    participant SDK as SDK 应用
    participant UB as uboot(user boot)
    participant PC as 上位机
    participant FM as Flash 存储

    SDK->>UB: 软件复位(USE_UPGRADE_MAGIC)
    Note over UB: main() 检测触发源并初始化升级外设
    PC->>UB: 建立连接(串口 / USB_HID,VID/PID 匹配)
    PC->>UB: 下发升级数据包
    UB->>UB: 校验数据(CRC)
    UB->>FM: 写入固件
    FM-->>UB: 写入完成
    UB-->>PC: 应答结果
    UB->>UB: 复位跳转
    UB->>SDK: 启动 SDK 应用

时序设计的要点:uboot 与上位机之间采用"请求-应答"式交互(协议细节见 uboot 升级协议流程),数据在写入 Flash 前先做 CRC 校验,保证传输与写入的一致性;升级完成后通过复位切换控制权,避免 boot 与 SDK 应用共存导致的资源冲突。

使用示例

以下示例均提取自仓库文档中的实际配置说明,展示了公共运行时框架的典型定制方式。

选择芯片工程入口(AC632N 示例)

升级使用说明 指出,根据芯片型号选择对应的 uboot 工程,以 AC632N 为例:

fw-Bootloader-main\user_boot\cpu\bd19\bd19_uboot.cbp

Source: uboot升级使用说明v1.1.2.md

工程入口与 README 的 SDK 对应表 配合使用:先查表得到 cpu 目录名,再打开对应 .cbp。

配置串口升级引脚与波特率

串口模式下,在 app\src\user.c 中调用 ut_device_mode(tx, rx, bud) 设置串口 TX 脚、RX 脚与波特率(升级使用说明):

// app/src/user.c —— 串口升级模式下的外设配置入口
// 参数依次为:TX 引脚、RX 引脚、波特率
ut_device_mode(tx, rx, bud);

Source: uboot升级使用说明v1.1.2.md

使能调试打印

方法一:在 main 函数中调用 uart_init(uttx, ut_buad),引脚与波特率取自 isd_config.ini 配置文件(升级使用说明):

// main() 中使能调试打印,引脚/波特率由 isd_config.ini 提供
uart_init(uttx, ut_buad);

Source: uboot升级使用说明v1.1.2.md

方法二:代码中直接设置打印脚和波特率(文档示例:PA5,1000000 波特率)。

SDK 软件复位触发升级

在 user.h 中使能 USE_UPGRADE_MAGIC 宏后,在 SDK 工程任意位置添加以下代码,即可实现 SDK 软件复位触发升级(升级使用说明):

// 在 sdk 工程中,添加以下代码实现 SDK 软件复位触发(任意位置)
extern u32 nvram_list[];
#define NV_RAM_LIST_ADDR nvram_list
// ...(写入升级 magic 后触发软复位)

Source: uboot升级使用说明v1.1.2.md

该示例展示了公共运行时框架的跨工程协作模式:SDK 侧写标记 → 复位 → uboot 侧读标记。nvram_list 是 SDK 侧暴露的 NVRAM 地址符号,NV_RAM_LIST_ADDR 将其映射为 magic 字的存放位置,uboot 复位后在 main 中检查该地址决定是否进入升级。

配置选项

公共运行时框架的配置集中在编译宏与代码调用两层,均可在构建前按产品需求定制:

选项类型默认/取值说明
USB_MODE编译宏(#defines)0 / 10 = 串口升级模式;1 = USB_HID 升级模式
__DEBUG编译宏(#defines)未定义定义后使能 uboot 调试打印功能
USE_UPGRADE_MAGIC编译宏(user.h)未定义定义后使能 SDK 软件复位触发升级
usb_vid / usb_pid数值常量需与上位机一致USB_HID 模式下 uboot 的设备标识,与 pc_demo\usb_hid\main.cpp 保持一致
isd_config.ini配置文件—调试打印引脚与波特率的配置文件源(方法一)
ut_device_mode(tx, rx, bud)函数调用—串口升级模式下设置 TX 脚、RX 脚、波特率
uart_init(uttx, ut_buad)函数调用—在 main 中应用调试打印配置

配置原则总结:

  • 构建期决定形态:USB_MODE、__DEBUG、USE_UPGRADE_MAGIC 三个宏共同决定 boot 固件的运行形态,同一源码可产出"纯串口版"、"纯 USB_HID 版"、"带调试版"等不同组合。
  • 外设参数分散在代码与配置文件:引脚/波特率既可通过 ut_device_mode 硬编码,也可通过 isd_config.ini 间接提供,前者适合固定产品,后者适合工具链统一管理。
  • VID/PID 是跨工程契约:uboot 与上位机必须成对修改,否则 USB 枚举失败。

API 参考(运行时入口)

函数/符号位置说明
ut_device_mode(tx, rx, bud)app\src\user.c设置串口升级的 TX 引脚、RX 引脚与波特率
uart_init(uttx, ut_buad)main 函数初始化调试打印串口,参数来自 isd_config.ini
main()uboot 入口检测 I/O 电平 / magic 标记,决定进入升级流程还是跳转 SDK
nvram_list[]SDK 工程SDK 侧暴露的 NVRAM 符号,配合 NV_RAM_LIST_ADDR 承载升级 magic
USE_UPGRADE_MAGICuser.h编译宏,使能软件复位触发路径

说明:以上函数签名来自仓库文档的调用描述(升级使用说明 与 L81)。仓库以文档+库文件形式分发,lib.a 内部的完整函数原型未在仓库中展开;如需逐参类型,请以对应芯片 SDK 头文件为准。

故障模式、边界情况与并发考量

构建期故障

故障现象根因处理
错误: uboot.boot数据的CRC校验错误工具链过旧,生成的 boot 数据 CRC 与烧录格式不匹配更新到最新工具(见 README 工具链说明)
生成失败,无效的F文件 / 系统找不到指定的文件工具链或工程文件路径异常更新工具并核对 .cbp 工程路径
编译失败未配套对应命名规则的 lib.a 库与子仓库严格按 SDK 型号查对应表选库(README L8)

运行期边界情况

  • 升级模式误配:USB_MODE 定义缺失或取值非 0/1 时,boot 无法确定外设通路。配置必须显式写在编译 #defines 中。
  • USB_HID 无法识别:uboot 与上位机的 usb_vid/usb_pid 不一致时,设备无法枚举。修改时必须两侧同步(uboot 工程 + pc_demo\usb_hid\main.cpp)。
  • 触发路径失效:I/O 检测依赖具体引脚电平与上电时序,量产治具需与硬件原理图对齐;magic 路径依赖 SDK 在复位前正确写入 nvram_list 地址,若 SDK 版本与 boot 不匹配(如 cpu 目录选错),复位后读不到标记,设备将直接进入 SDK 应用而非升级流程。
  • boot 特殊性:README 明确"鉴于 boot 的特殊性,请务必进行充分测试"。boot 直接操作 Flash 与底层外设,任何库/工程错配都可能造成升级失败甚至变砖,量产前必须全流程验证。

并发与一致性

  • boot 运行于复位后的单任务环境,升级期间不存在多线程并发;一致性风险集中在数据完整性上——通过 CRC 校验在"写入前"拦截损坏数据。
  • 升级过程中的意外断电属于主要中断场景:协议层(见协议流程文档)通过包序号与应答机制保证可重传恢复;本仓库文档层面给出的兜底手段是 I/O 触发——设备变砖后仍可强制进入升级模式重新烧写。
  • 多次升级之间需保证 Flash 写入的原子性由库层处理,本仓库不暴露该细节。

性能与运维要点

  • boot 体积与启动时间:升级通路按宏裁剪(只编入所选模式),有助于控制 boot 体积、缩短启动跳转时间;调试打印(__DEBUG)会显著增加输出开销,量产固件应关闭。
  • 部署流程:编译产物 uboot.boot 必须放入原 SDK 下载目录调试,遵循标准 SDK 的下载流程(README L55)。
  • 多系列维护:每新增一个芯片系列即新增一个 user_boot/cpu/<cpu> 工程目录;线上/线下同步发布机制要求发布时各 cpu 目录的 lib.a 与文档版本保持一致。
  • 升级协议版本:当前协议版本 v1.1.2(初始版本),协议变更会直接影响上位机与 boot 的兼容性,升级上位机与 boot 固件需配套发布。

扩展点

公共运行时框架通过以下方式支持定制与扩展:

  1. 新增芯片系列:在 user_boot/cpu/ 下新增 cpu 目录与 .cbp 工程,同时在 README 的 SDK 对应表中登记映射关系。这是框架最主要的结构化扩展点。
  2. 自定义串口参数:修改 app\src\user.c 的 ut_device_mode(tx, rx, bud) 调用,或通过 isd_config.ini 统一管理引脚与波特率。
  3. 自定义 I/O 触发:在 main 函数中按产品需求检测任意 I/O 电平组合,决定是否进入升级流程(文档仅给出"检测一个 I/O 的电平状态"的范式)。
  4. 升级通路扩展:当前框架内置串口与 USB_HID 两条通路;若要新增其他传输通道(如 BLE OTA),需要在上位机与 boot 两侧同时扩展协议处理,并保持 CRC 校验与 magic 触发机制不变。
  5. 上位机定制:pc_demo\usb_hid\main.cpp 是 USB_HID 上位机的修改入口(VID/PID、交互逻辑),可作为自定义升级工具的起点。

相关链接

  • 仓库根 README(子仓库索引)
  • fw-Bootloader 说明(SDK 对应表与编译说明)
  • uboot 升级使用说明 v1.1.2(模式/调试/触发配置)
  • uboot 升级协议流程 v1.1.2(协议包格式与状态机)
  • ac792n-ota-loader(AC792N OTA Loader)
  • fw-Bootloader 串口升级工具说明(win-uart)
Next
SD 卡与 USB 基础升级通道