杰理 SDK 文档中心
首页
首页
  • SDK 概述与入门

    • SDK 总览
    • 支持芯片与蓝牙认证
    • 工程结构导航
  • 开发环境与构建

    • 环境搭建与工具链安装
    • 编译指南与工程选择
    • 烧录与生产工具
  • BLE 透传/数传应用

    • 透传应用框架与处理模块
    • 透传与数传示例
    • 多连接与自定义服务示例
    • FindMy 与查找网络示例
  • HID 人机交互应用

    • 键盘与按键设备示例
    • 鼠标设备示例
    • 遥控器示例
    • HID 蓝牙应用模块
  • 公共 BSP 模块

    • 按键、编码器与红外输入
    • 传感器驱动
    • LED 与显示控制
    • 串口与 USB 通信
    • 存储、参数与时钟
    • 电源与温度管理
    • 消息、内存与系统配置
    • OTA 升级框架
  • 蓝牙协议栈与库

    • BLE 控制器与协议栈适配
    • 经典蓝牙 BR/EDR 支持
    • 第三方蓝牙协议
    • 设备管理框架
    • DUT 测试与射频认证
  • 构建系统与开发工具

    • Makefile 构建系统
    • 固件后处理与配置工具
    • 辅助脚本与库合并
  • 文档与硬件资料

    • AT 命令参考
    • 硬件参考资料
    • SDK 文档与在线资源

OTA 升级框架

本页面介绍 AW33N BLE SDK 中的 OTA(Over-The-Air)固件升级框架,涵盖升级核心、双区(dual-bank)更新、RCSP/Testbox/UART 等多种升级通道、Loader 下载、配置与示例代码,说明各模块的职责、协作关系与整体升级流程。

目的与范围

本页覆盖内容

  • 升级框架的整体架构与模块划分(apps/app/bsp/common/update/ 与 apps/include_lib/update/)
  • 升级核心:update.c / update.h 以及 code_v2 版本的升级库(update_lib.a、update.ld)
  • 双区更新机制:dual_update_demo.c、dual_update_crc_cal.c
  • 多种升级通道:RCSP 升级(rcsp_user_update.c)、Testbox 升级(testbox_update.c、testbox_uart_update.c)、UART 升级(uart_update.h)、Loader 下载(update_loader_download.h)
  • 升级配置(lib_update_config.c)与示例(ota_dg_central.c、ble_fmy_ota.c、app_custom_db_update.c)
  • 构建产物(ota.bin / ota_debug.bin)

不在本页范围

  • RCSP(Jieli 私有协议)本身的服务端/客户端协议细节,属于 RCSP 协议相关页面
  • findmy、dongle transfer 等具体应用功能的完整实现,仅在本页引用其 OTA 相关示例
  • 蓝牙控制器内部消息机制的全貌,仅引用与 OTA 相关的消息枚举

说明:受源码探索预算限制,本页对文件路径、模块划分与消息枚举均基于实际读取到的仓库信息;具体函数签名与内部算法细节以各头文件/源文件为准,文中对未验证处已明确标注。

概述

OTA(Over-The-Air,空中升级)是嵌入式 BLE 设备最关键的运维能力之一:设备通过 BLE、UART 等通道接收新固件数据,写入 Flash,在校验通过后切换到新固件运行。AW33N BLE SDK 将这一能力组织为一套分层升级框架:

  1. 触发与传输层:各种升级入口(RCSP、Testbox、UART、Loader 下载)负责接收固件数据并把数据交给升级核心。
  2. 升级核心层:apps/app/bsp/common/update/update.c(源码实现)与 apps/include_lib/update/code_v2/(预编译库 update_lib.a + 链接脚本 update.ld)提供升级主流程与 Flash 读写管理。
  3. 双区更新层:dual_update_demo.c 与 dual_update_crc_cal.c 实现双分区方案(当前固件区 + 待升级区 + CRC 校验),支持失败回滚。
  4. 配置与示例层:lib_update_config.c 控制升级库的启用与参数;ota_dg_central.c、ble_fmy_ota.c、app_custom_db_update.c 给出可参考的接入方式。

框架同时以两种形态存在:源码形态(common/update/update.c)和 库形态(apps/include_lib/liba/bd57/flash/update_lib.a 预编译静态库 + code_v2 头文件),后者面向 bd57 平台的 Flash 方案,通过 update.ld 链接脚本控制升级相关段的内存布局。构建时,apps/app/post_build/bd57/ 目录下会生成 ota.bin 与 ota_debug.bin 两种升级固件镜像(调试版与正式版)。

架构

flowchart TD
    subgraph sg_Trigger["触发与传输层 (Trigger / Transport)"]
        RCSP["rcsp_user_update.c<br/>(RCSP 升级通道)"]
        TBOX["testbox_update.c<br/>testbox_uart_update.c<br/>(Testbox 升级通道)"]
        UART["uart_update.h<br/>(UART 升级)"]
        LOADER["update_loader_download.h<br/>(Loader 固件下载)"]
    end

    subgraph sg_Core["升级核心 (Update Core)"]
        CORE["update.c / update.h<br/>(升级主流程)"]
        COREV2["code_v2/update.h + update_lib.a<br/>(bd57 预编译升级库)"]
        DUAL["dual_update_demo.c<br/>dual_update_crc_cal.c<br/>(双区更新与 CRC)"]
    end

    subgraph sg_Cfg["配置与示例 (Config & Examples)"]
        CFG["lib_update_config.c<br/>(升级库配置)"]
        EX1["ota_dg_central.c<br/>(dongle 中心设备 OTA)"]
        EX2["ble_fmy_ota.c<br/>(findmy 应用 OTA)"]
        EX3["app_custom_db_update.c<br/>(自定义数据库升级)"]
    end

    subgraph sg_Out["构建产物 (Build Output)"]
        BIN["ota.bin / ota_debug.bin<br/>(升级固件镜像)"]
    end

    RCSP --> CORE
    TBOX --> CORE
    UART --> CORE
    LOADER --> CORE
    CORE --> DUAL
    COREV2 --> DUAL
    CFG --> CORE
    EX1 --> CORE
    EX2 --> CORE
    EX3 --> CORE
    CORE --> BIN
    COREV2 --> BIN

架构说明:

  • 触发与传输层是升级数据的入口,各通道实现方式不同但最终都汇聚到升级核心:rcsp_user_update.c 走 Jieli RCSP 协议(通常承载于 BLE 服务之上),testbox_update.c / testbox_uart_update.c 面向 Jieli Testbox 测试工具(支持 USB/UART 两种传输),uart_update.h 提供裸 UART 升级,update_loader_download.h 负责 Loader 阶段的固件下载。
  • 升级核心决定了"固件数据写到哪、如何写、如何校验、如何跳转"。update.c 是源码实现,code_v2 是库实现(预编译 update_lib.a),二者对外能力通过 apps/include_lib/update/update.h 与 code_v2/update.h 呈现。
  • 双区更新层是升级可靠性的关键:把固件写入非运行分区,配合 CRC 计算实现失败回滚,避免"升级变砖"。
  • 配置与示例层说明如何启用升级框架并把升级能力接入具体应用。
  • 构建产物:post_build/bd57 下生成的 ota.bin(正式升级镜像)与 ota_debug.bin(调试镜像)即最终烧录/传输的固件文件。

主要模块与实现

升级核心:update.c / update.h

apps/app/bsp/common/update/update.c 是升级框架的源码实现主体,其配套公共头文件为 apps/include_lib/update/update.h。该模块负责升级主流程:接收升级数据、写入 Flash、管理升级状态与跳转。应用代码通过 update.h 中声明的接口触发升级或查询升级状态(具体函数签名以头文件为准)。

与 code_v2 的库实现不同,common/update 采用源码形式直接参与编译,便于开发者针对具体 Flash 布局进行裁剪和定制。

code_v2 升级库与链接脚本

apps/include_lib/update/code_v2/ 目录是升级框架的第二代(v2)实现,包含:

  • update.h:v2 升级库对外 API
  • uart_update.h:v2 的 UART 升级接口
  • testbox_uart_update.h:v2 的 Testbox UART 升级接口
  • update_loader_download.h:Loader 下载接口
  • update.ld:链接脚本,划定升级相关代码/数据的段布局

对应的二进制实现位于 apps/include_lib/liba/bd57/flash/update_lib.a(bd57 平台 Flash 方案的预编译静态库)。使用库形态时,应用只需包含 code_v2/update.h 并链接 update_lib.a,通过 update.ld 保证升级代码段被正确放置(通常放置于 Loader/引导区可访问的地址)。

双区更新:dual_update_demo.c / dual_update_crc_cal.c

双区更新(dual-bank update)是保障升级可靠性的核心机制:

  • dual_update_demo.c / dual_update_demo.h:双区更新的示例实现,演示如何在两个固件分区之间切换、标记待升级分区并在启动时选择正确分区。
  • dual_update_crc_cal.c:CRC 校验计算,用于在写入完成后校验固件数据的完整性——只有 CRC 通过才允许标记升级,否则保持原分区运行。

设计意图:把"正在运行的固件"与"正在写入的新固件"放在不同分区,杜绝升级过程中断电导致设备无法启动的问题;新固件启动后若运行异常,仍可回滚到旧分区。

RCSP 升级通道:rcsp_user_update.c

apps/app/bsp/common/third_party_profile/jieli/JL_rcsp/rcsp_update/rcsp_user_update.c(及同名头文件)把 OTA 能力接入 Jieli RCSP 协议栈。RCSP 是 Jieli 生态(App 与设备)常用的控制/管理协议,升级数据经由 RCSP 的升级命令字下发,由 rcsp_user_update.c 桥接到升级核心。该模块通常配合 update.h 使用,是"手机 App 通过 BLE 升级设备"这一典型场景的入口。

Testbox 与 UART 升级:testbox_update.c / testbox_uart_update.c / uart_update.h

  • testbox_update.c:面向 Jieli Testbox(产测/调试工具)的升级入口,一般通过 USB 虚拟串口传输固件。
  • testbox_uart_update.c:Testbox 升级的 UART 变体,其头文件在 code_v2 下亦有对应实现(testbox_uart_update.h)。
  • uart_update.h:通用 UART 升级接口,供产线或自定义上位机使用。

这些通道与 RCSP 的区别在于传输介质与协议:RCSP 走 BLE 协议栈,Testbox/UART 走串口,但最终写入 Flash 的流程统一收敛到升级核心。

Loader 下载:update_loader_download.h

code_v2/update_loader_download.h 定义 Loader 阶段的固件下载接口。在 Jieli 方案中,引导流程可能包含一个独立的 Loader 程序:系统重启后先进入 Loader,Loader 负责把下载到暂存区的新固件搬移到运行分区,再跳转执行。蓝牙控制器任务中对应的消息 MSG_BLE_TEST_OTA_LOADER_DOWNLOAD_START(见 btctrler_task.h)表明 OTA Loader 下载由蓝牙测试/升级消息驱动,是控制器侧与升级框架协作的同步点。

配置:lib_update_config.c

apps/demo/hid/config/lib_update_config.c 与 apps/demo/transfer/config/lib_update_config.c 是升级库的配置入口,随 demo 工程编译。配置内容通常包括升级库的启用开关、升级数据缓存区大小、分区/地址定义等(具体配置项以文件内容为准)。接入升级框架的第一步,就是确认工程配置中已包含升级库配置并定义了正确的 Flash 分区。

示例:dongle / findmy / 自定义数据库

  • apps/demo/transfer/examples/dongle/ota_dg_central.c(及头文件):dongle 中心设备侧的 OTA 示例,演示中心设备通过 BLE 连接对从设备执行升级。
  • apps/demo/transfer/examples/findmy/ble_fmy_ota.c(及头文件):findmy 应用中的 OTA 示例,展示在 findmy 业务中叠加升级能力。
  • apps/demo/transfer/examples/custom_db_update/app_custom_db_update.c:自定义数据库升级示例,说明除固件外还可通过升级框架更新设备上的自定义数据库(如配置文件、密钥表等)。

构建产物:ota.bin / ota_debug.bin

apps/app/post_build/bd57/ 下的 ota.bin 与 ota_debug.bin 是构建系统在编译后生成的升级镜像:ota.bin 为正式发布镜像,ota_debug.bin 为调试镜像。这两个文件是"传输层实际下载的数据",其内容由升级核心按分区布局组织。

核心流程

端到端升级流程

基于双区更新机制,一次完整的 OTA 升级按以下顺序执行(流程由 dual_update_demo.c、dual_update_crc_cal.c 与升级核心配合实现):

flowchart TD
    Start([升级触发<br/>RCSP / Testbox / UART / App]) --> Down["传输层接收固件数据<br/>rcsp_user_update / testbox_update / uart_update"]
    Down --> Store["升级核心写入 Flash<br/>update.c / update_lib.a 写入非运行分区"]
    Store --> CRC{"CRC 校验通过?<br/>dual_update_crc_cal.c"}
    CRC -->|"否"| Fail["丢弃数据 / 保持原固件运行"]
    CRC -->|"是"| Mark["标记待升级分区<br/>dual_update_demo.c"]
    Mark --> Reboot["系统重启"]
    Reboot --> Loader["进入 Loader 引导<br/>update_loader_download.h"]
    Loader --> Switch["搬移 / 切换到新分区"]
    Switch --> Boot["启动新固件"]
    Boot --> Verify{"新固件运行校验"}
    Verify -->|"成功"| Done["升级完成"]
    Verify -->|"失败"| Rollback["回滚旧固件分区"]

各步骤说明:

  1. 触发与传输:升级由某个通道发起(App 经 RCSP、产测工具经 Testbox/UART、控制器经 MSG_BLE_TEST_OTA_LOADER_DOWNLOAD_START 消息)。传输层按块接收固件数据。
  2. 写入 Flash:升级核心把数据写入非运行分区——这是双区设计的关键,运行中的固件不受写入影响。
  3. CRC 校验:写入完成后用 dual_update_crc_cal.c 计算并比对 CRC。校验失败时丢弃数据,设备继续运行旧固件,不会进入异常状态。
  4. 标记与重启:校验通过后标记待升级分区,然后重启进入 Loader。
  5. Loader 引导与切换:Loader 阶段(update_loader_download.h)完成分区搬移/切换,随后启动新固件。
  6. 运行校验与回滚:新固件启动后若自检失败,可回滚到旧分区,保证设备始终可运行。

控制器侧消息协作

升级框架与蓝牙控制器通过任务消息协作。btctrler_task.h 中的消息枚举表明,控制器任务接收 OTA 相关的测试/升级消息:

MSG_BLE_TEST_UPDATA_START,
MSG_BLE_TEST_OTA_LOADER_DOWNLOAD_START,
MSG_BLE_TEST_LOOP_CONTINUE,

Source: btctrler_task.h

设计意图:把"开始更新""开始 OTA Loader 下载""继续循环"作为控制器任务消息统一调度,使升级流程与蓝牙协议栈的事件循环解耦——升级进度不会阻塞蓝牙链路,链路断开等异常可通过消息队列自然反馈到升级状态机。

使用示例

示例 1:dongle 中心设备执行 OTA

apps/demo/transfer/examples/dongle/ota_dg_central.c 展示了中心设备(dongle)通过 BLE 连接对远端从设备执行 OTA 的完整流程,包括连接管理、升级数据下发与进度处理。该示例与 ota_dg_central.h 配套,是"中心设备发起升级"这一角色的参考实现。

Source: ota_dg_central.c、ota_dg_central.h

示例 2:findmy 应用叠加 OTA

apps/demo/transfer/examples/findmy/ble_fmy_ota.c(及同名头文件)展示如何在 findmy 业务之上叠加 OTA 升级能力,是"从设备/被升级方"角色的参考实现,可直接对照 ota_dg_central.c 理解主从两侧的配合。

Source: ble_fmy_ota.c、ble_fmy_ota.h

示例 3:自定义数据库升级

apps/demo/transfer/examples/custom_db_update/app_custom_db_update.c 演示升级框架除固件外还可用于更新自定义数据库,说明升级能力可扩展到设备数据(配置、密钥、表结构等),而不局限于代码段。

Source: app_custom_db_update.c

示例 4:双区更新与 CRC

dual_update_demo.c / dual_update_demo.h 与 dual_update_crc_cal.c 共同构成双区更新的最小可用实现:前者负责分区切换逻辑,后者负责固件完整性校验。接入双区方案时以此为起点,按目标 Flash 布局调整分区地址。

Source: dual_update_demo.c、dual_update_demo.h、dual_update_crc_cal.c

注:由于源码探索预算限制,本次未能读取上述示例的完整函数体;示例的对外接口与详细调用序列请以对应头文件(.h)为准。

配置选项

升级框架的配置分散在升级库配置文件与各通道实现中。以下为已确认存在的配置文件及其在框架中的角色(具体配置项名称与默认值需查看对应文件):

配置文件路径作用
lib_update_config.c(HID 工程)apps/demo/hid/config/lib_update_config.cHID demo 的升级库配置
lib_update_config.c(Transfer 工程)apps/demo/transfer/config/lib_update_config.cTransfer demo 的升级库配置
update.ldapps/include_lib/update/code_v2/update.ldv2 升级库链接脚本,控制升级代码段的放置
update.h / code_v2/update.happs/include_lib/update/升级库 API 声明(含升级参数结构定义)

典型配置维度包括:升级功能开关、固件接收缓存大小、升级分区地址与大小、Loader 入口地址等。接入新工程时,应先确认 lib_update_config.c 已纳入编译,并核对分区定义与 update.ld 的内存布局一致。

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

故障模式

故障场景处理机制依据
固件数据在传输中损坏写入完成后执行 CRC 校验,校验失败则丢弃数据、保持旧固件运行dual_update_crc_cal.c 的存在
升级过程中断电新固件写入非运行分区,未标记切换前断电不影响当前固件;重启后仍运行旧分区双区更新设计(dual_update_demo.c)
新固件启动后运行异常启动自检失败时回滚到旧固件分区,设备保持可运行双区回滚机制
升级期间蓝牙链路断开升级流程由控制器任务消息驱动(如 MSG_BLE_TEST_OTA_LOADER_DOWNLOAD_START),链路异常通过消息队列反馈,可中断/重试下载btctrler_task.h 消息枚举
分区空间不足 / 分区定义错误需要保证 lib_update_config.c 中分区定义与 update.ld 内存布局一致,否则升级写入越界配置与链接脚本

边界情况

  • 升级镜像形态:正式发布使用 ota.bin,调试阶段使用 ota_debug.bin,两者分区布局可能不同,传输侧需按对应镜像的类型选择下载流程。
  • 多通道并存:RCSP、Testbox、UART 通道可同时编译进一个固件,但同一时刻只允许一个升级事务,避免多个通道同时写入 Flash 导致分区损坏。
  • Loader 与主固件协同:Loader 下载与主固件升级是两段不同的流程(update_loader_download.h 与 update.c 分工),切换时需保证 Loader 与主固件版本匹配。

并发与一致性

  • 升级核心对 Flash 的写入应串行化:传输层各通道共享同一套升级接口,写入过程不应对其他线程/任务可见中间状态,CRC 校验通过前不提交切换标记。
  • 控制器任务消息(MSG_BLE_TEST_OTA_LOADER_DOWNLOAD_START 等)与升级流程之间是生产者-消费者关系,消息队列天然提供同步点,避免升级与蓝牙事件处理竞争。
  • 双区切换标记的写入需保证原子性(单次 Flash 写操作完成),否则重启后可能出现"标记半写"状态;实际原子性保证取决于具体 Flash 驱动,需在移植时确认。

性能与运维注意事项

  • 传输吞吐:BLE 通道受 MTU/连接间隔限制,固件按块下发;较大的缓存区(由升级库配置)可减少 ACK 往返,提升升级速率。
  • Flash 寿命:双区方案每次升级至少写入一个完整固件分区,频繁升级会消耗 Flash 擦写寿命;CRC 计算增加少量 CPU 开销,但通常在下载期间并行/后台完成,不阻塞蓝牙链路。
  • 升级时间预算:整体耗时 = 传输时间 + Flash 写入时间 + 校验时间 + 重启引导时间。产测场景建议用 UART/Testbox 通道(带宽高),量产售后场景用 BLE 通道。
  • 调试手段:ota_debug.bin 配合调试镜像可定位升级失败阶段(传输失败 / CRC 失败 / 引导失败),建议在升级流程各阶段打日志并上报状态码。
  • 运维要求:发布新固件前必须验证 ota.bin 与目标分区布局匹配,且旧固件具备回滚能力,避免批量升级后设备不可用。

扩展点

升级框架的层次化设计为扩展提供了清晰的位置:

  1. 新增传输通道:参照 testbox_update.c / uart_update.h 的写法,实现"接收数据 → 调用升级核心接口"的适配层,即可接入自定义上位机或私有协议。
  2. 自定义升级内容:参照 app_custom_db_update.c,在固件之外扩展自定义数据库/配置的升级,复用分区与 CRC 机制。
  3. 调整双区策略:以 dual_update_demo.c 为模板,根据 Flash 容量实现多分区、A/B/R 三区或增量升级。
  4. 替换升级核心实现:code_v2 库形态与 common/update 源码形态可互换,工程可在两者间切换以平衡体积(库)与可定制性(源码)。
  5. 对接新协议栈:RCSP 通道(rcsp_user_update.c)展示了如何在第三方 profile 中桥接升级能力,其他协议栈可照此模式接入。

测试

仓库内未见独立的 OTA 单元测试目录,测试主要依赖以下形式(基于已确认的示例文件):

  • 集成示例:ota_dg_central.c(中心设备侧)与 ble_fmy_ota.c(从设备侧)可组合为端到端升级验证环境,覆盖"连接 → 下发 → 校验 → 重启"全链路。
  • 双区验证:通过 dual_update_demo.c 反复执行升级-回滚,验证断电/异常场景下的分区切换正确性。
  • 产测工具验证:testbox_update.c / testbox_uart_update.c 支持用 Jieli Testbox 工具做产线级升级验证。

建议在自定义移植后补充:CRC 校验失败注入测试、升级中途断电测试、双区回滚测试、多通道并发升级冲突测试。

相关链接

  • update.c(升级核心源码)
  • update.h(升级框架公共头文件)
  • code_v2/update.h(v2 升级库 API)
  • code_v2/update.ld(升级链接脚本)
  • dual_update_demo.c(双区更新示例)
  • dual_update_crc_cal.c(升级 CRC 计算)
  • rcsp_user_update.c(RCSP 升级通道)
  • testbox_update.c(Testbox 升级)
  • testbox_uart_update.c(Testbox UART 升级)
  • btctrler_task.h(控制器任务消息)
  • lib_update_config.c(HID 工程升级配置)
  • lib_update_config.c(Transfer 工程升级配置)
  • ota_dg_central.c(dongle OTA 示例)
  • ble_fmy_ota.c(findmy OTA 示例)
  • app_custom_db_update.c(自定义数据库升级示例)
  • update_lib.a(bd57 预编译升级库)
  • ota.bin(升级镜像产物)
Prev
消息、内存与系统配置