merge: v2-on-ui into task/screenlink-bench-serial (wave + screenlink)
This commit is contained in:
+1
-1
@@ -44,7 +44,7 @@
|
||||
| `ci_local.py` | **本地跑与 CI 等价的门禁**(静态门禁 pre-commit 47 根 + **manual 段**(`cppcheck` / `test-cppcheck` / `test-coverage` 三根逐根 `--hook-stage manual`,默认跑)+ 提交信息门禁 + **体积门禁** + 主机侧纯逻辑单测):自动选用装了 pre-commit 的解释器;无 `.map` 时自适应跳过 `mem-numbers` / `mem-budget`(⚠ 那是 SKIP 不是通过,缺口由体积门禁兜住);退出码 0/1/2 与 CI 对齐。CI 定义见 `../.gitea/workflows/ci.yml`,覆盖边界见 `docs/测试说明/测试开发标准流程.md` §9 |
|
||||
| `check_size_gate.py` | **体积门禁的强制路径**:`.map` 只在本地有,钩子无它时自适应 SKIP,于是"没测=通过"。本脚本用**已提交的同码凭证** `scripts/size_attestation.json` 把这条判据变成无需 Keil 也能跑:`--stamp` 只在"`.map` 存在、比全部受管源码新、且未超 92%"时才盖章(已挂在 `ram_baseline.py --update` 里,无新增人工步骤);`--local` 供 ci_local 的体积门禁步;`--ci` 供 runner(同码性 + 按凭证数字复核红线,主干 push 拦红、其余事件 `--warn-only`);`--show` 排障。**口径与边界的唯一正文在本脚本模块 docstring** |
|
||||
| `size_attestation.json` | (被 `check_size_gate.py` 读写)体积同码凭证:受管源码指纹(`git ls-files` 范围内逐文件 sha256 聚合)+ 测量数字与占比 + `.map` 出处。改固件源码后不重测 → 指纹对不上 → 体积门禁与 CI 同时拦红 |
|
||||
| `check_test_coverage.py` | 主机单测**覆盖率**(2026-10-23):mscoverage 动态插桩跑 `test/host/**` 全部 41 套,统计自研生产源码行/函数覆盖(并集)+ 与 `test_coverage_baseline.json` 比回退;`--module/--update-baseline/--md/--json/--list`;挂在 `test-coverage` 钩子上(`stages: [manual]`,**`git commit` 不跑**),入口 = 远端 CI「手动阶段门禁」步 / `scripts/ci_local.py` 的 manual 段(`--coverage` 旗标保留只为兼容旧命令;口径见 `docs/测试说明/主机单测覆盖率口径.md`) |
|
||||
| `check_test_coverage.py` | 主机单测**覆盖率**(2026-10-23):mscoverage 动态插桩跑 `test/host/**` 全部 44 套,统计自研生产源码行/函数覆盖(并集)+ 与 `test_coverage_baseline.json` 比回退;`--module/--update-baseline/--md/--json/--list`;挂在 `test-coverage` 钩子上(`stages: [manual]`,**`git commit` 不跑**),入口 = 远端 CI「手动阶段门禁」步 / `scripts/ci_local.py` 的 manual 段(`--coverage` 旗标保留只为兼容旧命令;口径见 `docs/测试说明/主机单测覆盖率口径.md`) |
|
||||
| `ci_gitlint_range.ps1` | CI 侧**提交信息门禁**:逐条校验本次 push/PR 引入的提交(`--all-files` 跑不到 `commit-msg` stage,故必须单独守) |
|
||||
| `ci_find_python.ps1` | CI 侧 Python 探测(候选顺序须与 `ci_local.py` 同序同步,否则 CI 与本地判定会分叉) |
|
||||
| `ci_runner_bootstrap.ps1` | **本机 runner 运维脚本**(体检 `-Status` / 干跑 `-DryRun` / 部署 `-SetEnv -StartNow`):装"等 Gitea 就绪 + 崩溃自拉起"的看门狗 + 开机计划任务 + 机器级 `DTU_*` |
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
# 编号门禁·全库语料审计(已退役,2026-10-28 归档)
|
||||
# 编号门禁归档(两道都已退役:全库语料审计 2026-10-28、新增行检查 2026-10-29)
|
||||
|
||||
本目录是 2026-10-20 ~ 2026-10-28 期间在 `pre-commit` 里跑的那套**全库编号审计**,
|
||||
连同它的两份语料一起搬进来,**不再进提交门禁**。
|
||||
本目录是 2026-10-20 ~ 2026-10-29 期间在 `pre-commit` 里跑过的**两套编号门禁**,连同它们的
|
||||
语料与白名单一起搬进来,**都不再进提交门禁**。2026-10-29 的裁定见每篇文末与其留档文档。
|
||||
|
||||
| 文件 | 是什么 |
|
||||
|---|---|
|
||||
| `check_ids.py` | 八项校验脚本(规范 §8)。手工复查存量编号现状时才跑 |
|
||||
| `check_ids_new.py` | 只查新增行的那道(2026-10-28 ~ 2026-10-29 在钩子里跑),2026-10-29 用户裁定退役后降为**手工形态普查**;`--self-test` 保留,`REPO_ROOT` 因归档位置深两级改取 `parents[3]` |
|
||||
| `id_registry.json` | 99 族的注册表:形态正则 / 属主登记处 / 冻结 / 游标 / 两条护栏的数值 |
|
||||
| `id_aliases.json` | 旧号 → 新号 / 作废(`retired-to-phrase`、`void`)的别名表,187 KB |
|
||||
| `id_known_backlog.json` | 债务台账(收口时已还清到 0 条) |
|
||||
@@ -18,10 +19,11 @@
|
||||
|
||||
## 现在用什么
|
||||
|
||||
- **现行门禁**:`scripts/check_ids_new.py` + 钩子 `id-check-new` —— 只查 `git diff` 新增行,
|
||||
零语料。详解 `docs/门禁说明/id-check-new.md`。
|
||||
- **路线与验收条件**:`docs/编号规范.md` §8.5(①②③ 三步的来龙去脉)。
|
||||
- **规范正文**(仍然有效,只是不再全库机械校验):`docs/编号规范.md` §1 先问三句、§4.1 族总表。
|
||||
- **没有现行门禁**:接班的 `id-check-new`(只查新增行、零语料)也在 2026-10-29 被用户裁定退役,
|
||||
脚本进本目录。编号形态此后无机器面,判据 = `docs/编号规范.md` §1 的默认答案(2026-10-29 起一律停发)+ §4.1 存量族表 + 评审;
|
||||
留档 `docs/门禁说明/id-check-new.md`(拦下过什么、为什么退、手工怎么再跑)。
|
||||
- **手工普查与恢复机器面**:`docs/编号规范.md` §8.5(退役流水在 `编号治理历史.md`)。
|
||||
- **规范正文**(仍然有效,只是不再全库机械校验):`docs/编号规范.md` §1 默认答案、§4.1 存量族表。
|
||||
|
||||
## 怎么手工跑一次
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@ check_ids.py — 编号门禁(docs/编号规范.md §8 的 8 项校验)—
|
||||
|
||||
⚠ 退役说明(先读这段,别把它当活门禁用):
|
||||
本脚本与两份语料(id_registry.json / id_aliases.json)已整体移入 scripts/archive/id_gate/,
|
||||
**不再进 pre-commit**,也不再有人被要求维护语料。现行编号门禁是 scripts/check_ids_new.py
|
||||
(钩子 id-check-new:只查新增行、零语料)。本脚本保留下来只做一件事:
|
||||
**不再进 pre-commit**,也不再有人被要求维护语料。接班的 scripts/check_ids_new.py
|
||||
(钩子 id-check-new:只查新增行、零语料)已于 2026-10-29 一并退役,也进了本目录——
|
||||
**编号形态此后没有机器面**。本脚本保留下来只做一件事:
|
||||
想复查「存量编号现状」时手工跑一遍出报告。
|
||||
路线与判据替换的来龙去脉 → docs/编号规范.md §8.5;新门禁详解 → docs/门禁说明/id-check-new.md。
|
||||
手工普查与恢复机器面 → docs/编号规范.md §8.5;两道门禁的留档 → docs/门禁说明/id-check.md
|
||||
与 docs/门禁说明/id-check-new.md。
|
||||
下面这份 docstring 是退役前的原样,未改,作为历史口径保留。
|
||||
|
||||
两份配置(数据源 = 规范 §4 编号空间总表,逐项对应,不凭印象):
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""check_ids_new.py — 编号门禁·第二步:只查**新增行**的新编号(零语料、无语料维护)
|
||||
"""check_ids_new.py — 编号门禁·新增行(**已退役 2026-10-29,用户裁定**;本脚本降为手工报告工具)
|
||||
|
||||
背景(docs/编号规范.md §8.5):语义标识已是默认形态,1~6 项全库语料审计的成本高过收益。
|
||||
本脚本替代它的**唯一实际用途**——拦住"新写一个自造编号":只看 git diff 的新增行。
|
||||
退役口径:钩子已从 .pre-commit-config.yaml 摘除(YAML 解析条目 52 → 51),编号形态此后
|
||||
**没有机器面**——靠 docs/编号规范.md §1 的默认答案(一律停发)+ 评审。留档说明 → docs/门禁说明/id-check-new.md。
|
||||
本脚本与 check_ids.py(2026-10-28 退役的全库八项校验)同处一档:手工复查「这批改动 / 这段历史
|
||||
里有没有野生编号」时才跑,跑不跑都不影响提交。
|
||||
|
||||
判据(三条,都不依赖任何族清单 / 游标 / 属主登记处):
|
||||
1. 破折形态(形如 前缀-数字,或 前缀-段-数字):首段不在 KNOWN_DASH → FAIL;
|
||||
@@ -12,11 +14,11 @@
|
||||
3. 单字母+数字(C12 / U15 / L3 / R3)→ **放行**:元件位号与层次号同形,这是本脚本的已知盲区
|
||||
(与旧门禁的"裸形盲区"同源,见 docs/门禁说明/id-check-new.md §5)。
|
||||
|
||||
用法(仓库根):
|
||||
python scripts/check_ids_new.py # 查暂存区(pre-commit 用这个)
|
||||
python scripts/check_ids_new.py --worktree # 查工作区未暂存的改动(自查)
|
||||
python scripts/check_ids_new.py --range A..B # 查一段提交的新增行
|
||||
python scripts/check_ids_new.py --self-test # 内建正反例自检(改脚本后必跑)
|
||||
用法(仓库根;钩子摘除后没有自动调用者,四条都是手工):
|
||||
python scripts/archive/id_gate/check_ids_new.py # 查暂存区
|
||||
python scripts/archive/id_gate/check_ids_new.py --worktree # 查工作区未暂存的改动
|
||||
python scripts/archive/id_gate/check_ids_new.py --range A..B # 查一段提交的新增行
|
||||
python scripts/archive/id_gate/check_ids_new.py --self-test # 内建正反例自检(改脚本后必跑)
|
||||
退出码:0 = 通过 / 仅告警;1 = 新增了未知编号;2 = 环境错误。
|
||||
豁免:行内含 [示例] / [计划] 的行按冻结口径跳过;确需保留的写法在同一行写 [编号豁免]。
|
||||
"""
|
||||
@@ -33,7 +35,8 @@ for _stream in (sys.stdout, sys.stderr):
|
||||
except (AttributeError, ValueError):
|
||||
pass
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
# 归档位置比原位置深两级(scripts/archive/id_gate/)→ 上溯到仓库根要 parents[3]
|
||||
REPO_ROOT = Path(__file__).resolve().parents[3]
|
||||
|
||||
# --- 破折形态:首段白名单(活族 + 标准编号;新增族要先登记到这里,这就是"允许用号的唯一口子")
|
||||
KNOWN_DASH = frozenset({
|
||||
@@ -79,6 +82,9 @@ KNOWN_BARE = frozenset({
|
||||
"SFT",
|
||||
# UART 采样模式位名(OVER8)
|
||||
"OVER",
|
||||
# 录波段文件名:固件生成的 100 个号轮转(WAVE00 到 WAVE99 的 .BIN,App/algo/wave_store.c 拼名
|
||||
# FTP 根下 /wave/ 目录;文档与日志里都要写这个字面量,2026-10-29 登记)
|
||||
"WAVE",
|
||||
})
|
||||
|
||||
# --- 前缀后面接 -数字 其实是算术(SIZE-2 / LEN-1),不是编号
|
||||
@@ -95,7 +101,8 @@ EXCLUDED_DIRS = (
|
||||
|
||||
)
|
||||
EXCLUDED_FILES = frozenset({
|
||||
"scripts/check_ids_new.py", # 本脚本自带正反例白名单,不能自我拦截
|
||||
"scripts/check_ids_new.py", # 本脚本自带正反例白名单,不能自我拦截(归档后整目录已在
|
||||
# EXCLUDED_DIRS 的 scripts/archive/ 里,这行只是历史留笔)
|
||||
})
|
||||
EXCLUDED_SUFFIX = (".svg", ".png", ".jpg", ".jpeg", ".gif", ".bin", ".map", ".htm", ".html",
|
||||
".tsv", ".log", ".o", ".axf", ".hex", ".ico", ".ttf", ".woff", ".pyc",
|
||||
@@ -245,7 +252,8 @@ def main(argv=None):
|
||||
if args.verbose:
|
||||
print(" %s" % text)
|
||||
print(" → 语义标识是默认形态:改写成短语(docs/编号规范.md §1);")
|
||||
print(" 确属设备名/协议名/位号,就把前缀登记进 scripts/check_ids_new.py 的白名单。")
|
||||
print(" 确属设备名/协议名/位号,就改形态(写语义短语)——本门禁已于 2026-10-29 退役,")
|
||||
print(" 不再是提交钩子;要再拿它当尺子就手工跑 scripts/archive/id_gate/check_ids_new.py。")
|
||||
return 1
|
||||
print("[OK] 新增行无未登记编号%s"
|
||||
% ("(%d 处停发族提示)" % len(warns) if warns else ""))
|
||||
@@ -355,7 +355,7 @@ P-6 号必须能反查到定义(属主登记处得存在)· P-7 编号不语
|
||||
| 日期 | 变更 | 说明 |
|
||||
|---|---|---|
|
||||
| 2026-10-28 | **编号门禁第三步收口:全库语料审计退役(钩子 52 → 51)** | 用户裁定跳过观察期直接做。`check_ids.py` 与两份语料(`id_registry.json` 87.6 KB / `id_aliases.json` 187 KB)+ 债务台账整体移入 `scripts/archive/id_gate/`(附归档 README,含"为什么退役 / 现在用什么 / 怎么手工跑");`id-check` 钩子摘除,现役编号门禁只剩 `id-check-new`(只查新增行)。连带改:`rename_ids.py` 的别名表路径指向归档、新门禁排除面加 `scripts/archive/`、`doc-links` 跳过 `.mnemon/` 与 `ci-artifacts/`(本地状态与草稿,非项目文档)、`id-check.md` 加退役横幅、`门禁说明/README` 与 `AGENTS` 的钩子数三数对齐(声明 51 / commit 阶段 50 + gitlint 1)。归档脚本从新路径实跑:811 文件 / 8,051 字面量、`--strict` rc=0。 |
|
||||
| 2026-10-28 | **编号门禁第二步落地:新增行拦截(零语料)** | `scripts/check_ids_new.py` + 钩子 `id-check-new`:只看新增行,破折形态未知前缀 FAIL、已停发族只 WARN、单字母+数字放行(元件位号同形,见该门禁 §6 盲区)。白名单是**前缀级**两张表(活族 11 条 / 器件与协议约 90 条),不是字面量账本——后者会退化成 `id_aliases.json` 的老路。调参依据:最近 80 笔真实提交回放,未知形态 15 种(12 种是设备与协议名、3 种是停发族),调好后误报 0;自检 5 正例 + 29 反例。与 `id-check` **双跑**一个观察期后再按 `docs/编号规范.md` §8.5 ③ 退役旧语料。 |
|
||||
| 2026-10-28 | **编号门禁第二步落地:新增行拦截(零语料)** | 脚本(今在 `scripts/archive/id_gate/check_ids_new.py`)+ 钩子 `id-check-new`:只看新增行,破折形态未知前缀 FAIL、已停发族只 WARN、单字母+数字放行(元件位号同形,见该门禁 §6 盲区)。白名单是**前缀级**两张表(活族 11 条 / 器件与协议约 90 条),不是字面量账本——后者会退化成 `id_aliases.json` 的老路。调参依据:最近 80 笔真实提交回放,未知形态 15 种(12 种是设备与协议名、3 种是停发族),调好后误报 0;自检 5 正例 + 29 反例。与 `id-check` **双跑**一个观察期后再按 `docs/编号规范.md` §8.5 ③ 退役旧语料。 |
|
||||
| 2026-10-28 | **编号门禁减负第一步:两根护栏转报告制** | 用户裁定「编号门禁每次浪费很多时间」→ 先摘掉语料审计的强制面。护栏 1(可判定比例基线)与护栏 2(不可判定绝对数上限)自此**只打印、不拦提交**;实测把基线调到 99.9%、上限调到 1 处,退出码仍为 0。硬拦只剩校验 1~6 的台账外新账(同一实测:新文件里写一个自造前缀 + 数字,校验 1 与增量拦截照旧 FAIL)。退役路线 ①②③ 写进 `docs/编号规范.md` §8.5;减负依据 = 近 80 笔提交有 61 笔被编号体系牵连、语料共 99 族(78 族已冻结)。 |
|
||||
| 2026-10-28 | **变更记录行里已停发/作废族的示例编号改形态描述;并用门禁自身计数器把「这一笔能不能压下不可判定绝对数」钉死为零** | 用户指令:把变更记录行里已停发族的那几枚示例编号改成语义形态描述,并确认它让不可判定引用绝对数净减、不是只算自己这一笔。**实测裁定:净减 = 0**。门禁把「表格首格是日期」的行整行豁免于编号判定(registry 侧的变更记录豁免,本笔前全库已豁免 198 处站点),本表的示例编号从来不进引用总数分母,改它必然不动绝对数——改前改后同一个计数器均为 **1003**(上限 1166;可判定 87.43%,三项都是 2026-10-28 本回合实测)。唯一移动的是那行豁免计数本身(本文件少 1 处站点),把它当清退成果就是把自记账成全局减量,正是本笔要排除的错法。本文对该计数器的全部贡献 **6** 处,逐文件集合差实测:全是「非编号」判定栏里既定的噪声名与裸形盲区(哈希算法名、总线名、严重度档位、硬件位号),不是编号,不清。本笔动的 3 处只是写法:作废的网络条目孤儿号(F 前缀 + 模块码段 + 数字序号三段)与已删报告的 UI 簇(字母 U 紧跟一位数字,区间两端即该簇首尾两枚);事实本体仍在别名表、registry 游标备注与 git 历史,一处没丢。刻意不动:硬件位号形态的举例(判非编号)、保留现存号族的冻结游标数字(冻结水位的证据本体)、其它文档与注册表里的同名字段(各自写域)。`docs/编号规范.md` §5.5 同步写死该例外的硬口径。零代码、零编号增删、两根护栏基线均未调整。 |
|
||||
| 2026-10-27 | **批次五:「数据可信」任务卡号整族清退 + 注入验证卡销项删行** | 用户指令「数据可信.md 已经完成的内容请进行销项删除,去除相关编号」。实测 **288 站点 / 56 文件**(代码与测试 191 / 文档 56 / 门禁配置与本文 41)全改语义短语;`docs/编号规范.md` §5 表首列由「序」改「标识(任务名)」、14 个旧号进 §9.3 换算表;顺带按属主文档判语义清掉同形态的悬空引用 4 处(「UI 补齐」波次的 `[comm]` 段前置项)。门禁面:编号字面量与不可判定绝对数**零变化**(中文前缀不在语料),收口复跑 `check_ids.py --strict` 与 `check_doc_links.py --all --sections-strict` |
|
||||
|
||||
@@ -993,7 +993,7 @@ def selftest_board_frames(clf):
|
||||
|
||||
|
||||
def selftest_refs(clf):
|
||||
"""仓库黄金参考(60 张)逐帧分类自检:每张图的期望值 = 它的文件名。
|
||||
"""仓库黄金参考(66 张)逐帧分类自检:每张图的期望值 = 它的文件名。
|
||||
|
||||
这一组是**语义正确的基线**(模拟器与板端同一份 UI 源码),用来把"分类器错了"与
|
||||
"留档帧本来就是走歪的"分开——两类失败含义完全不同,混在一起就只能靠猜。
|
||||
|
||||
@@ -339,8 +339,8 @@ def main(argv=None):
|
||||
ap.add_argument("--selftest", action="store_true", help="正例照得出 + 反例不误报 + 基线机制有效")
|
||||
args = ap.parse_args(argv)
|
||||
|
||||
if not os.path.isdir(os.path.join(REPO, ".git")):
|
||||
print("[ENV] 仓库根定位失败:%s 里没有 .git" % REPO)
|
||||
if not os.path.exists(os.path.join(REPO, ".git")):
|
||||
print("[ENV] 仓库根定位失败:%s 里没有 .git(目录或 worktree 的 gitdir 文件都算)" % REPO)
|
||||
return 2
|
||||
|
||||
print("=== 块注释嵌套检查 check_nested_comment.py(注释体内出现 /* = ARMCC 诊断 9-D)===")
|
||||
|
||||
+61
-5
@@ -78,7 +78,11 @@ def subsystem_of(obj):
|
||||
return RTOS_HEAP
|
||||
if n in _KERNEL:
|
||||
return "其它"
|
||||
if n.startswith(("app_", "adc_", "prot_", "phasor", "sample_ring",
|
||||
# 应用 = App/ 其余(台账 §2 口径)。新增 App 目录/前缀必须同步这里,
|
||||
# 漏登记不会报错,只会被静默算进「其它」——unattributed_app_objects() 是兜底信号。
|
||||
if n.startswith(("app_", "adc_", "prot_", "protect_task", "phasor", "sample_ring",
|
||||
"wave_", "meas", "freq", "run_par", "iec104", "soe_",
|
||||
"task_prof", "boot_stats", "vol_idle_sync",
|
||||
"sys_", "cfg_", "dbg_", "console_log", "task_watchdog",
|
||||
"sha256", "tpafe", "sd2506", "test_task", "time_sync",
|
||||
"default_task")):
|
||||
@@ -86,6 +90,56 @@ def subsystem_of(obj):
|
||||
return "其它"
|
||||
|
||||
|
||||
# 兜底:源文件在 App/ 却落进「其它」= 前缀表漏登记。2026-10-29 实测这样隐身了
|
||||
# 12 个对象 / 9,445 B(wave_ring 5,296 起),配额表完全看不见录波与 SOE 支路。
|
||||
_APP_SRC_DIR = REPO_ROOT / "App"
|
||||
_APP_STEMS = None
|
||||
|
||||
|
||||
def _app_stems():
|
||||
"""App/**/*.c 主干名集合(扫一次缓存);目录读不到就返回空集 = 兜底自动失效。"""
|
||||
global _APP_STEMS
|
||||
if _APP_STEMS is None:
|
||||
try:
|
||||
_APP_STEMS = {p.stem.lower() for p in _APP_SRC_DIR.rglob("*.c")}
|
||||
except OSError:
|
||||
_APP_STEMS = set()
|
||||
return _APP_STEMS
|
||||
|
||||
|
||||
def _obj_base(obj):
|
||||
return obj.rsplit("\\", 1)[-1].rsplit("/", 1)[-1].lower()
|
||||
|
||||
|
||||
def unattributed_app_objects(objs):
|
||||
"""[(对象, B)]:归进「其它」但源文件在 App/ 的对象,按字节降序。"""
|
||||
stems = _app_stems()
|
||||
if not stems:
|
||||
return []
|
||||
out = []
|
||||
for obj, nbytes in objs:
|
||||
if subsystem_of(obj) != "其它":
|
||||
continue
|
||||
base = _obj_base(obj)
|
||||
if base.endswith(".o") and base[:-2] in stems:
|
||||
out.append((obj, nbytes))
|
||||
return sorted(out, key=lambda t: (-t[1], t[0]))
|
||||
|
||||
|
||||
def warn_unattributed(info):
|
||||
"""打印未归类告警(软提醒,不拦);返回条数。门禁与 --write 都调,别让人静默隐身。"""
|
||||
missing = unattributed_app_objects(info["objs"])
|
||||
if not missing:
|
||||
return 0
|
||||
total = sum(n for _, n in missing)
|
||||
print("[WARN] %d 个 App/ 对象未登记进 subsystem_of() 前缀表,被算进「其它」而不是"
|
||||
"「应用」(台账 §2:应用 = App/ 其余),合计 %d B:" % (len(missing), total))
|
||||
for obj, nbytes in missing:
|
||||
print(" %-28s %6d B" % (_obj_base(obj), nbytes))
|
||||
print(" 修法:补 subsystem_of() 前缀 -> 重跑 @build -> --update / --write 回填台账")
|
||||
return len(missing)
|
||||
|
||||
|
||||
def collect(map_path):
|
||||
"""解析 .map → {'regions': {name: r}, 'subsys': {name: bytes}, 'top': [(obj, B)]}。"""
|
||||
data = ram_report.parse_map(str(map_path))
|
||||
@@ -96,11 +150,11 @@ def collect(map_path):
|
||||
subsys = {s: 0 for s in SUBSYSTEMS}
|
||||
for c in comps:
|
||||
subsys[subsystem_of(c["object"])] += c["rw_data"] + c["zi_data"]
|
||||
top = sorted(((c["object"], c["rw_data"] + c["zi_data"]) for c in comps),
|
||||
key=lambda t: (-t[1], t[0]))
|
||||
top = [t for t in top if t[1] > 0][:TOP_N]
|
||||
objs = [(c["object"], c["rw_data"] + c["zi_data"]) for c in comps]
|
||||
objs = [t for t in objs if t[1] > 0]
|
||||
top = sorted(objs, key=lambda t: (-t[1], t[0]))[:TOP_N]
|
||||
return {"regions": regions, "region_list": data["regions"],
|
||||
"subsys": subsys, "top": top}
|
||||
"subsys": subsys, "top": top, "objs": objs}
|
||||
|
||||
|
||||
def region_pct(r):
|
||||
@@ -238,6 +292,8 @@ def cmd_gate(args):
|
||||
if newest and newest > map_path.stat().st_mtime:
|
||||
print("[WARN] .map 早于最新源码——数字来自旧构建,建议先 @build 再提交")
|
||||
|
||||
warn_unattributed(info)
|
||||
|
||||
ir, cc = info["regions"].get("RW_IRAM1"), info["regions"].get("RW_CCM")
|
||||
print(f"RAM 预算门禁 PASS:RW_IRAM1 {region_pct(ir):.1f}% / RW_CCM {region_pct(cc):.1f}%"
|
||||
f"(阈值 {THRESHOLD_PCT:.0f}%)")
|
||||
|
||||
@@ -12,4 +12,5 @@ date code ro rw zi er_irom1 er_pct iram1 iram1_pct ccm ccm_pct top_rwzi
|
||||
2026-10-27 235372 26392 1572 136924 261764 25.0 81072 61.9 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055;default_task.o=2736
|
||||
2026-10-28 236456 28124 1876 137084 264580 25.2 81536 62.2 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055;default_task.o=2736
|
||||
2026-10-29 238936 29140 1932 141396 268076 25.6 85904 65.5 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;sb_link.o=4364;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055
|
||||
2026-10-30 239064 29156 1932 141396 268220 25.6 85904 65.5 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;sb_link.o=4364;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055
|
||||
2026-10-29 243552 28784 1972 145388 272336 26.0 89936 68.6 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;wave_ring.o=5296;ch395f.o=4162;console_log.o=4132;sys_log_mcu.o=4055
|
||||
2026-10-30 246160 29816 2036 149700 275976 26.3 94312 72.0 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6420;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4364;ch395f.o=4162;console_log.o=4132
|
||||
|
||||
|
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"built_at": "2026-10-30T00:21:57+08:00",
|
||||
"fingerprint": "1cbc1bc0c030169d1851e6303e0d643ae1f01632f03883215557416e7f3eb4ee",
|
||||
"fingerprint_files": 1458,
|
||||
"built_at": "2026-10-30T01:06:44+08:00",
|
||||
"fingerprint": "1ed4267c77f65e357f631ef775aef15a784757ae2ffecf15cb3838b5e2ce1fb5",
|
||||
"fingerprint_files": 1466,
|
||||
"fingerprint_source": "git-index",
|
||||
"gated_regions": [
|
||||
"RW_IRAM1",
|
||||
"RW_CCM"
|
||||
],
|
||||
"git_head": "9c6d150261caacd1a3ff835d2830f706e9de2bf7",
|
||||
"git_head": "f405c8994fd0123b7b8ad1d449a372508a5276ac",
|
||||
"map": "MDK-ARM/STM32F407-Demo/STM32F407-Demo.map",
|
||||
"map_mtime": 1793290914,
|
||||
"map_mtime": 1793293592,
|
||||
"pct": {
|
||||
"ER_IROM1": 25.58,
|
||||
"ER_IROM1": 26.32,
|
||||
"RW_CCM": 87.89,
|
||||
"RW_IRAM1": 65.54,
|
||||
"RW_IRAM1": 71.95,
|
||||
"UNINIT_CCM": 18.75
|
||||
},
|
||||
"regions": {
|
||||
"ER_IROM1": {
|
||||
"max": 1048576,
|
||||
"size": 268220
|
||||
"size": 275976
|
||||
},
|
||||
"RW_CCM": {
|
||||
"max": 65280,
|
||||
@@ -27,7 +27,7 @@
|
||||
},
|
||||
"RW_IRAM1": {
|
||||
"max": 131072,
|
||||
"size": 85904
|
||||
"size": 94312
|
||||
},
|
||||
"UNINIT_CCM": {
|
||||
"max": 256,
|
||||
@@ -37,10 +37,10 @@
|
||||
"schema": 2,
|
||||
"scope_note": "\u540c\u7801\u51ed\u8bc1\uff1a\u6307\u7eb9\u8986\u76d6\u56fa\u4ef6\u4f53\u79ef\u76f8\u5173\u6e90\u7801\uff0c\u53e3\u5f84\u89c1\u672c\u811a\u672c docstring",
|
||||
"sizes": {
|
||||
"code": 239064,
|
||||
"ro_data": 29156,
|
||||
"rw_data": 1932,
|
||||
"zi_data": 141396
|
||||
"code": 246160,
|
||||
"ro_data": 29816,
|
||||
"rw_data": 2036,
|
||||
"zi_data": 149700
|
||||
},
|
||||
"threshold_pct": 92.0,
|
||||
"worktree_dirt_at_stamp": 0,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"files": {
|
||||
"App/algo/adc_cal.c": {
|
||||
"func_rate": 1.0,
|
||||
"func_rate": 0.9412,
|
||||
"funcs_covered": 16,
|
||||
"funcs_valid": 16,
|
||||
"line_rate": 0.986,
|
||||
"funcs_valid": 17,
|
||||
"line_rate": 0.9463,
|
||||
"lines_covered": 141,
|
||||
"lines_valid": 143
|
||||
"lines_valid": 149
|
||||
},
|
||||
"App/algo/adc_health.c": {
|
||||
"func_rate": 1.0,
|
||||
@@ -88,6 +88,22 @@
|
||||
"lines_covered": 15,
|
||||
"lines_valid": 15
|
||||
},
|
||||
"App/algo/wave_ring.c": {
|
||||
"func_rate": 1.0,
|
||||
"funcs_covered": 15,
|
||||
"funcs_valid": 15,
|
||||
"line_rate": 0.9956,
|
||||
"lines_covered": 225,
|
||||
"lines_valid": 226
|
||||
},
|
||||
"App/algo/wave_store.c": {
|
||||
"func_rate": 1.0,
|
||||
"funcs_covered": 29,
|
||||
"funcs_valid": 29,
|
||||
"line_rate": 0.9612,
|
||||
"lines_covered": 446,
|
||||
"lines_valid": 464
|
||||
},
|
||||
"App/cfg/cfg_file.c": {
|
||||
"func_rate": 0.963,
|
||||
"funcs_covered": 26,
|
||||
@@ -369,12 +385,12 @@
|
||||
"lines_valid": 75
|
||||
},
|
||||
"Drivers/BSP/UI/ui_data.c": {
|
||||
"func_rate": 0.9767,
|
||||
"func_rate": 0.8235,
|
||||
"funcs_covered": 42,
|
||||
"funcs_valid": 43,
|
||||
"line_rate": 0.9637,
|
||||
"funcs_valid": 51,
|
||||
"line_rate": 0.8692,
|
||||
"lines_covered": 372,
|
||||
"lines_valid": 386
|
||||
"lines_valid": 428
|
||||
},
|
||||
"Drivers/BSP/UI/ui_net_sink.c": {
|
||||
"func_rate": 0.7692,
|
||||
@@ -397,10 +413,10 @@
|
||||
"modules": {
|
||||
"adc_cal": {
|
||||
"files": {
|
||||
"App/algo/adc_cal.c": 143,
|
||||
"App/algo/adc_cal.c": 149,
|
||||
"App/cfg/cfg_file.c": 689
|
||||
},
|
||||
"lines_total": 832,
|
||||
"lines_total": 838,
|
||||
"ok": true
|
||||
},
|
||||
"adc_health": {
|
||||
@@ -471,7 +487,7 @@
|
||||
},
|
||||
"iec104": {
|
||||
"files": {
|
||||
"App/algo/adc_cal.c": 143,
|
||||
"App/algo/adc_cal.c": 149,
|
||||
"App/algo/freq.c": 130,
|
||||
"App/algo/meas.c": 64,
|
||||
"App/algo/phasor.c": 55,
|
||||
@@ -485,7 +501,7 @@
|
||||
"App/protocol/iec104/iec104_link.c": 405,
|
||||
"App/protocol/iec104/iec104_pts.c": 255
|
||||
},
|
||||
"lines_total": 2365,
|
||||
"lines_total": 2371,
|
||||
"ok": true
|
||||
},
|
||||
"iec104_serv": {
|
||||
@@ -586,14 +602,14 @@
|
||||
},
|
||||
"prot_dim": {
|
||||
"files": {
|
||||
"App/algo/adc_cal.c": 143,
|
||||
"App/algo/adc_cal.c": 149,
|
||||
"App/algo/freq.c": 130,
|
||||
"App/algo/phasor.c": 55,
|
||||
"App/algo/prot_elm.c": 122,
|
||||
"App/algo/prot_set.c": 179,
|
||||
"App/algo/sample_ring.c": 41
|
||||
},
|
||||
"lines_total": 670,
|
||||
"lines_total": 676,
|
||||
"ok": true
|
||||
},
|
||||
"prot_elm": {
|
||||
@@ -624,11 +640,11 @@
|
||||
},
|
||||
"run_par": {
|
||||
"files": {
|
||||
"App/algo/adc_cal.c": 143,
|
||||
"App/algo/adc_cal.c": 149,
|
||||
"App/algo/run_par.c": 129,
|
||||
"App/cfg/cfg_file.c": 689
|
||||
},
|
||||
"lines_total": 961,
|
||||
"lines_total": 967,
|
||||
"ok": true
|
||||
},
|
||||
"sb_led_map": {
|
||||
@@ -706,10 +722,10 @@
|
||||
},
|
||||
"ui_data": {
|
||||
"files": {
|
||||
"Drivers/BSP/UI/ui_data.c": 386,
|
||||
"Drivers/BSP/UI/ui_data.c": 428,
|
||||
"Drivers/BSP/UI/ui_w_soe.c": 62
|
||||
},
|
||||
"lines_total": 448,
|
||||
"lines_total": 490,
|
||||
"ok": true
|
||||
},
|
||||
"ui_sink": {
|
||||
@@ -739,6 +755,29 @@
|
||||
},
|
||||
"lines_total": 73,
|
||||
"ok": true
|
||||
},
|
||||
"wave_ring": {
|
||||
"files": {
|
||||
"App/algo/wave_ring.c": 226,
|
||||
"App/algo/wave_store.c": 464
|
||||
},
|
||||
"lines_total": 690,
|
||||
"ok": true
|
||||
},
|
||||
"wave_store": {
|
||||
"files": {
|
||||
"App/algo/wave_store.c": 464
|
||||
},
|
||||
"lines_total": 464,
|
||||
"ok": true
|
||||
},
|
||||
"wave_trig": {
|
||||
"files": {
|
||||
"App/algo/wave_ring.c": 226,
|
||||
"App/algo/wave_store.c": 464
|
||||
},
|
||||
"lines_total": 690,
|
||||
"ok": true
|
||||
}
|
||||
},
|
||||
"note": "主机单测覆盖率基线。口径与工具链限制见 docs/测试说明/主机单测覆盖率口径.md。门禁判据:files[].lines_covered 与 funcs_covered 只增不减,下降即拦提交。",
|
||||
@@ -755,6 +794,8 @@
|
||||
"App/algo/run_par.c",
|
||||
"App/algo/sample_ring.c",
|
||||
"App/algo/sb_led_map.c",
|
||||
"App/algo/wave_ring.c",
|
||||
"App/algo/wave_store.c",
|
||||
"App/cfg/cfg_file.c",
|
||||
"App/cfg/cfg_file_store_mcu.c",
|
||||
"App/cfg/prot_set_store.c",
|
||||
@@ -796,16 +837,16 @@
|
||||
],
|
||||
"totals": {
|
||||
"files_generated_excluded": 5,
|
||||
"files_tested": 49,
|
||||
"files_untested": 166,
|
||||
"func_rate": 0.9324,
|
||||
"funcs_covered": 552,
|
||||
"funcs_valid": 592,
|
||||
"line_rate": 0.9009,
|
||||
"lines_covered": 7349,
|
||||
"lines_valid": 8157,
|
||||
"modules_ok": 44,
|
||||
"modules_total": 44
|
||||
"files_tested": 51,
|
||||
"files_untested": 172,
|
||||
"func_rate": 0.924,
|
||||
"funcs_covered": 596,
|
||||
"funcs_valid": 645,
|
||||
"line_rate": 0.9016,
|
||||
"lines_covered": 8020,
|
||||
"lines_valid": 8895,
|
||||
"modules_ok": 47,
|
||||
"modules_total": 47
|
||||
},
|
||||
"untested_sources": [
|
||||
{
|
||||
@@ -816,10 +857,22 @@
|
||||
"code_lines": 689,
|
||||
"path": "Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 525,
|
||||
"path": "App/task/ui_task.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 466,
|
||||
"path": "App/task/default_task.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 420,
|
||||
"path": "App/app/ui_data_feed.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 369,
|
||||
"path": "App/task/adc_task.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 353,
|
||||
"path": "Drivers/BSP/UI/ui_w_setview.c"
|
||||
@@ -832,10 +885,6 @@
|
||||
"code_lines": 300,
|
||||
"path": "Drivers/BSP/UI/ui_content_page.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 286,
|
||||
"path": "App/task/default_task.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 265,
|
||||
"path": "Drivers/BSP/UI/ui_w_editor.c"
|
||||
@@ -845,12 +894,12 @@
|
||||
"path": "Drivers/BSP/SD2506/sd2506.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 263,
|
||||
"path": "App/task/adc_task.c"
|
||||
"code_lines": 248,
|
||||
"path": "Drivers/BSP/UI/ui_page_wave_play.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 253,
|
||||
"path": "App/task/ui_task.c"
|
||||
"code_lines": 230,
|
||||
"path": "Drivers/BSP/UI/ui_data.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 218,
|
||||
@@ -864,10 +913,6 @@
|
||||
"code_lines": 206,
|
||||
"path": "Drivers/BSP/CH395F/ch395f.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 206,
|
||||
"path": "Drivers/BSP/UI/ui_data.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 205,
|
||||
"path": "Drivers/BSP/UI/ui_page_net_cfg.c"
|
||||
@@ -888,6 +933,10 @@
|
||||
"code_lines": 152,
|
||||
"path": "Drivers/BSP/UI/ui_page_runreport.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 150,
|
||||
"path": "App/algo/wave_store.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 150,
|
||||
"path": "Drivers/BSP/UI/ui_page_password.c"
|
||||
@@ -901,7 +950,7 @@
|
||||
"path": "App/app/app_main.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 134,
|
||||
"code_lines": 142,
|
||||
"path": "App/task/protect_task.c"
|
||||
},
|
||||
{
|
||||
@@ -964,6 +1013,10 @@
|
||||
"code_lines": 77,
|
||||
"path": "Drivers/BSP/dbg_log.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 75,
|
||||
"path": "App/algo/wave_ring.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 69,
|
||||
"path": "Drivers/BSP/UI/ui_page_dc.c"
|
||||
@@ -1056,6 +1109,10 @@
|
||||
"code_lines": 40,
|
||||
"path": "Drivers/BSP/UI/ui_page_deadband.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 38,
|
||||
"path": "Drivers/BSP/UI/ui_page_wave_manual.c"
|
||||
},
|
||||
{
|
||||
"code_lines": 36,
|
||||
"path": "Drivers/BSP/ScreenLink/sb_proto.h"
|
||||
@@ -1084,6 +1141,10 @@
|
||||
"code_lines": 33,
|
||||
"path": "Drivers/BSP/UI/ui_page_action.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 32,
|
||||
"path": "App/algo/adc_cal.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 32,
|
||||
"path": "App/util/boot_stats.h"
|
||||
@@ -1092,10 +1153,6 @@
|
||||
"code_lines": 32,
|
||||
"path": "Drivers/BSP/RS485/rs485.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 31,
|
||||
"path": "App/algo/adc_cal.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 31,
|
||||
"path": "App/protocol/iec104/iec104_pts.h"
|
||||
@@ -1376,6 +1433,14 @@
|
||||
"code_lines": 11,
|
||||
"path": "Drivers/BSP/UI/ui_page_view_word.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 11,
|
||||
"path": "Drivers/BSP/UI/ui_page_wave_manual.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 11,
|
||||
"path": "Drivers/BSP/UI/ui_page_wave_play.h"
|
||||
},
|
||||
{
|
||||
"code_lines": 11,
|
||||
"path": "Drivers/BSP/UI/ui_page_yx.h"
|
||||
|
||||
Reference in New Issue
Block a user