52e28885cb
三个薄页面模块 ui_page_clock / ui_page_reset / ui_page_clear,页面注册由生成器 自动写双端(裁定 A-1:「三叶各绑一页」与「零新增 .c」不可兼得,选薄页面加生成器, 不写手写 node switch——那种分发在增删叶子时会静默换功能,且没有任何门禁照得到)。 数据侧是注入式函数表:UI 不 include App 层的头。两条硬理由都实测过——分层方向 (layer-deps)之外,模拟器根本不链 sys_clock,ALLOW 豁免挡得住 layer-deps, 挡不住模拟器链接期。面板对时的唯一真判据是回读 RTC:sys_clock_set() 恒返 0 (RTC 写失败只打日志),所以真机侧写 1 后回读 1,最坏约 200 ms 落在一次「保存」 按键上,IWDG 800 ms 窗有余;上界与依据都写进注释。 「无时钟」徽标位置有两个像素级实测坑:放标题带右侧会被 4 字标题连成「时钟设置 无时钟」一句话;放页脚带左侧 x=7 会压住页脚——页脚从 x=6 起排,不是居中。 最终落在清单末行与页脚之间的空带 y=124。clear_done 那张顺带给出像素证据: 清 run.log 之后「操作记录」那一行从 2 变 3,页面上没缓存、没撒谎。 ui_w_records 的 UI_W_REC_LOG_* 顺序必须等于 syslog_id_t 顺序(7 类,只准尾追加), 已加编译期顺序守卫;执行侧 7 条映射表同样带编译期守卫。 测试与真值:内容页黄金 27 → 40 页(+13),文本断言 +68、反向断言 ABSENT +19; 27 张旧参考 git diff 为空 = 逐字节未变。往返池 5448 B 与菜单常驻堆 5368 B 均未变; 字库未扩(源码在用 171 并 KEEP_EXTRA 39 = 清单 183),font-charset 与 cn-chars、 cn-font 字节一致。@build 0 错误 0 警告;uiTask 静态最坏链 1,336 B / 16,384 (余 91%)与基线相同,页面钩子没进最坏链。 一条测试学结论单独留痕:反向断言不能当「位置不重叠」的证据——本脚本的字形匹配 把 y 带判得比字面宽(徽标在 125..136、页脚在 144..155,仍被 (140,160) 判命中)。 该防线改由正向断言「页脚未被徽标压住」承担(压字那一版实测过不了它)。 两条自我更正一并记档(作者自报,按真值而非原口径): ① 先前报「文案零新增汉字」是错的——观测行拟用「动作元件」,「元」不在子集, cn-chars 与 font-charset 如实红;最终改「保护动作 N」才让「零新增」成为事实。 顺序是:先按机器红,再按真值写结论。 ② 先前报「6 个文件 BOM 逐个核过」被 bom-guard 证伪:丢 BOM 发生在上一次编译之后, 正是 AGENTS 那句「历史 0 警告不代表安全」的活例;此后一律以退出码为准。 未覆盖项不假装:台架「N>0 → N=0」在产品构建的未标定闭锁期拿不到(闭锁期 N 恒 0), 判据显式退化为「页面受理 + 落一条操作记录」,写在 rs_watch 注释里。 生成物入库例外照用:uvprojx 只加 3 个 ui_page_ 的 FilePath(真增删源文件), CMakeLists 同批;两处都由 gen_menu.py 自己写,没手写。 本笔先走了一次真钩子:20 条钩子实跑通过(ui-golden 菜单 8 状态加内容页 40 页、 generated-fresh、registration-check、font-charset、ui-data 单测、cppcheck、 coding-standard、bom、mojibake、id-check、doc-links 等),只有 mem-numbers 与 mem-budget 两条红——磁盘上的 .map 出自 20:39 那次构建、含三条在飞道的代码, 与 HEAD 台账必然不同码。按仓库既有约定(这两条等台账回填时允许 --no-verify 并 正文留证)落这一笔;回填由我统一在收尾一笔做。 三条在飞道(task-26 崩溃证据路径、task-16 与 task-17 谓词收敛和卷锁观测、 task-36 台架工具)的未暂存改动被 autostash 暂时收走,钩子看到的是 HEAD 加本笔; 过程中曾把 comm 道未跟踪的 iec104_comm.c 临时移出(它不在 stash 覆盖面内), 那次移出反而让 ui-golden 撞见 CMake 缓存里的悬空引用而红——已改用「先落 comm 那笔、再落本笔」的顺序消掉这个中间态。ui_data_maint_ready() 待删(只有测试在读 的自检口),排在本笔之后单独一笔。
MDK-ARM/ — Keil MDK-ARM v5 工程与构建/烧录/探针脚本
唯一工具链:Keil MDK-ARM v5(ARMCC,C99)。本目录含工程文件、启动文件、 命令行构建/烧录脚本,以及台架探针与判读脚本。
关键文件
| 文件/目录 | 作用 |
|---|---|
STM32F407-Demo.uvprojx |
Keil 工程文件(源文件清单、编译选项、目标配置) |
STM32F407-Demo.uvoptx |
Keil 用户选项(调试器、断点等) |
startup_stm32f407xx.s |
启动文件(Heap_Size EQU 0x200(512B)在此限定) |
.dsh/skills/stlink-flash/scripts/stlink_flash.py |
复位/烧录/回读(ST-LINK_CLI 封装,见下;原 reset.bat 已于 2026-10-10 删除) |
构建与烧录
# 编译(@build = keil-build skill;相对路径,勿用绝对路径)
& '.venv\Scripts\python.exe' .dsh\skills\keil-build\scripts\keil_build.py # 退出码 0 = 0 errors, 0 warnings
# 烧录 + 复位运行(@download = stlink-flash skill)
& '.venv\Scripts\python.exe' .dsh\skills\stlink-flash\scripts\stlink_flash.py flash <文件.hex|.bin>
# 仅复位
& '.venv\Scripts\python.exe' .dsh\skills\stlink-flash\scripts\stlink_flash.py reset
⚠️ 烧录铁律
stlink_flash.py flash=ST-LINK_CLI -c SWD -P <文件> -Rst -Run——-Rst -Run不可省略! 裸-P会报Programming Complete,但目标核处于异常状态时写入并不落地(芯片内容不变)- 烧录后必须回读校验:
ST-LINK_CLI -c SWD -CmpFile <文件> 0x08000000(No difference found才算真写入) - 本机 3 线接线(nRST 未接),只重启不烧录用
stlink_flash.py reset
台架探针与判读脚本
| 脚本 | 作用 |
|---|---|
bench_verdict.py |
台架判读(把运行结果判为 PASS/FAIL) |
ftp_freeze_probe.py |
FTP 上传+回读哈希(真实路径冻结探针)——被 Trap 记录当作可信判据引用,保留;2026-10-22 起用设备账号登录(设备无匿名通道) |
tcp_reconnect_probe.py |
TCP 快速复连探针(TRAP-NET-17) |
audit_runs.py / audit_tcpclient.py |
运行记录审计 / TCP 客户端审计 |
check_crecipe_content.py |
检查创建配方内容 |
子目录
| 目录 | 内容 |
|---|---|
RTE/ |
Keil Run-Time Environment 配置 |
DebugConfig/ |
调试会话配置 |
STM32F407-Demo/ |
构建输出(.o/.axf/.map 等,产物不提交) |
bench_diag/ |
2026-10-22 删除:4 个一次性台架诊断脚本,全库零引用、且自设备启用 FTP 鉴权起就登录不上(需要时从 git 历史取回) |
retracted_bench_20260922/ |
已撤回的台架数据(存证) |
⚠️ 注意
- 工具路径经
DTU_*环境变量解析(DTU_KEIL_UV4= UV4.exe 完整路径,DTU_STLINK_CLI= ST-LINK_CLI.exe 完整路径;换机设变量即可,无需改脚本;契约见docs/环境与部署/本地工具路径环境变量方案.md) - 本目录被 pre-commit 门禁排除
- 启动文件的
Heap_Size = 512B是自研代码禁用malloc的根因(见AGENTS.md)
相关文档
- 烧录/复位:
docs/测试说明/ST-LINK_CLI_复位使用说明.md - 构建与验证:根
AGENTS.md「构建与验证」章 - 测试流程:
docs/测试说明/自动化测试流程.md