feat(ppclock): SUOTA 固件升级(ota.py + CLI ota 子命令 + 预检),APK互证报告入库,123 测试全绿

This commit is contained in:
agent committed 2026-07-24 11:26:14 +00:00
1 parent 7079053dde
commit 3b92c382fc
7 files changed
+443

No files matched your search

+22
View File
@@ -162,6 +162,10 @@ def build_parser() -> argparse.ArgumentParser:
sp.add_argument("--channel", default="rxtx", choices=["rxtx", "epd"])
sp.add_argument("--no-response", action="store_true")
sp = sub.add_parser("ota", help="SUOTA 固件升级(高危,需确认)")
sp.add_argument("file", help="固件 .img(pQ 头格式)")
sp.add_argument("--yes", action="store_true", help="确认执行(否则仅预检)")
sp = sub.add_parser("batch", help="JSONL 批量执行(单次连接,agent 编排)")
sp.add_argument("file", help="JSONL 文件,每行 {\"argv\": [...]};'-' 读 stdin")
sp.add_argument("--stop-on-error", action="store_true")
@@ -235,6 +239,24 @@ async def _run_command(args, t):
else:
await t.write_rxtx(data, response=not args.no_response)
return {"sent": len(data)}
if c == "ota":
import zlib
from pathlib import Path
image = Path(args.file).read_bytes()
# 独立预检(pQ 头 + CRC32(body)),与 tools/fw.py 同规则
if len(image) < 64 or image[0:2] != b"pQ":
raise ValueError("固件格式错误(缺 pQ 头)")
body_size = int.from_bytes(image[4:8], "little")
crc_ok = (zlib.crc32(image[64:64 + body_size]) & 0xFFFFFFFF
== int.from_bytes(image[8:12], "little"))
if not crc_ok:
raise ValueError("固件 CRC 校验失败,拒绝烧录")
if not args.yes:
return {"precheck": "ok", "body_size": body_size,
"hint": "加 --yes 执行烧录"}
progress_log = []
result = await t.run_ota(image, on_progress=progress_log.append)
return {"ota": "done", **result, "blocks_ok": len(progress_log)}
raise ValueError(f"未知命令 {c}")