4.4.8.2. OTA API

本系统提供底层刷写库 libupdate.so,并实现了一套跨平台的 API,用于烧写 OTA 升级包。

源码路径:hbre/otaupdate/src/ota_apis/hobot_ota_hl.c

头文件: hobot_ota_hl.h

针对 OTA HighLevel API开发了ota_tool 工具,使用该工具可以帮助客户在设计 OTA Service 时更便捷地参考和实现相关功能。

源码路径:hbre/otaupdate/src/ota_tool

头文件: hobot_ota_hl.h

链接库: libupdate.so

动态库接口返回的错误类型

动态库错误值定义如下:

enum ota_err_e {
    OTA_SUCCESS = 0,
    OTAERR_IO,
    OTAERR_PLAT_UNSUPPORT,
    OTAERR_REPEAT,
    OTAERR_MUTEX_INIT_LOCK_ERR,
    OTAERR_NOTINIT,
    OTAERR_NULLPOINTER,
    OTAERR_SHORTBUF,
    OTAERR_THREAD_CREATE,
    OTAERR_RANGE,
    OTAERR_STAGE,
    OTAERR_IMAGE_WRITE,
    OTAERR_BOOT_FAILED,
    OTAERR_VEEPROM,
    OTAERR_FILE_TYPE,
    OTAERR_UNZIP,
    OTAERR_NO_EXISTS,
    OTAERR_MALLOC,
    OTAERR_VERIFY,
    OTAERR_IMG_SIZE,
    OTAERR_UPDATE_STATUS,
}

接口列表

接口原型 描述
int32_t otaInitLib(void); 动态库初始化
int32_t otaDeinitLib(void); 动态库反初始化
int32_t otaGetLibVersion(char *version, int32_t len); 获取动态库版本
int32_t otaRequestStart(const char *image_name, enum ota_update_owner owner); 启动升级线程
int32_t otaGetResult(void); 获取升级状态和结果
int32_t otaGetProgress(void); 获取升级进度
int32_t otaGetUpdatingImageName(char *image_name , int32_t len); 获取正在升级的包
int32_t otaGetSysVersion(char *version, int32_t len); 获取当前系统版本
int32_t otaGetPartition(uint8_t *partition); 获取当前启动的 AB 分区
int32_t otaSetPartition(uint8_t partition); 设置下次启动的 AB 分区
int32_t otaGetOwnerFlag(enum ota_update_owner *owner); 获取 OTA owner(重启后)
int32_t otaMarkOTASuccessful(void); 标记 OTA 升级成功(重启后)
int32_t otaCheckUpdate(void); 检查是否升级成功(重启后)
int32_t otaPartitionSync(void); AB 分区、bak 分区同步
void otaClearFlags(void); 结束升级,清除 ota 标志

otaInitLib

【函数声明】

int32_t otaInitLib(void);

【参数描述】

  • [OUT] N/A

  • [IN] N/A

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_REPEAT: 重复初始化

【功能描述】

板端刷写接口动态库初始化,主要进行全局结构体g_upgrade_info的初始化。

【示例代码】

#include <stdio.h>
#include <hobot_ota_hl.h>
int main(void) {
    int32_t ret;
    ret = otaInitLib();
    if (ret != 0) {
        printf("otaInitLib return: %d\n", ret);
        return ret;
    }
    ret = otaDeinitLib();
    if (ret != 0) {
        printf("otaDeinitLib return: %d\n", ret);
        return ret;
    }
    return 0;
}

otaDeinitLib

【函数声明】

int32_t otaDeinitLib(void);

【参数描述】

  • [OUT] N/A

  • [IN] N/A

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NOTINIT: 当前未初始化,不能调用反初始化

【功能描述】

反初始化

【示例代码】

参考 otaInitLib

otaGetLibVersion

【函数声明】

int32_t otaGetLibVersion(char *version, int32_t len);

【参数描述】

  • [OUT] version: 用于存储 version 信息。version以三段式字符串形式返回(如:1.0.0)

  • [IN] len: 传入的 buffer 长度

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NULLPOINTER: version 空指针

  • -OTAERR_SHORTBUF: 传入的 buffer 过小

  • -OTAERR_PLAT_UNSUPPORT: 不支持获取版本号

【功能描述】

获取本动态库版本

【示例代码】

#include <stdio.h>
#include <hobot_ota_hl.h>
int main(void) {
    int32_t ret;
    char version[128];
    if (ret = otaGetLibVersion(version, sizeof(version))) {
        return ret;
    }
    printf("version: %s\n", version);
}

otaRequestStart

【函数声明】

int32_t otaRequestStart(const char *image_name, enum ota_update_owner owner);

【参数描述】

  • [OUT] N/A

  • [IN] image_name: 升级包绝对路径。支持多种不同类型的包同时传入,用分号隔开。

  • [IN] owner: 发起本次升级的进程, owner 由 enum ota_update_owner 定义

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NULLPOINTER: image_name 空指针

  • -OTAERR_RANGE: owner设置错误,超出当前定义范围

  • -OTAERR_NOTINIT: 未初始化本动态库

  • -OTAERR_REPEAT: 当前有其他进程正在升级

  • -OTAERR_IO: IO失败

  • -OTAERR_THREAD_CREATE: 线程创建失败

【功能描述】

启动升级线程,对传入的image_name进行升级,并设置当前升级所有者

【示例代码】

#include <stdio.h>
#include <hobot_ota_hl.h>
int main(void) {
    int32_t ret;
    int32_t result;
    int32_t progress;
    char imgname[256];
    ret = otaInitLib();
    if (ret != 0) {
        printf("otaInitLib return: %d\n", ret);
        return ret;
    }
    if (ret = otaRequestStart("/userdata/all_in_one.zip", OTA_TOOL)) {
        printf("otaRequestStart return: %d\n", ret);
        return ret;
    }
    do {
        result = otaGetResult();
        if (ret = otaGetUpdatingImageName(imgname, sizeof(imgname))) {
            printf("otaGetUpdatingImageName return: %d\n", imgname);
        }
        progress = otaGetProgress();
        printf("current image: %s, progress: %d\n", imgname, progress);
        sleep(1);
    } while(result != 0 && result != 3);

    ret = otaGetPartition(&cur_part);
    if (ret != 0) {
        printf("otaGetPartition returned with %d\n", ret);
    }
    ret = otaSetPartition(1 - cur_part);
    if (ret != 0) {
        printf("otaSetPartition returned with %d\n", ret);
    }
    /* Then reboot system */
    return 0;
}

otaGetResult

【函数声明】

int32_t otaGetResult(void);

【参数描述】

  • [OUT] N/A

  • [IN] N/A

【返回值】

  • OTA_UPGRADE_NOT_START: 升级未开始

  • OTA_UPGRADE_IN_PROGRESS: 升级中

  • OTA_UPGRADE_SUCCESS: 升级结束,成功

  • OTA_UPGRADE_FAILED: 升级结束,失败

  • -OTAERR_NOTINIT: 未初始化本动态库

【功能描述】

获取升级结果

【示例代码】

参考 otaRequestStart

otaGetProgress

【函数声明】

int32_t otaGetProgress(void);

【参数描述】

  • [OUT] N/A

  • [IN] N/A

【返回值】

  • 0 ~ 100: 当前升级进度(%)

  • -OTAERR_NOTINIT: 未初始化本动态库

【功能描述】

获取当前升级进度

【示例代码】

参考 otaRequestStart

otaGetUpdatingImageName

【函数声明】

int32_t otaGetUpdatingImageName(char *image_name , int32_t len);

【参数描述】

  • [OUT] image_name: 用于存放结果的 buffer。 image_name 可能出现的内容: “idle_state”–升级未开始 “all_img_finish”–升级完成 “”–未开始烧写镜像就失败 其他以”.img”结尾的包名

  • [IN] len: buffer 长度

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NULLPOINTER: image_name 空指针

  • -OTAERR_NOTINIT: 本动态库未初始化

  • -OTAERR_SHORTBUF: buffer长度太短

【功能描述】

获取当前正在升级的镜像

【示例代码】

参考 otaRequestStart

otaGetSysVersion

【函数声明】

int32_t otaGetSysVersion(char *version, int32_t len);

【参数描述】

  • [OUT] version: 用于存储 version 信息。version 中保存系统软件版本,以日期开头(yyyymmdd)

  • [IN] len: 传入的 buffer 长度

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NULLPOINTER: version 空指针

  • -OTAERR_SHORTBUF: 传入的 buffer 过小

  • -OTAERR_IO: io 错误,请重试

【功能描述】

获取当前系统软件版本

【示例代码】

#include <stdio.h>
#include <hobot_ota_hl.h>
int main(void) {
    int32_t ret;
    char version[128];
    if (ret = otaGetSysVersion(version, sizeof(version))) {
        printf("otaGetSysVersion return: %d\n", ret);
        return -1;
    }
    printf("current system version: %s\n", version);
    return 0;
}

otaGetPartition

【函数声明】

int32_t otaGetPartition(uint8_t *partition);

【参数描述】

  • [OUT] partition: 用于接收当前分区的变量地址。 *partition=0:当前为 A 分区,*partition=1:当前为 B 分区

  • [IN] N/A

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NULLPOINTER: partition 为空指针

  • -OTAERR_IO: io 错误,请重试

【功能描述】

获取当前启动 AB 分区

【示例代码】

参考 otaRequestStart

otaSetPartition

【函数声明】

int32_t otaSetPartition(uint8_t partition);

【参数描述】

  • [OUT] N/A

  • [IN] partition: 下次启动分区。0:A 分区,1:B 分区

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NOTINIT: 本动态库未初始化

  • -OTAERR_RANGE: partition 范围错误,partition 范围为0和1

  • -OTAERR_IO: io 错误,请重试

  • -OTAERR_STAGE: 当前升级阶段不支持。升级过程中或升级失败不支持

【功能描述】

设置下次启动的 AB 分区

【示例代码】

参考 otaRequestStart

otaGetOwnerFlag

【函数声明】

int32_t otaGetOwnerFlag(enum ota_update_owner *owner);

【参数描述】

  • [OUT] owner: 用于接收当前升级 owner 的变量。请参考 enum ota_update_owner

  • [IN] N/A

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NOTINIT: 未初始化

  • -OTAERR_NULLPOINTER: partition 为空指针

  • -OTAERR_IO: io 错误,请重试

【功能描述】

获取当前升级 owner

【示例代码】

static int check_and_mark(void) {
    enum ota_update_owner owner;
    int32_t ret;
    ret = otaGetOwnerFlag(&owner);
    if (ret != 0) {
            printf("otaGetOwnerFlag returned with %d\n", ret);
            return -1;
    }
    if (owner != OTA_TOOL) {
            printf("The OTA update is not launched by ota_tool, owner: %d\n", owner);
            return -1;
    }
    ret = otaCheckUpdate();
    if (ret == -OTAERR_IMAGE_WRITE) {
            printf("ota_tool: OTA image write failed, is there a reboot during update?\n");
            goto clearFlags;
    }
    if (ret == -OTAERR_BOOT_FAILED) {
            printf("ota_tool: The new package boot failed. Please check the packages\n");
            goto clearFlags;
    }
    if (ret != 0) {
            printf("otaCheckUpdate returned with %d\n", ret);
            goto clearFlags;
    }
    ret = otaMarkOTASuccessful();
    if (ret != 0) {
            printf("otaMarkOTASuccessful returned with %d\n", ret);
            goto clearFlags;
    }
    ret = otaPartitionSync();
    if (ret != 0) {
            printf("otaPartitionSync returned with %d\n", ret);
            goto clearFlags;
    }
clearFlags:
    otaClearFlags();
    return ret;
}

otaMarkOTASuccessful

【函数声明】

int32_t otaMarkOTASuccessful(void);

【参数描述】

  • [OUT] N/A

  • [IN] N/A

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_NOTINIT: 未初始化

  • -OTAERR_IO: io 错误,请重试

【功能描述】

标记本次升级成功

【示例代码】

参考 otaGetOwnerFlag

otaCheckUpdate

【函数声明】

int32_t otaCheckUpdate(void);

【参数描述】

  • [OUT] N/A

  • [IN] N/A

【返回值】

  • OTA_SUCCESS: 成功

  • -OTAERR_IO: io 错误,请重试

  • -OTAERR_STAGE: 未进行升级

  • -OTAERR_IMAGE_WRITE: 镜像写入失败

  • -OTAERR_BOOT_FAILED: 新镜像启动失败或未切换分区

【功能描述】

检查本次升级是否成功

【示例代码】

参考 otaGetOwnerFlag

otaClearFlags

【函数声明】

void otaClearFlags(void);

【参数描述】

  • [OUT] N/A

  • [IN] N/A

【返回值】

  • N/A

【功能描述】

清除 OTA flags

【示例代码】

参考 otaGetOwnerFlag

otaPartitionSync

【函数声明】

int32_t otaPartitionSync(void);

【参数描述】

  • [OUT] N/A

  • [IN] N/A

【返回值】

  • -OTAERR_NOTINIT: 未初始化

  • -OTAERR_IO: io 错误

  • -OTAERR_REPEAT: 与其他升级进程冲突

  • OTA_SUCCESS: 成功

【功能描述】

AB分区、bak分区同步

【示例代码】

参考 otaGetOwnerFlag