
系统版本: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}`)
};

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



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


手动(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 卡异常,升级可能失败
