Files
banban/docs/OTA_READY_FACTORY_BASELINE.md
T

232 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Banban OTA-ready 工厂基线
## 1. 目标和边界
本基线用于尚未量产的 `EG800AKCN_11LG` 设备。目标是在不改变现有对话、音频、
MQTT、NFC、GNSS、按键、休眠和 LED 业务流程的前提下,一次性固定后续本地暂存式
OTA 所依赖的底层条件。
本基线完成:
- 将 `customer_fs` 从 256 KiB 扩大到 640 KiB;
- 保持 `customer_app` 为 460 KiB;
- 将 APP 物理/XIP 地址固定为 `0x002C2000` / `0x802C2000`;
- 保留 SDK 已有的 `QUEC_APP_FULL_FOTA` 与 FULLOTA2 公共 API;
- 为设备和构建产物加入唯一布局身份;
- 在构建前后执行 fail-closed 校验。
本基线暂不完成:
- 不把当前 `ql_fullfota_app_start()` 在线升级流程切换成 FULLOTA2;
- 不增加签名 manifest、SHA-256 下载校验、断点续传或后台灰度;
- 不提供 A/B APP 分区,也不承诺自动版本回滚;
- 不在线更新 kernel、分区表或 `customer_fs`。
这样安排是为了先冻结量产后难以改变的 Flash 布局,同时避免在生产前仓促替换业务 OTA
状态机。后续 FULLOTA2 逻辑只需通过 `customer_app` 版本迭代即可加入。
> 生产门禁:从本工厂基线开始量产,到 FULLOTA2 业务 APP 完成真机验收并正式发布之前,
> 后端必须暂停向生产设备下发 OTA 命令。当前 `ql_fullfota_app_start()` 入口仍是原有
> FULLOTA1 流程,新的分区基线不会自动消除其覆盖下载风险。
## 2. 固定身份与 Flash 布局
设备布局身份:
```text
eg800akcn_11lg-fs640-app2c2000
```
构建 profile:
```text
ota_ready_fs640
```
4 MiB 内部 Flash 的尾部分区固定如下:
| 分区 | 起始地址 | 结束地址 | 大小 |
| --- | ---: | ---: | ---: |
| reserved | `0x00287000` | `0x002C2000` | 236 KiB |
| customer_app | `0x002C2000` | `0x00335000` | 460 KiB |
| customer_fs | `0x00335000` | `0x003D5000` | 640 KiB |
| nvm | `0x003D5000` | `0x003F5000` | 128 KiB |
| erase_rd | `0x003F5000` | `0x003F7000` | 8 KiB |
| fota_param | `0x003F7000` | `0x003FA000` | 12 KiB |
| factory_a | `0x003FA000` | `0x00400000` | 24 KiB |
`customer_app` 是单槽。FULLOTA2 能保护下载阶段:文件未下载完整、哈希错误或 FBF 校验
失败时不会设置升级标志;但 updater 开始擦写 `customer_app` 后,没有旧 APP 槽可供回滚。
## 3. 本次修改
### 3.1 分区和链接地址
- `CRANELRH_QUEC_FLASH_LAYOUT_SS_04M_OPEN.json`:`customer_fs = 640KiB`;
- `app_linkscript.ld`:ROM 起始地址改为 `0x802C2000`,最大 ROM 大小收紧为 `0x73000`;
- `customer_fs.bin`:从原 256 KiB LittleFS 中提取全部 14 个音频文件,以 4096 字节块、
160 个块重新生成 640 KiB LittleFS;
- 新文件系统镜像 SHA-256:
`19bd849dbcc6816f6dfffd1e585645a3474a2265f96a926b5dd073f0affb69f9`。
### 3.2 运行身份
`ota_baseline.h` 固定布局身份、APP/FS 地址和分区大小。应用启动时打印:
```text
[OTA-BASELINE] layout=eg800akcn_11lg-fs640-app2c2000 ... slot=single
[OTA-BASELINE] U: total=... free=... fota2_reserve=65536
```
该日志用于产线和联调确认设备没有混入旧的 fs256 基线,不改变任何业务状态。
### 3.3 构建保护
`build_rel.bat` 在构建前运行源码校验,在生成 APP 后运行容量校验。任何一项不满足都会中止:
- `customer_fs` 必须为 640 KiB;
- APP 地址必须为 `0x002C2000`;
- LittleFS 必须为 4096 字节块、160 块且镜像哈希一致;
- kernel 必须继续定义 `QUEC_APP_FULL_FOTA`;
- FULLOTA2 所需的 SDK API 必须存在;
- `app.bin + 8192` 不得超过 460 KiB。
可独立执行:
```powershell
ql-cross-tool\win32\owtoolchain\Python\python.exe tools\verify_ota_ready_baseline.py
ql-cross-tool\win32\owtoolchain\Python\python.exe tools\verify_ota_ready_baseline.py `
--app-bin ql-application\threadx\build\app.bin
```
## 4. 构建和生产烧录
在 Windows SDK 构建环境中执行:
```bat
build_rel.bat <生产版本号>
```
量产必须烧录该构建产生的完整 `*-fac.zip`,不能只烧 `customer_app`。完整工厂包需要同时
携带新 `partition.bin`、新 `customer_fs.bin`、11LG kernel/system 和新地址 APP。
量产前冻结并记录:
- 源码 Git commit;
- 工厂 ZIP 文件名、字节数和 SHA-256;
- `customer_fs.bin` SHA-256;
- `customer_app.bin` 字节数和 SHA-256;
- `partition.bin` 字节数和 SHA-256;
- 编译器、Aboot/arelease 和 FBFMake 版本;
- 首台、末台抽检设备串口中的 OTA baseline 日志。
不要把 `EG800AKCN_91LC` 的 `cp.bin`、工厂包或射频/GNSS 制品复制给本项目。两个项目同为
ASR1605/CRANELRH,但量产包必须由 `EG800AKCN_11LG` 配置生成。
## 5. 生产前测试
### 5.1 静态和产物测试
1. 运行 `verify_ota_ready_baseline.py`,结果必须通过。
2. 解包工厂 ZIP,确认其中 `customer_fs.bin` 为 655360 字节且哈希一致。
3. 使用 Aboot 工具检查 `partition.bin`,确认 APP/FS 地址与本文件一致。
4. 确认 `customer_app.bin + 8192 <= 471040`。
5. 确认 FBF 的目标物理地址是 `0x002C2000`,不能是旧地址 `0x00322000`。
### 5.2 全擦工厂烧录测试
至少准备 3 台板执行完整擦除和工厂烧录:
1. 下载器无越界、校验或 partition 错误。
2. USB 重新枚举,`AT`/`ATI` 正常。
3. 串口打印正确 layout、地址和 640 KiB 文件系统容量。
4. 14 个预置音频均可读取和播放。
5. IMEI、SIM、驻网、数据连接和 GNSS 正常。
6. MQTT 注册、命令收发、心跳和状态上报正常。
7. 唤醒、对话、打断、录音、播放、音量和休眠正常。
8. NFC、按键、LED、电池检测和低电关机正常。
9. 连续冷启动、软重启和断电启动各不少于 20 次。
10. 连续运行至少 8 小时,观察 watchdog、内存、文件系统和网络重连。
### 5.3 文件系统压力测试
1. 启动后记录 `ql_fs_size('U')` 和 `ql_fs_free_size('U')`。
2. 写入一个与计划 FBF 等大的测试文件,关闭、重启并逐字节回读。
3. 删除测试文件,确认空间恢复。
4. 在写入 10%、50%、90% 时分别断电,重启后确认业务 APP 仍可运行并可清理残留文件。
5. 验证正常业务文件占用后,仍满足 `FBF size + 64 KiB` 空闲门槛。
### 5.4 最小 FULLOTA2 冒烟测试
正式量产前至少做一次 A 到 B 的本地暂存升级。B 可以只修改版本号:
1. 将 B 版 `customer_app.fbf` 顺序写入 `U:/FotaFile.bin`;
2. 调用 `ql_fota_fixed_internal_flash_upgrade(1)`;
3. 调用 `ql_fota_set_package_path()`、`ql_fota_init()`、`ql_fota_image_write()`、
`ql_fota_image_flush()` 和 `ql_fota_image_verify()`;
4. 重启,确认 updater 安装 B,且 `U:/FotaFile.bin` 被正确处理;
5. 确认 NVM、设备身份、业务配置和预置音频未损坏;
6. 下载损坏、截断和旧地址 FBF,确认均不能设置有效升级标志。
## 6. 后续 FULLOTA2 业务实现
后续 APP 版本建议按以下顺序加入,不再改变本基线分区:
1. 下载所有权收敛到单一 OTA task,其他任务只投递数据或事件。
2. 下载前停止对话、录音、播放和非必要 Flash 写入,保持 watchdog 正常喂狗。
3. 删除确认不再使用的旧暂存文件。
4. 检查 `free >= manifest.size + 65536`。
5. 从偏移 0 顺序写入 `U:/FotaFile.bin`;首版不要宣称支持断点续传。
6. 同时计算 SHA-256,并在下载完成后重新打开本地文件复核大小和 SHA-256。
7. 在设置升级标志前持久化 `PENDING_REBOOT` 状态。
8. 只有 `ql_fota_image_verify()` 成功后才重启。
9. 新 APP 启动后核对版本、release sequence 和 layout,再上报健康状态。
10. 失败时 deinit、删除残留文件、恢复业务,并上报明确错误码。
建议使用两个带 CRC 和递增 generation 的状态文件,例如 `U:/ota_state.a`、
`U:/ota_state.b`。这能抵抗状态文件写入中断,但不构成固件 A/B 回滚。
## 7. 后端联调契约
现有 OTA 命令仅有 URL 和版本不足以可靠激活 FULLOTA2。建议后端增加:
```json
{
"product": "EG800AKCN_11LG",
"layout_id": "eg800akcn_11lg-fs640-app2c2000",
"version": "1.9.0",
"release_seq": 10900,
"min_release_seq": 10800,
"url": "https://ota.example/releases/1.9.0/customer_app.fbf",
"size": 212992,
"sha256": "64-lowercase-hex",
"signature": "optional-first-stage"
}
```
设备校验顺序:产品、layout、版本序号、URL host、大小、SHA-256,最后才允许设置升级标志。
设备状态建议至少包含:
- `ACCEPTED`:命令和布局校验通过;
- `DOWNLOADING`:带下载字节数或百分比;
- `VERIFIED`:本地文件 SHA-256 和 FBF 校验通过;
- `REBOOTING`:升级标志已设置;
- `UPDATED`:目标 APP 已启动并通过健康检查;
- `FAILED`:带稳定错误码和失败阶段。
联调测试矩阵必须覆盖:同版本、降级、错误 layout、大小不符、SHA 不符、404、超时、下载
中断、下载阶段断电、verify 前断电、重启后无法确认,以及后台重复下发同一命令。
如果暂时没有动态 OTA 后端,也可以用“不可变 FBF 对象 + 签名 current.json”实现;但灰度、
设备级进度和失败统计需要后台服务。
## 8. 发布和回退策略
- 新生产设备只允许使用 fs640 工厂包和 `0x002C2000` APP/FBF。
- 禁止向 fs640 设备发布旧地址 `0x00322000` 的 FBF。
- 如生产前验证失败,可回退源码分支和工厂包重新全擦烧录;不得混烧新旧布局制品。
- 量产后若只是业务问题,可通过 APP OTA 修复;若分区或 kernel 基线有问题,需要返厂或有线
完整烧录,不能假定业务 APP OTA 能安全修改分区表。
- 当前为单槽。发布新版本必须先小批量灰度,并保持可用的有线恢复工厂包。