固件 C2:OTA 双槽 + 失败回滚(已上板实测正常 / 哈希错 / 回滚三条路径)
- 分区重排(16 MB,nvs 0x9000 不动):ota_0 / ota_1 各 3 MB、otadata 0x610000、evlog 挪到 0x612000;
flash 大小改正为 16 MB;开 CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
- ota.{h,c}(宿主机可测):URL / sha256 校验、判定(下载中 busy、待验证拒、同镜像不重下)、健康判据
- ota_esp.{h,c}:t_ota 任务经 HTTP 下载、边下边算 sha256、核 project_name 后切启动分区;
新固件 120 s 内连不上 broker 就回滚(t_link 判 + esp_timer 兜底);重启前等回应发出、事件落盘
- 新命令 ota = 13(两条链路都收,reboot 默认 false:复位 = 五台手机断电一次);status 加 ota 一块;
新事件 LOG_EV_OTA = 18;PROJECT_VER 取 PHONERAIL_FW_VERSION
- test_ota.c 13 例,全工程 442 例全绿;版本 0.1.0-c2
- 服务器:nginx 7765 只放行 /fw/<16 hex>.bin(不过门户,路由器转发已加);tools/ota_push.py 推送;
rack protocol.py 加事件 18 / 命令 13(已部署)
- 板 B:推送到自证健康 19 s;错哈希不切分区;删掉 broker 账号后 120 s 回滚,bad 报出被回滚的版本
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -848,6 +848,28 @@ base = `phonerail/<id>`,id = 板子 STA MAC 的 12 位小写十六进制(板
|
||||
- 失联不动作:WiFi 断按 1/2/4…60 s 退避重连,MQTT 由 esp-mqtt 每 10 s 重连;没有任何分支会碰输出。
|
||||
- 实测(板 B,2026-09-27):经 WiFi `CANBOX-5G` → 公网 → 8883 TLS 连上;判重 / `link` / `empty` / `parse` 回应与遥测(1 条/s)全部符合。
|
||||
|
||||
#### C2 定稿的 OTA(2026-09-27,`firmware/main/ota.h` / `ota_esp.c`)
|
||||
|
||||
用户定的三条:**明文 HTTP 下载 + 命令带 sha256**(哈希走 MQTT/TLS,下载被改了只会哈希不对)、**不签名**(不烧 eFuse)、
|
||||
**新固件 120 s 内连上 broker 才算健康,否则回滚**。
|
||||
|
||||
- 命令(两条链路都收,会动东西 ⇒ 必须带 seq、进判重窗口):
|
||||
`{"seq":N,"cmd":"ota","url":"http://home.example:7765/fw/<sha256 前 16 位>.bin","sha256":"<64 位小写>","size":N,"reboot":false}`
|
||||
回 `{"seq":N,"ok":true,"act":"start"|"reboot"|"ready"}`;下载中再来 `busy`;新固件还没自证时 `state`;size 超一个槽(3 MB)`range`。
|
||||
url 只收 `http://`、≤64 字节(命令字符串上限)。
|
||||
- ⚠️ **`reboot` 默认 false**:ESP 一复位 EN 就被下拉,**五台手机硬断电一次**,起来后按意图逐路恢复。
|
||||
默认只下载 + 校验 + 切启动分区、下次复位生效;同一个镜像已就绪时再发带 `"reboot":true` 的,不重下、直接重启。回滚也是一次复位。
|
||||
- status 多一块 `"ota":{"st":"idle|dl|ready","got":N,"size":N,"err":null|"http|size|hash|flash|image|boot|noslot","pend":bool,"bad":null|"版本号"}`;
|
||||
`pend` = 正在跑的固件还没自证,`bad` = 被判无效回滚掉的那份的版本号(镜像头版本 = `PHONERAIL_FW_VERSION`)。
|
||||
- 新事件 **`LOG_EV_OTA`(18)**,arg:1 开始 / 2 就绪 / 3 失败(bus_mv = 原因号)/ 4 自证健康 / 5 回滚 / 6 为换固件重启。新命令号 **`ota` = 13**。
|
||||
- 健康判据:启动走完 + 配了 broker 就要 MQTT 连上(只配 WiFi 则 WiFi 通、都没配只看启动);在 `t_link` 里判,另有 esp_timer 在 150 s 兜底
|
||||
(app_main 卡死也能回滚);自证前崩溃 / 看门狗由 bootloader 回滚(`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE`)。
|
||||
- 分区(16 MB):nvs 0x9000(没动)/ phy_init / **ota_0 0x10000、ota_1 0x310000 各 3 MB** / otadata 0x610000 / evlog 0x612000。
|
||||
- 服务器:nginx 7765(`rack/deploy/nginx-phonerail-fw.conf`)只放行 `/fw/<16 位十六进制>.bin`,**不过门户**(板子过不了门禁;
|
||||
完整性靠哈希、镜像里无机密);路由器 7765 转发 2026-09-27 已加。推送工具 `firmware/tools/ota_push.py <id> [--reboot]`。
|
||||
- 实测(板 B,2026-09-27):1 MB 下载 ≈8 s,推送到自证健康 19 s;错哈希 ⇒ `err:hash`、不切分区;删掉板子 broker 账号后推送 ⇒
|
||||
120.1 s 回滚到旧版、`bad` 报出被回滚的版本;下载期间巡检 `skipped` 0。
|
||||
|
||||
### 10.9 启动顺序
|
||||
|
||||
```
|
||||
@@ -920,7 +942,7 @@ FR-12 是「中(可选)」,建议**首版先不做**,把接口留出来
|
||||
| 项 | 状态 |
|
||||
|---|---|
|
||||
| ~~上位机链路选型(10.8)~~ | ✅ **2026-09-06 用户拍板:方案 C**,WiFi 常态 + USB CDC 兜底 |
|
||||
| **OTA 升级** | 既然定了 WiFi,**建议做**:双分区 + 失败回滚。没有 OTA 的话一次坏固件要把板子从机架上拆下来插 USB,而 USB 兜底链路本身也能烧 —— 所以这是「省事」不是「救命」,可以排在首版之后 |
|
||||
| ~~OTA 升级~~ | ✅ **2026-09-27 C2 完成**:双槽 + 失败回滚,定稿见 §10.8「C2 定稿的 OTA」 |
|
||||
| WiFi 掉线重连策略 | 指数退避 + 上限;**重连过程不得阻塞 `t_safety`**(10.3),链路任务优先级最低就是为这个 |
|
||||
| **MQTT broker 与 topic** | 2026-09-27 起由本项目自定(D7,broker 在 home 服务器);topic 约定随 A14 写进 §10.8 |
|
||||
| 时间同步 | 当前方案是上位机下发墙钟做偏移,不加 RTC。若日志要脱机长期归档需重议 |
|
||||
|
||||
在新工单中引用
屏蔽一个用户