MS-RTOS OTA 升级

更新时间:
2023-08-09
下载文档

MS-RTOS OTA 升级

本章将介绍 MS-RTOS OTA 升级服务的实现。

OTA 升级流程

OTA 升级服务是一个 APP 或内核服务,它负责与远程的升级服务器通信,当有新固件发布时,它主动下载的新版本 OS 镜像、APP 镜像、启动参数文件(这些文件可以是差分文件,也允许只升级部分文件)到外部文件系统,在外部文件系统中生成升级动作文件和升级请求文件,然后调用 ms_rtos_update 函数,MS-RTOS 将文件系统 CACHE 回写到磁盘后进行重启。重启后由 MS-BOOT 进行 OS 镜像的升级工作,由 MS-RTOS 进行 APP 镜像、启动参数文件的升级工作。

OTA 升级服务

流程:

  • 下载新版本 OS 镜像、APP 镜像、启动参数文件到外部文件系统
  • 如果是差分包,利用 ms_patch 函数生成新的完整包
  • 检查固件的完整性、合法性
  • 在外部文件系统中创建升级动作文件
  • 在外部文件系统中创建升级请求文件
  • 调用 ms_rtos_update 函数

新固件下载

下载的新版本 OS 镜像、APP 镜像、启动参数文件到外部文件系统。下载完毕后需要检查固件的完整性、合法性。

创建升级请求文件

升级请求文件是系统重启时 MS-BOOT 和 MS-RTOS 用来判断是否需要升级的标志。

升级请求文件储存了升级动作文件的路径。

在 OTA 升级服务程序中可以使用如下代码创建升级请求文件:

#define __UPDATE_ACTIONS_PATH               "/nor/update/update_actions"
#define __UPDATE_REQUEST_PATH               "/nor/update/update_req"

    fd = ms_io_creat(__UPDATE_REQUEST_PATH, 0666);
    ms_io_write(fd, __UPDATE_ACTIONS_PATH, sizeof(__UPDATE_ACTIONS_PATH));
    ms_io_close(fd);

创建升级动作文件

升级动作文件描述了升级过程需要执行哪些动作。

升级动作文件内容是一个 ms_flashfs_action_t 类型的数组,每个元素是一个升级动作:

MS_STRUCT_PACK_BEGIN
struct ms_flashfs_action {
    // 动作 id
#define MS_FLASHFS_ACTION_CREATE_FILE       0U // 创建文件
#define MS_FLASHFS_ACTION_UPDATE_FILE       1U // 升级文件
#define MS_FLASHFS_ACTION_REMOVE_FILE       2U // 删除文件
#define MS_FLASHFS_ACTION_DEFRAG            3U // 磁盘碎片整理
#define MS_FLASHFS_ACTION_UPDATE_OS         4U // 升级 OS 镜像(该类型动作由 MS-BOOT 执行) 
    MS_STRUCT_PACK_FIELD(ms_uint32_t  id);           // 动作 id
    MS_STRUCT_PACK_FIELD(ms_uint32_t  reserve_size); // 预留给未来升级的大小
    MS_STRUCT_PACK_FIELD(ms_uint32_t  crc32);        // 文件的 CRC32
    MS_STRUCT_PACK_FIELD(ms_err_t     err);          // 动作执行的错误码
    MS_STRUCT_PACK_FIELD(char         name[MS_FLASHFS_NAME_BUF_SIZE]);   // 文件名
    MS_STRUCT_PACK_FIELD(char         source[MS_FLASHFS_PATH_BUF_SIZE]); // 外部文件系统中的源文件
} MS_STRUCT_PACK_STRUCT;
MS_STRUCT_PACK_END
typedef struct ms_flashfs_action ms_flashfs_action_t;

在 OTA 升级服务程序中可以使用如下代码创建升级动作文件:

#define __UPDATE_FIRMWARE_PATH(x)           "/nor/update/firmware/"x
#define __UPDATE_ACTIONS_PATH               "/nor/update/update_actions"
#define __UPDATE_REQUEST_PATH               "/nor/update/update_req"

    ms_flashfs_action_t actions[2];

    /*
     * 创建启动参数文件 ms-boot-param.dtb 动作
     */
    actions[0].id = MS_FLASHFS_ACTION_CREATE_FILE;
    actions[0].reserve_size = 0;
    actions[0].err = MS_ERR_NONE;
    ms_file_crc32(__UPDATE_FIRMWARE_PATH("ms-boot-param.dtb"), &actions[0].crc32);
    strcpy(actions[0].name, "ms-boot-param.dtb");
    strcpy(actions[0].source, __UPDATE_FIRMWARE_PATH("ms-boot-param.dtb"));

    /*
     * 安装应用 app1.bin 动作
     */
    actions[1].id = MS_FLASHFS_ACTION_CREATE_FILE;
    actions[1].reserve_size = 0;
    actions[1].err = MS_ERR_NONE;
    ms_file_crc32(__UPDATE_FIRMWARE_PATH("app1.bin"), &actions[1].crc32);
    strcpy(actions[1].name, "app1.bin");
    strcpy(actions[1].source, __UPDATE_FIRMWARE_PATH("app1.bin"));

    /* 其它动作 */

    /*
     * 创建升级动作文件
     */
    int fd = ms_io_creat(__UPDATE_ACTIONS_PATH, 0666);
    ms_io_write(fd, actions, sizeof(actions));
    ms_io_close(fd);

BOOTLOADER 要求

CPU 重启后,首先运行 BOOTLOADER,OS 镜像的升级需要由 BOOTLOADER 完成,以下是 BOOTLOADER 的升级流程:

  • 判断升级请求文件是否存在,如果不存在,则启动 MS-RTOS
  • 从升级请求文件读出升级动作文件的路径
  • 判断升级动作文件是否存在,如果不存在,则启动 MS-RTOS,如果存在,则加载升级动作文件到内存
  • 分析所有升级动作,如果有升级 OS 的动作(idMS_FLASHFS_ACTION_UPDATE_OS),则升级 MS-RTOS 镜像
  • 启动 MS-RTOS

BSP 要求

APP 镜像、启动参数文件的升级由 MS-RTOS 完成。MS-RTOS 重启后,在 BSP 中,一般由启动线程 boot_thread 来调用 ms_apps_update 函数。

ms_err_t ms_apps_update(const char *update_req_path, const char *log_path);
static void boot_thread(ms_ptr_t arg)
{
    // do something

    ms_launcher_init(rsa_pub_key, rsa_pub_key_len);

    ms_apps_update("/nor/update/firmware/update_req", "/nor/update/firmware/update_log");

    // do something
}

ms_apps_update 函数按顺序执行升级动作文件中的每个动作,执行的出错时会将错误码写到升级动作文件,并将升级日志记录到指定的日志文件中。

差分升级

MS-RTOS 提供了差分升级的支持,可有效节约升级通信时间和流量,实现快速升级。

相关 API

// 使用旧的文件和差分包生成新的文件
int ms_patch(const char *old_file, const char *new_file, const char *patch_file);

如果要使用差分函数 ms_patch,应用程序需要链接 libmspatch.a 静态库,即 xxx.mkLOCAL_DEPEND_LIB 需要添加 -lmspatch。BSP 需要链接 libmskpatch.a 静态库,即 bspxxx.mkLOCAL_DEPEND_LIB 需要添加 -lmskpatch

生成差分包

差分包生成工具比较旧文件和新文件的差异性,生成较小的补丁文件:

msrtos-diff oldfile newfile patchfile
文档内容是否对您有所帮助?
有帮助
没帮助