固件端¶
FAQ1 OTA标志位怎么置,才能重启后进入OTA模式?¶
NOR Flash 方案
// 获取全局变量
dfu_ctrl_ext_v3_env_t *env = dfu_ctrl_ext_v3_get_env();
// 设置为升级状态
env->prog.state = DFU_CTRL_PREPARE_START;
// 任务类型设置为DFU
env->prog.type = DFU_TYPE_DFU
// 存储状态到NV
dfu_ctrl_ext_v3_update_prog_info(env);
// 重启
drv_reboot();
NAND Flash/NOR Flash RAMRUN 方案
ota_ser_res_status(OTA_RES_STATUS_OVERWRITE);
drv_reboot();
FAQ2 资源/数据异常导致开机死机、无限重启的解决方案¶
问题背景 资源加载失败、代码 BUG 等异常,会导致设备开机即死机、无限重启,最终造成设备变砖,需针对性增加容错策略规避该问题。
解决方案(防砖 + 防误触) 核心策略:基于开机异常重启次数阈值,自动触发 OTA 自救,同时规避产线操作导致的误触发,完整逻辑如下:
开机标记:设备上电启动时,立即在 NV 区置位「开机未完成」标志位;
正常清除:设备成功加载至主界面(功能、界面均正常)后,立即清除该标志位;
阈值触发:累计检测到「开机未完成」标志位达 5 次及以上 时,自动触发 OTA 模式(阈值可根据产线需求调整,建议≥5 次);
产线防护:高阈值设计可有效避免「产线焊电池、频繁断电上电」导致的误进入 OTA 模式问题。
FAQ3 OTA手表打印dfu_link_sync_check error排查方向¶
该报错的本质是 手机端 APP 停止向手表发送 OTA 数据,导致手表端 OTA 链路同步超时,排查核心聚焦手机 APP 侧。
看图中log是有客户的ble消息,可以重点排查是不是app处理其他ble服务去了。
OTA的时候,客户有私有协议交互。会导致我们的OTA服务出现异常,sdk会停止送数。
1)其他ble服务影响:手机手表都不要有,包括ota service之外的读写,连接参数更新
send error notify error组包错误
2)app切后台(app在后台时间长了,被系统杀掉,会停止发包)
3)手机灭屏(灭屏,app在后台被杀。会停止发包)
4)手机超时未发包(处理其他逻辑去了)
FAQ4 支持断点续传的OTA软件升级过程中出现重启,重启之后无法进行升级¶
TBD.
FAQ5 修改flash分区后,怎么OTA¶
TBD.
NAND Flash 方案修改分区后,怎么OTA?¶
TBD.
NOR Flash RAMRUN 方案修改分区后,怎么OTA?¶
TBD.
FAQ6 OTA固件时系统状态是什么样¶
NOR Flash OTA 会重启进入OTA manager, 这个模式会一直运行, 直到ota完成。
NAND Flash OTA 会在主代码(hcpu)中进入一个特殊界面,此界面用的资源和字体都是内置编译到主代码。外置的资源不能使用, BT, 文件系统(sys分区除外),kvdb(dfu相关除外)等都不无法使用。
NOR Flash RAMRUN OTA 会在主代码(hcpu)中进入一个特殊界面,此界面用的资源和字体都是内置编译到主代码。外置的资源不能使用, BT, 文件系统(sys分区除外),kvdb(dfu相关除外)等都不无法使用, 接收完成后会重启进入OTA MANAGER进行hcpu解压安装处理。
FAQ7 怎么新增一个OTA类型?¶
在
ota_fs_proc.c中调用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)
在
ota_window.c中的app_ota_pre_copy_handler函数中增加copy前的预处理和app_ota_post_copy_handler函数中增加copy完成后处理
FAQ8 OTA续传规则是怎么样的?¶
OTA续传需要满足以下:
OTA类型注册时支持OTA_FLAG_RESUME标识
OTA续传包和上一次包相同且类型相同
未发生重启行为
续传的信息符合协议要求
FAQ9 OTA应用后怎么指定运行的应用?¶
修改ota_window.c中ota_get_run_app函数返回的应用名即可指定ota完成后运行的应用。
默认逻辑如下:
OTA 应用包完成会运行新增应用
OTA 表盘包完成会运行新表盘
OTA 其他包会运行
app_get_reg_main_app函数返回的应用
FAQ10 如何指定某些应用/界面不能进行OTA升级?¶
调用固件提供的 ota_set_ui_invalid(uint8_t invalid) 函数,即可实现指定场景的 OTA 禁用,接口入参规则:
invalid ≠ 0:标记当前应用 / 界面禁止触发 OTA 升级;
invalid = 0:标记当前应用 / 界面允许触发 OTA 升级。
调用时机:在目标应用 / 界面的初始化和反初始化函数中执行该接口,即可生效; 默认禁用场景:固件原生已默认禁用以下场景的 OTA,无需重复配置:
✔ 开机向导 APP 运行期间;
✔ 设备关机流程执行期间
FAQ11 container工程ota后只有一个app了¶
container工程如果ota了应用包,会删除原有应用,只保留ota后的应用。
FAQ12 如何实现背景图/gif传输?¶
采用自定义传输通道(类型3)实现,适配背景图、背景gif等资源文件OTA下发,步骤如下:
手机端处理:使用配套eZIP工具,将背景图/背景GIF进行压缩处理。
压缩是保证ZIP包内的文件夹子路径与固件端实际使用的路径完全一致, 比如主菜单背景gif的使用路径是
/images/dynamic_bg/xxx.gif,则ZIP包解压后的子路径也需要是/images/dynamic_bg/xxx.gif通过自定义OTA类型3通道下发ZIP包,固件端会将文件保存到指定路径。
FAQ13 OTA资源失败后传输的资源是怎么处理的?¶
传输阶段失败后,已经接收的资源会保留,用以下次续传
传输完成安装阶段失败,已经接收的文件会全部删除
重启后会删除所有已经接收的文件
FAQ14 如何调用接口进行固件安装包升级¶
对于传输由客户管理,安装包放置在TF卡中,需要使用SIFLI安装接口的场景:
HCPU menuconfig打开OTA_EXT_BACKUP_INSTALL_MODE
修改PACKET_NAME宏为客户安装包路径
参考如下代码进行处理,对于安装失败后的重下载处理又客户处理
ota_ext_recv_t *nvm_ota = ota_ext_recv_init(OTA_EXT_TYPE_PAN); /*初始化OTA需要的上下文*/
if (!nvm_ota)
{
rt_kprintf("ota_ext_recv_init failed\n");
break;
}
extern int ota_ext_packet_install(ota_ext_recv_t *recv, const char *packet);
if (0 == ota_ext_packet_install(nvm_ota, env->prog.tf_path)) /*根据ota_bin.c中的定义,将bin解析安装到备份地址或者覆盖地址*/
{
int ret = ota_ext_install_bins(OTA_EXT_TYPE_PAN, nvm_ota); /*将备份地址的bin安装到覆盖的bin*/
if (0 != ret)
{
LOG_I("%s failed ret %d", __func__, ret);
}
LOG_I("%s Upgrade completed", __func__);
extern void ota_ext_reset_all(void); /*清除OTA升级状态*/
ota_ext_reset_all();
ota_ext_recv_deinit(nvm_ota); /*释放上下文*/
drv_reboot(); /*重启进入正常界面*/
}
ota_ext_recv_deinit(nvm_ota);
if (OTA_RES_STATUS_WAIT_INSTALL == ota_ext_get_status()) /*安装包检查失败,未进行真正的安装,可以返回到主代码*/
{
LOG_I("install failed, jump to hcpu");
}
else
{
rt_kprintf("install imgs failed!, goto ota manager\n"); /*安装失败,需要停留在ota manager或者ota_error界面,进行重新下载升级 */
}