讨论广场 问答详情
4.0 APP 本地OTA全量升级失败(已解决)
mart!nhu 2025-03-25 09:55:24
369 评论 分享

系统版本:OpenHarmony4.0.10.13

平台:RK3588

问题现象:

1.将制作好的OTA全量包updater_full.zip放在/data/updater/updater.zip, 通过以下命令手动升级正常

# ls -al /data/updater
total 398711
drwxrwxrwx  2 update update        3488 2025-03-26 14:08 .
drwxrwx--x 17 system system        4096 2025-03-26 13:55 ..
-rw-r--r--  1 root   media_rw 407866635 2025-03-26 14:08 updater.zip

#write_updater updater /data/updater/updater.zip

#reboot updater

=>设备重启进入灰色背景升级界面,升级成功

2.app中通过以下代码启动本地升级

 let otaUpgradeConfig: Array<otaUpdate.UpgradeFile> = [{
    fileType: otaUpdate.ComponentType.OTA, // OTA包
    filePath: updateFilePath // 本地升级包路径:/data/updater/updater.zip
  }];

  try {
    let localUpdater: otaUpdate.LocalUpdater = otaUpdate.getLocalUpdater()
    await localUpdater.applyNewVersion(otaUpgradeConfig).then(() => {
      Log.showInfo(TAG, `applyNewVersion success`);
    }).catch((err: BusinessError) => {
      Log.showError(TAG, `applyNewVersion error ${JSON.stringify(err)}`)
    })
  } catch(error) {
    Log.showError(TAG, `Fail to get localUpdater error: ${error}`)
  };

=>设备重启进入白色背景升级UI,升级失败:

log见附件,分析log可见进入了sdcard升级:

03-25 01:33:42.687 Updater 285 I updater_main.cpp 495 : start sdcard update
03-25 01:33:42.702 Updater 285 I misc_info.cpp 94 : WriteUpdaterMiscMsg::misc path : /dev/block/platform/fe2e0000.mmc/by-name/misc
03-25 01:33:42.729 Updater 285 E mount.cpp 138 : child terminated by exit 12
03-25 01:33:42.729 Updater 285 E mount.cpp 156 : failed to mount /dev/block/mmcblk1p1 on /sdcard, errno is 22
03-25 01:33:42.745 Updater 285 E mount.cpp 138 : child terminated by exit 12
03-25 01:33:42.745 Updater 285 E mount.cpp 156 : failed to mount /dev/block/mmcblk1p1 on /sdcard, errno is 22
03-25 01:33:42.761 Updater 285 E mount.cpp 138 : child terminated by exit 12
03-25 01:33:42.761 Updater 285 E mount.cpp 156 : failed to mount /dev/block/mmcblk1p1 on /sdcard, errno is 22
03-25 01:33:42.761 Updater 285 E sdcard_update.cpp 77 : mount sdcard fail!
03-25 01:33:42.761 Updater 285 E updater_main.cpp 452 : can not find sdcard packages
03-25 01:33:44.762 Updater 285 D updater_ui_facade.cpp 186 : show failed page
03-25 01:33:49.762 Updater 285 D label_btn_adapter.cpp 41 : key OnFocus
03-25 01:34:10.770 Updater 301 D label_btn_adapter.cpp 55 : key OnBlur
03-25 01:34:10.771 Updater 301 D label_btn_adapter.cpp 41 : key OnFocus
03-25 01:34:10.820 Updater 301 I event_listener.cpp 56 : callback by async method
03-25 01:34:10.821 Updater 306 I updater_ui.cpp 66 : On Label Reboot
03-25 01:34:10.822 Updater 306 I utils.cpp 579 : updater mode
03-25 01:34:10.822 Updater 306 D mount.cpp 105 : Umount for path /system
03-25 01:34:10.823 Updater 306 D mount.cpp 105 : Umount for path /vendor
03-25 01:34:10.824 Updater 306 D mount.cpp 202 : Mount for path /data
03-25 01:34:11.258 Updater 306 D mount.cpp 202 : Mount for path /data/updater/log
03-25 01:34:11.258 Updater 306 I mount.cpp 207 : /data/updater/log already mounted
03-25 01:34:11.259 Updater 306 I utils.cpp 104 : subDir : /data
03-25 01:34:11.259 Updater 306 I utils.cpp 104 : subDir : /data/updater

问题:

1.app如何进行本地OTA全量升级,使用什么接口和顺序调用

2.灰色和白色背景的OTA升级有什么区别

 

分析过程:

由于通过命令可以正常升级则说明ota包是没有问题的。

ota包升级失败重启后查看设备/data/updater/log/updater_log日志

I updater_main.cpp 606 : Ready to start
...
I updater_main.cpp 495 : start sdcard update
E misc_info.cpp 31 : huzhou fopen path '/dev/block/platform/fe2e0000.mmc/by-name/misc
E mount.cpp 138 : child terminated by exit 11
E mount.cpp 151 : SD card never insert, dont try again, failed to mount /dev/block/mmcblk1p1 on /sdcard
E sdcard_update.cpp 77 : mount sdcard fail!
E updater_main.cpp 452 : can not find sdcard packages

可知:applyNewVersion()默认进入了sd卡升级流程,而此时设备没有插入sd卡,ota包路径也异常,因此升级失败

如果sd卡插上,ota包(制作ota包命令需添加-sc)路径正常,理应可以正常升级。

由于笔者项目要求使用本机存储升级,sd卡会存在升级过程中拔卡导致升级异常风险。

解决方案:

1、期望在app执行以下hdc shell 升级命令,模拟手动升级

write_updater updater /data/updater/updater.zip
reboot updater

参考 云端筑梦 巨佬的demo https://laval.csdn.net/user/discuss/65e9c1f61a836825ed790f76

尝试调用升级命令

Button("write_updater")
          .onClick(()=>
          {
            testNapi.hdcshell("write_updater updater /data/updater/updater.zip")
          })
          .margin(50)


        Button("reboot updater")
          .onClick(()=>
          {
            testNapi.hdcshell("reboot updater")
          })

但升级失败,从log中发现:write_updater 命令执行报错;若手动输入write_updater ...命令,app执行reboot updater则正常升级

尝试配置沙箱路径权限等仍未解决报错问题。此方案未打通

2、使用在线升级接口updater.upgrade(),ota包放在/data/update/ota_package/updater.zip

解决升级流程status状态不正确导致未进入upgrade问题后,调用接口仍未重启进入升级UI,此方案未成功

3、修改sd卡升级 为 强制升级

分析applyNewVersion接口调用流程,最终进行以下修改,将sd卡升级流程切换为强制升级后,验证OK

base\update\updateservice\services\engine\src\update_service_local_updater.cpp

int32_t UpdateServiceLocalUpdater::ApplyNewVersion(const UpgradeInfo &info, const std::string &miscFile,
    const std::string &packageName, BusinessError &businessError)
{
#ifndef UPDATER_UT
    SYS_EVENT_SYSTEM_UPGRADE(0, UpdateSystemEvent::UPGRADE_START);
    businessError.errorNum = CallResult::SUCCESS;
    std::vector<std::string> packageNames;
    packageNames.push_back(packageName);
    //修改sd卡升级流程为强制升级
    //int32_t ret = RebootAndInstallSdcardPackage(miscFile, packageNames) ? INT_CALL_SUCCESS : INT_CALL_FAIL;
    int32_t ret = RebootAndInstallUpgradePackage(miscFile, packageNames) ? INT_CALL_SUCCESS : INT_CALL_FAIL;
    SYS_EVENT_SYSTEM_UPGRADE(
        0, ret == INT_CALL_SUCCESS ? UpdateSystemEvent::EVENT_SUCCESS_RESULT : UpdateSystemEvent::EVENT_FAILED_RESULT);
    return ret;
#else
    return INT_CALL_SUCCESS;
#endif
}

总结:

1. OTA本地升级时,applyNewVersion()默认走sd卡升级流程,如果需走/data升级,需修改applyNewVersion接口流程

2. app ota本地升级核心代码:

  let otaUpgradeConfig: otaUpdate.UpgradeFile = {
    fileType: otaUpdate.ComponentType.OTA, // OTA包
    filePath: "/data/updater/updater.zip"  // 本地升级包路径
  };

  let otaUpgradeConfigArr: Array<otaUpdate.UpgradeFile> = [ otaUpgradeConfig ]

 await localUpdater.applyNewVersion(otaUpgradeConfigArr).then(() => {
      Log.showInfo(TAG, `applyNewVersion success`);
    }).catch((err: BusinessError) => {
      Log.showError(TAG, `applyNewVersion error ${JSON.stringify(err)}`)
    })
  } catch(error) {
    Log.showError(TAG, `Fail to get localUpdater error: ${error}`)
  };

 

369 评论 分享
相关文件下载
updater_log.rar
2.59 KB
下载
写回答
全部评论(8)

请问下楼主,我这边用write_updater 方式进行RK3588 OTA升级,从日志上看能够升级成功,但升级过程UI界面一直黑屏。已经配置过resources/板卡下面的资源,还是黑屏,能否给出点排查建议?

2025-06-11 16:53:49
2025-06-16 13:31:41
引用:“已经对比过rk3568和rk3588的升级日志,没看到明显差别,update ui相关日志都是正常的”
提供两份log看看
2025-06-16 13:31:41
2025-06-16 10:18:58
引用:“log显示升级成功,最好预埋点log确认镜像真的升级成功;从你的现象描述像是没有适配好rk3588的update ui,重点检查升级log中出现的resource、UI的error”
已经对比过rk3568和rk3588的升级日志,没看到明显差别,update ui相关日志都是正常的
2025-06-16 10:18:58
2025-06-11 19:05:12
log显示升级成功,最好预埋点log确认镜像真的升级成功;从你的现象描述像是没有适配好rk3588的update ui,重点检查升级log中出现的resource、UI的error
2025-06-11 19:05:12
2 楼

已解决,修改详情内容见文末

2025-03-26 14:46:31
2025-03-28 15:39:41
sd升级尽量还是走RebootAndInstallSdcardPackage接口哈,sdcard升级包需要注意制作升级包命令要加-sc,参考base/update/packaging_tools/build_update.py
2025-03-28 15:39:41

     手动(write_updater updater 命令)升级,进入的是 灰色背景升级界面(成功)

     使用 applyNewVersion 方法升级后,进入的是 白色背景升级界面(失败)
    1.  可能 applyNewVersion 默认走 SD 卡升级逻辑,而不是 手动 write_updater 那种 data 目录升级方式

		let localUpdater: otaUpdate.LocalUpdater = otaUpdate.getLocalUpdater()
		await localUpdater.applyNewVersion(armUpgradeConfig)

2. 尝试一下 使用 System Updater Shell 方式,让 App 直接调用 write_updater

	import systemplugin from '@ohos.systemplugin';

	async function startOtaUpdate() {
		try {
			// 运行 write_updater 命令,类似于手动升级方式
			await systemplugin.shell.executeCmd(`write_updater updater /data/updater/updater_full.zip`);
			await systemplugin.shell.executeCmd(`reboot updater`);
		} catch (err) {
			console.error(`OTA update failed: ${JSON.stringify(err)}`);
		}
	}

3. 灰色背景 OTA(成功) → Recovery 模式,支持 write_updater 方式
   白色背景 OTA(失败) → 进入的是 SD 卡升级模式,如果SD 卡异常,升级可能失败

2025-03-25 10:34:04
2025-03-25 10:44:24
未找到@ohos.systemplugin
2025-03-25 10:44:24