10.4.5. 设计说明

10.4.5.1. A/B 系统方案分区信息

../../../_images/part.png

注解

  1. ENV 分区,用来保存 env 环境变量,增加了一个备用 ENV 分区,确保在一份数据破坏后,另外一份数据还能继续使用

  2. OS,RODATA分区各有一个备份分区,它们一起称为 A/B 系统

10.4.5.2. A/B 系统升级过程

../../../_images/ab.png

注解

  1. 升级前,A系统为启动系统,B系统为备用系统;

  2. 启动 OTA升级,给B系统升级程序;

  3. 升级完成后重启,从B系统启动,A系统为备用系统。

10.4.5.3. 环境变量指导 A/B 系统升级和启动

10.4.5.3.1. OTA升级相关环境变量

osAB_next=A
osAB_now=A
upgrade_available=0
bootlimit=5
bootcount=0

10.4.5.3.2. 环境变量使用说明

环境变量名称

定义

注释说明

osAB_now

启动分区

osAB_now 为“A”表示 OS 本次从 OS_A 启动, 为“B”表示本次从 OS_B 分区启动

osAB_next

升级分区

osAB_next 为“A”表示更新 A 系统数据, 为“B”表示更新 B 系统数据

upgrade_available

OTA升级完成

OTA升级完成,指导 boot 程序更新启动分区和版本回退

bootcount

失败启动次数

启动分区启动os程序失败的次数

bootlimit

失败启动次数限制

启动分区启动失败次数超过bootlimit会触发版本回退

10.4.5.3.3. 环境变量在OTA升级过程中的作用

../../../_images/env.png

10.4.5.4. OTA 升级包制作过程

10.4.5.4.1. OTA升级包配置文件:ota-subimgs.cfg

相关文件路径如下:

target/d13x/per1-nor/pack/ota-subimgs.cfg

查看配置信息:

> cat ota-subimgs.cfg
os.aic
data.fatfs

10.4.5.4.2. OTA升级包生成工具: mkcpio.py

相关文件路径如下:

tools/scripts/mkcpio.py

执行编译命令,会自动执行 mkcpio.py 命令生成 ota.cpio。mkcpio.py 具体调用了cpio, cpio.exe命令进行打包。

10.4.5.4.3. OTA包数据组成格式

../../../_images/cpio.png

10.4.5.5. SPINOR OTA 流程

10.4.5.5.1. SPINOR 平台 OS 阶段 app OTA 执行流程

http_ota  //packages/third-party/ota_downloader/src/http_ota.c
|-> http_ota_fw_download(argv[1]);
    |-> aic_upgrade_start(); //packages/third-party/ota_downloader/absystem.c 升级前读取环境变量信息,获取将要升级的系统
    |-> webclient_session_create(GET_HEADER_BUFSZ);
    |-> webclient_shard_head_function(session, uri, &file_size);
    |-> webclient_register_shard_position_function(session, http_ota_shard_download_swu_handle);
    |-> webclient_shard_position_function(session, uri, file_offset, file_size, HTTP_OTA_BUFF_LEN);
        |-> http_ota_shard_download_swu_handle      //采用分片方式下载数据
        |-> ota_buf_push(&shdr, buffer, length);    //将下载的数据放到缓存区,供解析cpio头部信息
        |-> find_cpio_data(&fhdr, shdr.buf, shdr.buflen);   //解析cpio头部信息
        |-> swu_buf_pop(&bhdr, &shdr, &fhdr);               //将cpio头部信息后面的数据放到另外的缓存区,供升级使用
        |-> ota_buf_push(&bhdr, buffer, length);            //将下载的数据放到缓存区,供升级使用
        |-> fal_partition_find(partname[flag_cpio])         //获取分区信息
        |-> fal_partition_erase(dl_part, 0, dl_part->len)   //擦除分区
        |-> download_buf_pop(&bhdr, &fhdr)                  //将缓存区里面的数据取出来,升级到flash上
            |-> fal_partition_write                         //写入数据到flash上
            |-> cpio_file_checksum((unsigned char *)bhdr->buf, burn_len);       //升级完成以后,校验和信息
    |-> aic_upgrade_end(); //升级结束,更新环境变量信息

10.4.5.5.2. SPINOR 平台 boot 阶段新系统程序加载启动流程

do_nor_boot //application/baremetal/bootloader/cmd/nor_boot.c
|-> aic_ota_check();  //application/baremetal/bootloader/lib/absystem/absystem.c
    |-> aic_ota_version_fallback(); // OTA 升级失败,版本回退到之前的版本
|-> aic_get_os_to_startup(target); //获取新系统信息
|-> mtd_get_device(target); // 获取新系统 os 分区结构体
|-> spl_load_simple_fit(&info, &entry_point); // 加载 os 分区程序到缓存上

10.4.5.5.3. SPINOR 平台 OS 阶段判断 OTA 升级完成的流程

main //application/os/helloworld/main.c
|-> aic_ota_status_update // packages/third-party/ota_downloader/absystem.c 判断 OTA 升级成功
|-> aic_get_rodata_to_mount(target); // 获取新系统 rodata 分区
|-> dfs_mount(target, "/rodata", "elm", 0, 0) // 挂载新系统 rodata 分区