10.2.2. 设计说明
10.2.2.1. A/B 系统方案分区信息
备注
ENV 分区,用来保存 env 环境变量,增加了一个备用 ENV 分区,确保在一份数据破坏后,另外一份数据还能继续使用
OS,RODATA分区各有一个备份分区,它们一起称为 A/B 系统
10.2.2.2. A/B 系统升级过程
备注
升级前,A系统为启动系统,B系统为备用系统;
启动 OTA升级,给B系统升级程序;
升级完成后重启,从B系统启动,A系统为备用系统。
10.2.2.3. 环境变量指导 A/B 系统升级和启动
10.2.2.3.1. OTA升级相关环境变量
osAB_next=A
osAB_now=A
upgrade_available=0
bootlimit=5
bootcount=0
10.2.2.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.2.2.3.3. 环境变量在OTA升级过程中的作用
10.2.2.4. OTA 升级包制作过程
10.2.2.4.1. OTA升级包配置文件:ota-subimgs.cfg
相关文件路径如下(以M4为例):
target/m4/ZXM47D0N/pack/ota-subimgs.cfg
查看配置信息:
/* 需要升级的分区,根据需求添加,如果添加也需在image_cfg.json配置对应的 *_r 分区 */
> cat ota-subimgs.cfg
m4_os.itb
rodata.fatfs
data.fatfs
10.2.2.4.2. OTA升级包生成工具: mkcpio.py
tools/scripts/mkcpio.py
执行编译命令,会自动执行 mkcpio.py 命令生成 ota.cpio。mkcpio.py 具体调用了cpio, cpio.exe命令进行打包。
10.2.2.4.3. OTA包数据组成格式
10.2.2.5. SPINAND OTA 流程
10.2.2.5.1. SPINAND 平台 OS 阶段 app OTA 执行流程
zx_uart_ota uartx
|-> uart_rx_demo(argv[1]);
|-> uart_rx_demo_thread(uart 数据接收线程)
|-> aic_upgrade_start(); //packages/third-party/ota_downloader/absystem.c 升级前读取环境变量信息,获取将要升级的系统
|-> rt_device_read(serial, -1, uartrx, 1); //通过串口接收升级包数据,并根据串口协议存储数据到 uart_rx_buf
|-> _ota_update(uint8_t *framebuf, size_t len); //根据串口协议解析串口数据
|-> ota_shard_download_handle(char *buffer, int length); //采用分片方式写入数据
|-> ota_buf_push(&shdr, buffer, length); //将接收到的数据放到缓存区,供解析cpio头部信息
|-> find_cpio_data(&fhdr, shdr.buf, shdr.buflen); //解析cpio头部信息
|-> head_buf_pop(&bhdr, &shdr, &fhdr); //将cpio头部信息后面的数据放到另外的缓存区,供升级使用
|-> ota_buf_push(&bhdr, buffer, length); //将下载的数据放到缓存区,供升级使用
|-> aic_ota_find_part(partname); //获取分区信息
|-> aic_ota_erase_part(); //擦除分区
|-> download_buf_pop(&bhdr, &fhdr) //将缓存区里面的数据取出来,升级到flash上
|-> aic_ota_part_write //写入数据到flash上
|-> cpio_file_checksum((unsigned char *)bhdr->buf, burn_len); //升级完成以后,校验和信息
|-> aic_upgrade_end(); //升级结束,更新环境变量信息
|-> cmd_reboot(0, NULL); //重启
10.2.2.5.2. SPINAND 平台 boot 阶段新系统程序加载启动流程
do_nand_boot //application/baremetal/bootloader/cmd/nand_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 分区程序到缓存上