OTA固件

1. 介绍

2.0 版本 OTA 升级方案实现了固件升级、表盘传输、自定义数据传输等功能的统一,通过统一升级协议支持多场景升级。根据芯片所使用的 Flash 类型(NOR Flash/NAND Flash),升级模式存在差异,核心区别在于升级流程、存储布局及交互逻辑。

2. 按 Flash 类型划分的 OTA 方案

2.1 NOR Flash 方案

2.1.1 标准 NOR Flash OTA(独立 OTA Manager)

  • 存储布局:包含独立的ota_manager程序,与boot loader、hcpu(主程序)、RES(资源区)等分区独立划分。

  • 启动流程:每次开机固定执行 boot loader → ota_manager → hcpu,日常运行时主程序在hcpu分区。

  • 升级流程:

    • 触发升级时,设备重启进入ota_manager;

    • ota_manager通过 BLE 与手机交互,下载升级文件并直接覆盖hcpu、RES等目标分区;

    • 下载完成后重启,通过boot loader → ota_manager → hcpu流程运行新程序。

alt text

2.1.2 NOR Flash RAM Run OTA(内存运行 OTA Manager)

  • 存储布局:无独立ota_manager分区,ota_manager程序在升级时加载到 SRAM 运行,需预留备份区存储待升级镜像。

  • 启动流程:日常开机流程为 boot loader → hcpu,hcpu直接运行主程序。

  • 升级流程:

    • 主程序(hcpu)运行时通过 BLE 下载升级资源:

      • 压缩的hcpu镜像下载到备份区;

      • RES、FONT等资源直接覆盖目标分区(此阶段设备功能不可用);

    • 下载完成后重启,触发 boot loader → ota_manager(SRAM运行);

    • ota_manager将备份区的压缩镜像解压到hcpu原始分区,完成后重启进入新程序。

alt text

2.2 NAND Flash 方案

alt text

  • 核心特点:无独立ota_manager,通过双hcpu分区(hcpu1/hcpu2)实现升级,其他资源(如RES、FONT)采用直接覆盖方式。

  • 启动流程:开机时boot loader根据标记选择启动hcpu1或hcpu2(当前活跃分区)。

  • 升级流程:

    • 若当前运行在hcpu1,升级文件下载到hcpu2;反之则下载到hcpu1;

    • 其他资源直接覆盖目标分区(此阶段设备功能可能不可用);

    • 下载完成后重启,boot loader切换到新升级的hcpu分区,完成升级。

  • 差分升级支持:基于文件系统的分区可使用差分包升级(仅需传输与基础版本的差异部分),减少传输数据量。

2.2.1 带 MPI5 的 NAND 方案

  • 需在 NAND 中配置download buffer分区,用于升级与蓝牙相关的 MPI5 组件(避免直接覆盖导致蓝牙功能中断)。

2.2.2 不带 MPI5 的 NAND 方案

  • 无需特殊缓冲配置,仅需正确划分双hcpu分区及资源分区

3. 工程配置(HCPU 侧)

3.1 NOR Flash 配置

alt text

若需将下载内容备份到 Flash,需:

  • 勾选「store backup content on flash」;

  • 在 Flash 映射表(Excel)中配置dfu_download_buffer区域为hcpu分区大小的 0.7 倍。

alt text

3.2 NOR Flash RAM Run 配置

备份区域必须设置到 Flash,配置方式与标准 NOR Flash 一致(需确保备份区大小满足压缩镜像存储)。 alt text

3.3 NAND Flash 配置

  • 带 MPI5:需在工程中启用 MPI5 相关配置,并指定download buffer分区地址及大小。

    alt text

  • 不带 MPI5:无需特殊缓冲配置,仅需正确划分双hcpu分区及资源分区

    alt text

3.4 各项配置说明

  • Device firmware update support functions
    DFU功能本身的开关,需要打开

  • Device firmware using compress
    使用DFU压缩的开关,需要打开

  • Use software function to decompress zlib ota code
    使用软件解压,默认需要关闭,目前默认使用硬件解压,如果启用软件解压,压缩包的制作命令也需要改变,–com_type需要改为1

  • Backup for ota download content
    配置nor flash ota工程的备份位置,nand工程不受影响

  • Store backup content on flash
    备份到flash,重启后仍然保留,但是需要预留flash空间

  • Store backup content on psram
    备份到psran,重启后会自动重新下载,不需要预留空间

  • Support change image download address
    暂未启用,不需要打开

  • OTA error handle in user bin
    暂未启用,不需要打开

  • OTA will use solution’s version check and power off function
    DFU过程钟,调用solution的一些函数,需要打开

  • NOR flash OTA
    先前版本的nor flash ota,无需开启

  • NAND flash OTA
    先前版本的nand flash ota,无需开启

  • SOL2.0 OTA
    solution2.0的升级,需要开启

  • SOL2.0 OTA NOR FLASH
    solution2.0的NOR LFASH升级,视芯片开启

  • SOL2.0 OTA NOR FLASH OTA MAMAGER RUNNING ON RAM
    solution2.0的NOR LFASH,ota manager运行到ram的升级方案,视需求开启

  • SOL2.0 OTA NAND FLASH
    solution2.0的NAND,SD NAND,EMMC的升级,视芯片开启

  • SOL2.0 OTA NAND FLASH ONLY solution2.0的NAND,SD NAND,EMMC的升级,没有MPI5的时候才开启(如52x)

4. 升级包制作

4.1 基础镜像包(.bin)制作

通过imgtool.exe生成加密签名的 OTA 镜像包,核心命令如下:

  1. NOR FLASH imgtool.exe gen_dfu --img_para app 0 0 --key=s01 --sigkey=sig --dfu_id=1 --hw_ver=51 --sdk_ver=7001 --fw_ver=1001001 --com_type=0

  2. NAND FLASH imgtool.exe gen_dfu --img_para app 0 0 --key=s01 --sigkey=sig --dfu_id=1 --hw_ver=51 --sdk_ver=7001 --fw_ver=1001001 --com_type=0 --bksize=2048

参数说明:

  • –img_para: App是制作的bin的文件名,比如当前制作的是app.bin,可以同时制作多个bin。如:--img_para app 0 0 lcpu 0 1

    • 第一个数代表是否使用压缩,如果压缩就填16,只有nor flash ota可以使用压缩,且需要配置备份空间。

    • 第二个数代表image id,每一个image bin都由此ID区分,参照dfu_protocol.h中OTA_EXT_V3定义下的dfu_img_id_t。

  • –dfu_id,nor flash ota升级ota manager时,填2,其余填1。升级ota manager只能单独制作ota_manager.bin,不能和其他bin混合升级。

4.2 NAND Flash 差分包制作

  • 编译基础版本,保存fat_img文件夹,如果升级工程和基础版本不是同一工程,需要copy到其他路径或者重命名,避免编译升级版本覆盖

  • 编译升级版本,保存fat_img文件夹
    alt text

  • 差分包制作,生成的zip包就是基础版本到升级版本的资源包
    alt text alt text

4.3 升级包制作示例(以 SF32LB523 NOR 方案为例)

打包 OTA 升级包所需工具及签名文件在 Solution 中的路径:

  • sdk\tools\secureboot\imgtoolv37.exe

  • sdk\tools\secureboot\sifli02\s01.bin

  • sdk\tools\secureboot\sifli02\sig_hash.bin

  • sdk\tools\secureboot\sifli02\sig_pri.pem

4.3.1 仅升级 APP 分区(快包)

调用 imgtoolv37.exe 程序对APP分区进行封装打包

rem === 52x_pack_ota_app.bat ===

@echo off
cd /d "%~dp0"

set tool_dir=ota_tool
set ota_dir=ota
set root_path=output

set project_name=mod
set verno=1.0

set param1=%~1
set param2=%~2

if "%param1%"=="" (
    echo Input param1 - project_name is NULL
)else (
    set project_name=%param1%
)
if "%param2%"=="" (
    echo Input param2 - verno is NULL
)else (
    set verno=%param2%
)
echo project name is "%project_name%"
echo version number is "%verno%"

set str_date=%date:~0,4%%date:~5,2%%date:~8,2%
set str_time=%time:~0,2%%time:~3,2%
set str_time=%str_time: =0%

set packet_name=%project_name%_%verno%_%str_date%_%str_time%
set packet_path=%root_path%\%ota_dir%
set ota_zip=%root_path%\%packet_name%.zip
set cmd=imgtoolv37.exe gen_dfu --img_para app 0 0 --key=s01 --sigkey=sig --dfu_id=1 
        --hw_ver=51 --sdk_ver=7001 --fw_ver=1001001 --com_type=0

echo %str_date%
echo %str_time%
if exist %root_path% (
    rd %root_path% /s/q
)
md %root_path%
md %packet_path%

for %%s in (*.*) do (
    if %%~xs==.bat (
        echo %%s
    ) else (
        if %%s==7za.exe (
            echo %%s
        ) else if %%s==ER_IROM1.bin (
            echo %%s
        ) else if %%s==ER_IROM2.bin (
            echo %%s
        ) else if %%s==ER_IROM3.bin (
            echo %%s
        ) else if %%s==root.bin (
            echo %%s
        ) else (
            del %%s
        )
    )
)

copy %tool_dir%\imgtoolv37.exe
copy %tool_dir%\*.bin
copy %tool_dir%\*.pem

copy ER_IROM1.bin app.bin

start /wait "" %cmd%

copy ctrl_packet.bin %packet_path%\
copy outapp.bin %packet_path%\

cd %root_path%
start /wait "" ..\7za.exe a %packet_name%.zip %ota_dir%

@pause

4.3.2 升级所有分区(全量包)

调用 imgtoolv37.exe 程序对各分区进行封装打包

rem === 52x_pack_ota_all.bat ===

@echo off
cd /d "%~dp0"

set tool_dir=ota_tool
set ota_dir=ota
set root_path=output

set project_name=mod
set verno=1.0

set param1=%~1
set param2=%~2

if "%param1%"=="" (
    echo Input param1 - project_name is NULL
)else (
    set project_name=%param1%
)
if "%param2%"=="" (
    echo Input param2 - verno is NULL
)else (
    set verno=%param2%
)
echo project name is "%project_name%"
echo version number is "%verno%"

set str_date=%date:~0,4%%date:~5,2%%date:~8,2%
set str_time=%time:~0,2%%time:~3,2%
set str_time=%str_time: =0%

set packet_name=%project_name%_%verno%_%str_date%_%str_time%
set packet_path=%root_path%\%ota_dir%
set ota_zip=%root_path%\%packet_name%.zip
set cmd=imgtoolv37.exe gen_dfu --img_para app 0 0 res 0 3 font 0 4 root 0 5 --key=s01 --sigkey=sig 
        --dfu_id=1 --hw_ver=51 --sdk_ver=7001 --fw_ver=1001001 --com_type=0

echo %str_date%
echo %str_time%
if exist %root_path% (
    rd %root_path% /s/q
)
md %root_path%
md %packet_path%

for %%s in (*.*) do (
    if %%~xs==.bat (
        echo %%s
    ) else (
        if %%s==7za.exe (
            echo %%s
        ) else if %%s==ER_IROM1.bin (
            echo %%s
        ) else if %%s==ER_IROM2.bin (
            echo %%s
        ) else if %%s==ER_IROM3.bin (
            echo %%s
        ) else if %%s==root.bin (
            echo %%s
        ) else (
            del %%s
        )
    )
)

copy %tool_dir%\imgtoolv37.exe
copy %tool_dir%\*.bin
copy %tool_dir%\*.pem

copy ER_IROM1.bin app.bin
copy ER_IROM2.bin res.bin
copy ER_IROM3.bin font.bin

start /wait "" %cmd%

copy ctrl_packet.bin %packet_path%\
copy outapp.bin %packet_path%\
copy outres.bin %packet_path%\
copy outfont.bin %packet_path%\
copy outroot.bin %packet_path%\

cd %root_path%
start /wait "" ..\7za.exe a %packet_name%.zip %ota_dir%

@pause

5. 新增 OTA 类型(自定义传输)

5.1 注册接口

通过OTA_REGISTER接口注册新的 OTA 类型,定义如下:

/*
 *id:  
 *      ota类型的标识, 需要和手机端保持一致。
 *      添加类型在"ota_custom_config.h"的OTA_DFU_CUSTOM_START_IND后添加枚举值。
 *flag: 
 *      可以位或方式传入参数,见ota_flag_t。
 *      OTA_FLAG_REINSTALL: 支持重安装,目前只有NAND ota差分资源支持重安装处理,其余都不支持。
 *      OTA_FLAG_RESUME: 支持续传,目前基于文件系统存储都支持续传,重启/传输其他ota包时不会续传。
 *      OTA_FLAG_SEP_DIR:传输的文件放到由手机和固件协商解析的子目录,只有SF_TOOL传输使用。
 *      OTA_FLAG_BACKGROUND:支持后台传输,建议只有升级较小的文件时使用后台传输功能。
 *dst:  
 *      固件端指定存放路径,如音乐,SF_TOOL,背景传输等手机不知道路径,需要固件指定存放路径。
 *backup:
 *      备份路径,基于文件系统传输都会设置备份路径,可以避免覆盖模式传输失败对原有包的影响。
 *      NAND 差分资源特殊处理,dst和backup不会生效
 *msg_handler:
 *      OTA协议消息处理回调函数
 *
*/
OTA_REGISTER(id, flag, dst, backup, msg_handler)

5.2 数据透传与安装

  • 基于文件系统:可复用sdk提供的ota_fs_proc.c,无需额外实现透传逻辑。

  • 非文件系统(如内存 / 串口写入):需自定义msg_handler处理数据接收与解析。

  • 安装流程(基于文件系统,参考ota_window.c):

    • pre_copy:清除旧文件及内存数据(如旧表盘);

    • copy:SDK 统一处理从备份区到目标区的文件搬移;

    • post_copy:执行安装后逻辑(如加载新表盘、更新配置)。

6. 代码位置

  1. SDK OTA升级核心处理 \sdk\middleware\dfu\dfu_ctrl_ext_v3.c
    负责OTA底层核心逻辑(协议交互,通信处理,flash适配,img固件分片接收,校验,写入等)

  2. 应用层OTA通用定义和接口 \solution\components\ota\common
    定义应用层OTA通用数据结构,状态错误码,状态回复,消息回调注册等

  3. 应用层OTA服务和框架 \solution\components\ble\ble_ota
    ota类型注册,文件资源续传,校验,备份写入,UI交互处理等

  4. 应用层OTA界面 \solution\components\ota\ota_app\gui
    负责HCPU端OTA相关的用户交互界面

  5. 应用层OTA各类型具体处理 \solution\components\ota\ota_app\proc
    针对不同类型的OTA的差异化处理

  6. OTA MANAGER界面和逻辑处理 \solution\components\ota\ota_manager
    负责OTA MANAGER用户交互界面,消息处理等

注意

  • HCPU编译范围,1,2,3,4,5

  • OTA MANAGER编译范围1,2,3,6

7. 常见问题

  • BLE 传输干扰:升级时需尽量停止设备与手机的其他 BLE 交互,避免传输中断。

  • NOR OTA Manager 适配:标准 NOR 方案中,ota_manager运行时使用默认 BLE 广播和 GATT 服务,如自定义需单独适配。

  • 续传限制:支持续传的场景下,重启设备或切换其他 OTA 包后,原续传进度会丢失。

  • 功能可用性:直接覆盖分区(如RES、FONT)时,设备功能不可用,需提示用户等待升级完成。