UI 内容页框架加实时页自动刷新机制(交流量页启用,300ms)

- ui_content_page:描述符尾部追加 auto_ms/auto_seq 可选字段(缺省=0/NULL=
  旧行为逐位不变);页打开期间框架持一只 lv_timer,仅当发布序号变过才整页
  失效(零空转失效),关页即销;新 API ui_content_page_auto_poll
- ui_page_ac.c:.auto_ms=300(≥200ms 发布节拍、避 400=2×200 锁相、300=
  15×20ms LVGL 整刷周期;最坏屏上滞后 500ms;完整取值账目在代码注释)
- simulator:rt 帧装配收口 sim_fill_rt_frame(n=0 冻结帧保 74 张黄金逐字节
  一致,n≥1 确定性斜坡);新增 --rtlive 两态自检 + 窗口模式 200ms 节拍发布;
  check_content_pages.py 增 [rtlive] 零按键 A≠B 落屏断言
- docs/UI设计:供给说明新增 §5.5 自动刷新口径;内容页架构 §3.1/§四/§九 同步
  (并修正 s_open 判定旧描述)
- 台账:Keil 构建后按固定顺序回填(Code=256,588 / RW_IRAM1 +8B / UI +8B)

验证:模拟器 0错0警;菜单 8 状态 + 内容页 74 张 + rtlive(A≠B 30 字节)PASS
(lead 独立复跑 RC=0);Keil 0错0警;mem-budget --gate / mem-numbers --scan 绿。
This commit is contained in:
2026-11-13 14:23:06 +08:00
parent 5bab248dee
commit a5142c6d9d
11 changed files with 384 additions and 105 deletions
+28 -1
View File
@@ -17,6 +17,10 @@ check_content_pages.py — 叶子内容页像素黄金参考回归 + 文本级
另做开页-关页往返池水位门禁:`es`(info)与 `ddeeesll`(密码页,ESC 后 ←← 弹出路上压的
2 个菜单框回根框,完全还原初始态)后 used 须等于 POOL_AFTER_ROUNDTRIP。
另跑 --rtlive 两态比对,实证「不按任何键,新数据照样刷屏」(task-2 框架自动失效链:
开页拍 A → 仿真发布一帧斜坡帧并直调 ui_content_page_auto_poll → 拍 B,A≠B 才 PASS;
黄金参考本身仍建立在冻结帧上,与本检查互不影响)。
黄金参考更新流程(有意改视觉时):先肉眼看图确认新效果正确,再 --update 刷新,
刷新即改基准 → `git diff --stat simulator/tests/ref` 必须逐页过目并在提交正文说明;
最后 regen_ref_png.py 重生成目检 PNG;误报排查见 docs/UI设计/UI_自动化测试流程.md。
@@ -1220,13 +1224,36 @@ def main():
else:
print("[rt:%s] PASS 开页-关页往返池水位 %d B" % (rt_name, used))
# --rtlive 两态比对(task-2):开交流量页拍 A,发布 live 斜坡帧 + 框架判定体再拍 B。
# A≠B = 「数据在变、页面没被按键过,屏上内容照样更新」成立;黄金参考不受影响。
rtA = os.path.join(tmp, "rtlive_a.bin")
rtB = os.path.join(tmp, "rtlive_b.bin")
proc = subprocess.run([str(EXE), "--rtlive", "dee", rtA, rtB],
cwd=tmp, capture_output=True, text=True)
if proc.returncode != 0:
ok = False
print("[rtlive] FAIL 退出码 %d stderr=%s" % (proc.returncode, proc.stderr.strip()))
elif "rtlive: frames written" not in proc.stdout:
ok = False
print("[rtlive] FAIL 输出缺标记行:\n%s" % proc.stdout)
else:
a = Path(rtA).read_bytes()
b = Path(rtB).read_bytes()
if len(a) != len(b) or a == b:
ok = False
print("[rtlive] FAIL A/B 异常(lenA=%d lenB=%d equal=%s)——自动失效链断了或斜坡帧没动显示值"
% (len(a), len(b), a == b))
else:
diff = sum(1 for x, y in zip(a, b) if x != y)
print("[rtlive] PASS 未按键实时数据落屏(A≠B,字节差异 %d)" % diff)
if update:
print("PASS: 黄金参考已刷新(%d 页)" % len(PAGES))
shutil.rmtree(tmp, ignore_errors=True)
return 0
if ok:
print("PASS: %d 内容页 + 往返池水位全部通过" % len(PAGES))
print("PASS: %d 内容页 + 往返池水位 + rtlive 全部通过" % len(PAGES))
shutil.rmtree(tmp, ignore_errors=True)
return 0
# 失败时保留临时截图便于排查