docs(配图): 生成器与产物清单并成一张唯一真值表,挂载列改由实测反推

两张清单各自登记同一批生成器,2026-10-30 实测各漏各的:
`tools/arch_diagram/README.md`「脚本一览」21 行缺 5 个(adc_health 三张、
net_instability、net_pending),`docs/架构设计/图形绘制流程.md` 的三列表 18 行
缺 9 个(多出的还在 `docs/架构设计/图形绘制流程.md` §2.1 另立一张表登记例外面)。
同一条事实两处登记必然漂,现并成一张:

- 唯一真值表 = `tools/arch_diagram/README.md`「产物清单」:按图逐行,32 张入库
  `docs/images/*.svg` 全量(26 个本目录生成器 + refgraph 2 张 + 无生成器的手工
  级联框 2 张),列 = 图 / 生成器 / 这张图答什么 / 顶部数据区(改这里 → 重跑)/
  挂在(`文档:行号`)。
- `docs/架构设计/图形绘制流程.md` §二 的逐脚本表换成指针(只留选型判据与流程),
  §2.1 保留「钩子扫不到的图」的维护口径、去掉与主表重复的表。
- 级联框两张的绘制日期按 `git log --follow` 改对:原写「2026-10-26 手画」与 git 史
  不符,实测 2026-09-08 `891c9ef0` 入库、2026-09-11 `2429955d` 随配图规范收拢进
  `docs/images/`,此后未再改动。
- `docs/门禁说明/generated-fresh.md` §8 旧口径「加生成器 = `GENS` 加一项」对
  `docs-svg` 不实:该条目声明 `dir` + `pattern = gen_*.py`,实跑 `glob.glob` 现扫
  (`scripts/check_generated_fresh.py`:146-150 与 :452)→ 新增生成器自动进扫描面,
  要同批改的是产物清单不是门禁。已拆成「加新类别」与「`docs-svg` 不必登记」两条。
- 「挂在」列由扫描 `![]()` 反推,并跳过 ``` 围栏与行内反引号里的示例写法——
  `docs/文档规范.md`:83、`draw-diagram` SKILL.md:155、本文档 §3.1 第 5 步
  那三处是教学示例、不是真挂载,先前手写表时误计进去过。
- 三张零内嵌图(`内存布局_RAM.svg`、`引用关系图.svg`、`引用关系图_模块.svg`)
  在表里明写「零内嵌」并给出被文字提到的位置。

`draw-diagram` skill 的落库义务同批改指:§二第 6 步与验证清单都指向「产物清单」,
并写明「全仓只此一张逐脚本清单」,避免下一个人再另起第二张。

自查:`check_doc_links.py --sections-strict` 三篇 rc=0;`check_generated_fresh.py`
PASS(26 生成器 / 22 一致 / 4 存量基线);`check_skill_size.py` 17 个 SKILL.md ok;
`check_mermaid.py --all` 31 文件 62 围栏新发 0;`check_bom_drift.py --all` 99 文件
无漂移;产物清单核对器(一次性,不入库)重写挂载列后复跑归零、再跑幂等。
纯文档与 skill 文案,未改任何生成器与代码,未 commit。
This commit is contained in:
2026-10-30 16:54:53 +08:00
parent 002e66d928
commit f48208f1c5
4 changed files with 99 additions and 59 deletions
+6 -3
View File
@@ -71,7 +71,10 @@ whenToUse: 需要新增/修改 docs/ 文档的技术配图(协议帧、分层
```
5. 跑 `& '.venv\Scripts\python.exe' tools/arch_diagram/gen_<主题>_svg.py`,**把 OVERFLOW 告警打到 0 再进目检**——预检能在渲染前就报出 `foot: 974 > 968` 这类溢出(本窗实测两张图首跑各报一条脚注超宽),比靠眼睛反复量便宜一个数量级。
6. 新脚本落库时**同批**把这一行加进 `tools/arch_diagram/README.md` 的「脚本一览」表。
6. 新脚本落库时**同批**把行加进 `tools/arch_diagram/README.md` 的「**产物清单**」——那张表按图逐行,列 =
图 / 生成器 / 这张图答什么 / 顶部数据区 / 挂在(`文档:行号`)。**全仓只此一张逐脚本清单**:
`docs/架构设计/图形绘制流程.md` 曾另立一张三列表,结果两张各漏各的(2026-10-30 实测 README 漏 5 个、
那张漏 9 个),现已换成指针。所以新图只加一行,别在第二篇文档再起一张表。
## 三b、大图(几十框几十边)加一道碰撞审计,别只靠眼睛
@@ -179,7 +182,7 @@ sha1sum docs/images/<主题>.svg
## 六、提交
生成器脚本(源)+ `docs/images/<主题>.svg`(产物)+ 引用它的 `.md` + `tools/arch_diagram/README.md` 那一行**同一笔**提交;PNG 预览不入库。
生成器脚本(源)+ `docs/images/<主题>.svg`(产物)+ 引用它的 `.md` + `tools/arch_diagram/README.md`「产物清单」那一行**同一笔**提交;PNG 预览不入库。
```powershell
& '.venv\Scripts\python.exe' -m pre_commit run --files <脚本> <svg> <md> <README.md>
@@ -202,7 +205,7 @@ sha1sum docs/images/<主题>.svg
- [ ] 绝对路径 PNG 存在、尺寸 = 画布,`read_image` 回读确认:无文字压框 / 溢出、无标签互撞、无 `…` 截断收尾、配色在调色板内。
- [ ] 连跑两次产物 sha1 不变;`scripts/check_generated_fresh.py` rc=0(无 DIFF / NEW,`[BASELINE]` 未增加)。
- [ ] 大图(≥20 边):跑一遍 §三b 的碰撞审计,报数归零(标签压框 / 走线穿框 / 标签出画布)。
- [ ] 引用它的 `.md` 相对路径正确(根目录 `images/`,子目录 `../images/`);`tools/arch_diagram/README.md` 已加脚本行。
- [ ] 引用它的 `.md` 相对路径正确(根目录 `images/`,子目录 `../images/`);`tools/arch_diagram/README.md`「产物清单」已加行,「挂在」列的 `文档:行号` 用 `grep -rn "<图名>.svg" docs/ --include=*.md` 现扫核对(**别抄旧行号**,行号一漂整列就废)。
- [ ] 脚本 + 产物 `.svg` + `.md` + README 行一并暂存;`pre-commit run --files …` 全过(无乱码 / 行尾空白 / 编码 OK)。
> **TODO(口径未与权威文档同步)**:`docs/架构设计/图形绘制流程.md` §3.1 第 4 步「目检:浏览器打开 SVG」与 §四「给 `.venv` 装 cairosvg 转 PNG」在 Windows 上按本 skill 的实测是走不通的。该文档是规范归属(AGENTS.md:同一事实只在一处详述),采纳 §三 / §五 时应把这两段同步过去;目前两处不一致,**做图以本 skill 的实测命令为准,规范条文以该文档为归属**。
+21 -28
View File
@@ -36,41 +36,34 @@
## 二、既有工具(`tools/arch_diagram/`)
以下生成器共享同一套约定(§3.2),均为**纯标准库**拼 SVG:
`tools/arch_diagram/` 下的 26 个生成器共享同一套约定(§3.2),均为**纯标准库**拼 SVG。**逐脚本 / 逐图的
清单不在本文**——2026-10-30 起并成一张,落 **`tools/arch_diagram/README.md`「产物清单」**:32 张入库
`docs/images/*.svg` 逐张列出「谁生成它 / 它答什么问题 / 改哪段数据能重跑 / 被哪篇文档内嵌」,本文一度
另立一张三列表,结果两张表各自漏登记(README 漏 5 个、本文漏 9 个,2026-10-30 实测),同一条事实两处
登记必然漂移 → 现只留一处,本文只讲**怎么选、怎么画、怎么审**。
| 脚本 | 产物(入库) | 顶部数据区(改这里 → 重跑) |
|---|---|---|
| `gen_arch_svg.py` | `docs/images/项目架构总览.svg` | `LAYERS` / `ROWS` / `FOOT` |
| `gen_barrier_svg.py` | `docs/images/就绪屏障.svg` | `BITS` / `PRODUCERS` / `CONSUMERS` |
| `gen_frame_svg.py` | `docs/images/RemoDispBus帧格式.svg` | `FIELDS` / `TITLE` / `SUB` / `FOOT` |
| `gen_storage_stack_svg.py` | `docs/images/存储栈分层.svg` | `L_*` / `ROWS` / `TITLE` / `SUB` / `FOOT` |
| `gen_partition_svg.py` | `docs/images/物理分区布局.svg` | `FIELDS` / `TITLE` / `SUB` / `FOOT`(MB 计量) |
| `gen_net_pending_svg.py` | `docs/images/Net层阻塞模型.svg` | `CALLER_STEPS` / `LOOP_STEPS` / `PHASES` |
| `gen_arch_endtoend_svg.py` | `docs/images/架构总览_端到端链路.svg` | `NODES`(id / 列 / 行 / 标题 / 副题)+ `EDGES`(出入框方位与 f / g / my / gx 旋钮)+ `BANDS` 纵带;三条独占通道 `CHAN_B` / `CHAN_78` / `CHAN_SLOTS` 与走廊 `GUT_C4C5` 落在几何区 |
| `gen_cfg_arch_svg.py` | `docs/images/配置文件分层架构.svg` | 配置引擎分层 |
| `gen_net_stack_svg.py` | `docs/images/BSD网络栈分层.svg` | BSD 网络栈分层 |
| `gen_memory_svg.py` | `docs/images/内存布局_*.svg` | RAM / FLASH 布局 |
| `gen_watchdog_svg.py` | `docs/images/看门狗心跳模型.svg` | `TASKS` / `REQ_BITS` / `POLL_STEPS` / `TIMELINE` |
| `gen_adc_frontend_svg.py` | `docs/images/ADC前端电路.svg` | `SUB1` / `NOTE_*` 等文案常量 + 面板坐标(电路拓扑固定,网表变了才重画) |
| `gen_adc_code_scale_svg.py` | `docs/images/ADC码值刻度.svg` | `PANELS` 列表(码范围 / LSB / 实测码标记位置)+ `FOOT`(换芯片才重画) |
| `gen_data_trust_ladder_svg.py` | `docs/images/数据可信台阶.svg` | `STEPS` 五级台阶(状态 / 问题 / 依据)+ `BAND_LABEL_1` / `GATE_LABEL` / `FOOTNOTE`(台阶状态变了才重画) |
| `gen_data_trust_dc_ac_svg.py` | `docs/images/ADC直流标定与交流验证.svg` | `BOXES_A` / `BOXES_B` 两条泳道 + `CHIPS` 六件事 + `NOTES` 红线与"证不到"清单 |
| `gen_wave_record_flow_svg.py` | `docs/images/故障录波数据流.svg` | `CHAIN` 主链四段 + `EDGE` 跨边界标签 + `TRAPS` 三条陷阱 + `FORBID` 四条红线(所有权、段形态或红线变了才重画) |
| `gen_menu_tree_svg.py` | `docs/images/菜单树总览.svg` | **内嵌 `NODE_SRC`**(= `ui_menu_tree.txt` 的 43 行节点)+ 版面常量;仓库里跑会与真值逐行互验,不一致 exit 1(临时目录里读不到真值 → 用内嵌表,输出逐字节一致) |
- 要新增一张精确布局图:先到那张表按主题找最接近的生成器**照抄骨架**(`draw-diagram` skill §二),
落库时**同批把行加进那张表**(不往本文加)。
- 要挑工具(SVG 还是 Mermaid 还是截图):看本文 §一 的选型表与维度对比表——那是**判据**,不是清单,
与逐脚本清单不重复。
### 2.1 钩子扫不到的图:refgraph 产物与历史手画稿
`generated-fresh` 的 `docs-svg` 条目只把 `tools/arch_diagram/gen_*.py` 拷进临时目录重跑逐字节比对。
上表没列到的 `docs/images/*.svg` 就是下面这几张,**它们全都不在这条钩子的扫描面里**——改了不会有任何
人报警,这就是「42 个节点的旧图挂在 43 个节点的标题下」能一路活到今天的原因。
**本目录生成器不产的那四张图**(`引用关系图.svg`、`引用关系图_模块.svg`、`级联框总览.svg`、
`级联框几何计算.svg`)**全都不在这条钩子的扫描面里**——改了不会有任何人报警,这就是「42 个节点的旧图
挂在 43 个节点的标题下」能一路活到今天的原因。四张图的产物、出处与挂载逐张列在
**`tools/arch_diagram/README.md`「产物清单」**末尾两组,本文不再重复登记;只留维护口径:
| 图 | 谁画的 | 用在哪 | 维护口径 |
|---|---|---|---|
| `docs/images/引用关系图.svg`、`docs/images/引用关系图_模块.svg` | `tools/refgraph/gen_refgraph.py`(graphviz,不在 `gen_*.py` 命名面里) | `docs/架构设计/引用关系图说明.md` 的产品 | 改了代码引用就跑 `tools\refgraph\gen_refgraph.bat` 重生成,**svg 与改动同一笔提交**,别只更新 `.dot`;口径 → `docs/架构设计/引用关系图说明.md` |
| `docs/images/级联框总览.svg` | 2026-10-26 手画 | `docs/UI设计/菜单页面设计.md` §4.1(级联框显示几何:根框 + 整定子框) | 只作**显示几何示意**,不承载菜单树事实;树的结构 / 层级 / 绑页 → `docs/images/菜单树总览.svg`(有生成器) |
| `docs/images/级联框几何计算.svg` | 同上 | `docs/UI设计/菜单页面设计.md` §5.3(逐框坐标推导) | 同上;坐标公式变了要重算重画,别在 SVG 上描字 |
- **refgraph 两张**(`tools/refgraph/gen_refgraph.py`,graphviz,命名不在 `gen_*.py` 面内):改了代码引用
就跑 `& 'tools\refgraph\gen_refgraph.bat'` 重生成,**svg 与改动同一笔提交**,别只更新 `.dot`;
口径 → `docs/架构设计/引用关系图说明.md`。
- **级联框两张**:手工 SVG、**无生成器**(`git log --follow` 实测 2026-09-08 `891c9ef0` 入库、2026-09-11
`2429955d` 随配图规范收拢进 `docs/images/`,此后未再改动;本文此前写的绘制日期与 git 史不符,已按 git 改)。
只作**显示几何示意**,不承载菜单树事实——树的结构 / 层级 / 绑页走
`docs/images/菜单树总览.svg`(有生成器);坐标公式变了要重算重画,别在 SVG 上描字。
新增精确布局图一律走 `tools/arch_diagram/gen_*.py`(`docs-svg` 条目自动发现,**不必登记基线**);上面这几张
新增精确布局图一律走 `tools/arch_diagram/gen_*.py`(`docs-svg` 条目自动发现,**不必登记基线**);上面这两组
是这套纪律的**例外面**,再多一张先说清为什么不能用生成器。
---
+6 -2
View File
@@ -177,8 +177,12 @@
## 8. 改这个门禁本身
- 加生成器:`GENS` 加一项(声明 `seed` 输入 + `mkdir` 输出目录)→ **同笔**更新本页 §1 的表与
`docs/文档规范.md` §4.4 的在册表;先跑 `--only <新id> --verbose` 确认干净再合。
- 加**新类别**(一批产物 + 一种 seed 机制):`GENS` 加一项(声明 `seed` 输入 + `mkdir` 输出目录)→
**同笔**更新本页 §1 的表与 `docs/文档规范.md` §4.4 的在册表;先跑 `--only <新id> --verbose` 确认干净再合。
- **`docs-svg` 不必登记**(2026-10-30 复核脚本实测纠正本条旧口径):该条目声明的是 `dir` +
`pattern = gen_*.py`,实跑用 `glob.glob` 现扫 `tools/arch_diagram/` → **新增生成器自动进扫描面**,
往 `GENS` 里再加一项反而没有对应的 seed 可声明。要同批改的是**产物清单**
`tools/arch_diagram/README.md`「产物清单」(逐图逐脚本的唯一真值表),不是本页也不是门禁。
- 声明 `seed` 要按**生成器实际读了什么**写,不是按「我觉得它是输入」:`gen_menu.py` 会
`os.listdir(Drivers/BSP/UI)` 找页面实例,所以整个 UI 目录 + 两份注册表必须一起拷。
- 临时目录一律 `tempfile.mkdtemp()`:任何「顺手写回仓库」的改动都不要加——本钩子的全部安全性
+66 -26
View File
@@ -2,32 +2,66 @@
> 用 Python 脚本**精确生成**架构类 SVG 图(分层、内存布局、协议帧、屏障等),
> 产物放 `docs/images/`。用于"必须精确布局"的图;拓扑图(流程/时序/状态机)改用 Mermaid。
>
> 下面这张表是**配图产物的唯一真值清单**——入库的 32 张 `docs/images/*.svg` 逐张列出:谁生成它、
> 它答什么问题、改哪一段数据能重跑、被哪篇文档内嵌。选型判据与绘制流程 → `docs/架构设计/图形绘制流程.md`,
> 画图时的操作入口 → **`draw-diagram` skill**。
## 脚本一览
## 产物清单(按主题分组 · 32 张全量)
| 脚本 | 产物 | 用途 |
|---|---|---|
| `gen_arch_svg.py` | 架构分层图 | 六层分层结构 |
| `gen_memory_svg.py` | 内存布局图 | RAM / Flash 分区 |
| `gen_storage_stack_svg.py` | 存储栈图 | FTL / dhara / FatFs 三层栈 |
| `gen_net_stack_svg.py` | 网络栈图 | BSD 网络栈分层 |
| `gen_barrier_svg.py` | 就绪屏障图 | Event Flags 屏障模型 |
| `gen_frame_svg.py` | 协议帧格式图 | RemoDispBus 帧结构 |
| `gen_cfg_arch_svg.py` | 配置引擎架构图 | 配置分层与持久化 |
| `gen_partition_svg.py` | 分区图 | 存储分区 |
| `gen_watchdog_svg.py` | 看门狗心跳模型图 | IWDG + 任务心跳位图(置位→判定→喂狗 + 时间轴) |
| `gen_adc_frontend_svg.py` | ADC 前端电路图 | 端子 → 串阻 → 转换节点 → 转换器引脚;含差分负端与 STM32 侧对照 |
| `gen_adc_code_scale_svg.py` | ADC 码值刻度图 | 「码」的直观定义:两片转换器的刻度尺对照(16 位双极性 vs 12 位单极性) |
| `gen_arch_endtoend_svg.py` | 架构总览端到端链路图 | 端到端链路鸟瞰:片外硬件 → 驱动 → 算法 → 任务 → 落点 → 对外/同构端,42 框 37 边 5 条纵带;线型分数据 / 命令 / 屏障心跳三类,长边各占一条独占通道(与 §1 分层图分工:那张答「谁在哪一层」,这张答「一条数据走到底要穿过谁」) |
| `gen_data_trust_ladder_svg.py` | 数据可信台阶图 | 采集数据可信度的五级台阶:现在踩在哪一级、下一级挡什么 |
| `gen_data_trust_dc_ac_svg.py` | ADC 直流标定与交流验证图 | 上排直流注入链、下排信号发生器正弦验证,中间列只有正弦能证的六件事 |
| `gen_wave_record_flow_svg.py` | 故障录波数据流图 | 录波段数据的四个所有者与四条「不许」:谁独占写、谁只能读、标志怎么过界 |
| `gen_menu_tree_svg.py` | 菜单树总览图 | 43 节点的层级 / 绑页 / 密码门鸟瞰;内嵌 `ui_menu_tree.txt` 的节点行并与真值互验,防图与树漂移 |
| `gen_sample_ring_why_svg.py` | 采样环缓冲_为什么需要 | 上游 1 kHz 覆盖写只交最新一帧 vs 下游要 20 点滑窗:缺口 19 点与三个消费者 |
| `gen_sample_ring_layout_svg.py` | 采样环缓冲_环形布局 | 40 格环里哪 20 格是本窗、写指针指「下一格」、回绕与三条设计不变量 |
| `gen_sample_ring_start_svg.py` | 采样环缓冲_窗首下标 | 窗首 = head − n 的圆周走法,与「直接减 / 16 位回绕 / 先加 DEPTH」三种写法对照 |
| `gen_ac_rounds_svg.py` | 交流六轮速查 | 执行手册 §8 六轮总览卡:每轮注什么波形(正弦/方波三角/异相/扫频/削顶/谐波叠加缩略图)、判据一句话、主读数出口 |
| `gen_ac_median_svg.py` | 交流定数取中位数 | 「连取 10 行取中位数」的机理(全周窗滑动 → 读数拍频跳)与操作(中位数 vs 平均 vs 单行对真值)两栏数值示意 |
「挂在」列只认 Markdown 图片链接 `![](...)`,格式 `文档:行号`;**行号会漂,现查勿背**:
`grep -rn "图名.svg" docs/ --include=*.md`。零内嵌的图在单元格明写「零内嵌」,它要么只被正文文字提到、
要么就是**挂了但没人挂图**——改图的人顺手把这条也核对一次。
| 图(`docs/images/`) | 生成器 | 这张图答什么 | 顶部数据区(改这里 → 重跑) | 挂在 |
|---|---|---|---|---|
| **架构与启动** | | | | |
| `项目架构总览.svg` | `gen_arch_svg.py` | 六层分层结构与跨层依赖——「谁在哪一层」(不含数据流边、不含片外硬件) | `LAYERS` / `ROWS` / `FOOT` | `docs/架构设计/软件架构与运行时规格.md`:14、`docs/架构设计/项目架构总览.md`:11 |
| `架构总览_端到端链路.svg` | `gen_arch_endtoend_svg.py` | 端到端链路鸟瞰——一个电气量从引脚走到 104 报文 / 显存 / 记录文件**穿过谁、与谁在什么时候换锁**;42 框 37 边 5 条纵带,线型分数据 / 命令 / 屏障心跳 | `NODES`(id / 列 / 行 / 标题 / 副题)+ `EDGES`(出入框方位与 `f` / `g` / `my` / `gx` 旋钮)+ `BANDS`;三条独占通道 `CHAN_B` / `CHAN_78` / `CHAN_SLOTS` 与走廊 `GUT_C4C5` 在几何区 | `docs/架构设计/项目架构总览.md`:53 |
| `就绪屏障.svg` | `gen_barrier_svg.py` | Event Flags 屏障模型:位 → 生产者 → 消费者三栏对齐,哪些位真在用、哪些是预留 | `BITS` / `PRODUCERS` / `CONSUMERS` / `FOOT` | `docs/架构设计/软件架构与运行时规格.md`:63、`docs/架构设计/项目启动顺序管理.md`:48、`docs/架构设计/项目架构总览.md`:85 |
| `配置文件分层架构.svg` | `gen_cfg_arch_svg.py` | 配置引擎分层与持久化:谁解析 `[section]`、落盘走哪条链 | `ROWS` 分层清单 + 标题 / 脚注文案 | `docs/产品需求/产品需求设计文档.md`:331、`docs/子系统设计/配置文件设计说明.md`:144 |
| **采集与算法** | | | | |
| `ADC前端电路.svg` | `gen_adc_frontend_svg.py` | 端子 → 串阻 → 转换节点 → 转换器引脚;含差分负端与 STM32 侧对照 | `SUB1` / `NOTE_*` 等文案常量 + 面板坐标(电路拓扑固定,网表变了才重画) | `docs/测试说明/专项验证/ADC前端注入验证流程.md`:31、`docs/硬件平台/ADC通道映射说明.md`:161 |
| `ADC码值刻度.svg` | `gen_adc_code_scale_svg.py` | 「码」的直观定义:两片转换器的刻度尺对照(16 位双极性 vs 12 位单极性) | `PANELS`(码范围 / LSB / 实测码标记位置)+ `FOOT`(换芯片才重画) | `docs/测试说明/专项验证/ADC前端注入验证流程.md`:104 |
| `ADC直流标定与交流验证.svg` | `gen_data_trust_dc_ac_svg.py` | 上排直流注入链、下排信号发生器正弦验证,中间列只有正弦能证的六件事 | `BOXES_A` / `BOXES_B` 两条泳道 + `CHIPS` 六件事 + `NOTES` 红线与"证不到"清单 | `docs/任务规划/数据可信.md`:294 |
| `数据可信台阶.svg` | `gen_data_trust_ladder_svg.py` | 采集数据可信度的五级台阶:现在踩在哪一级、下一级挡什么 | `STEPS` 五级台阶(状态 / 问题 / 依据)+ `BAND_LABEL_1` / `GATE_LABEL` / `FOOTNOTE`(台阶状态变了才重画) | `docs/任务规划/数据可信.md`:21 |
| `采样有效性校验数据流.svg` | `gen_adc_health_flow_svg.py` | 观测计数 → 快照 → 判定 → 位图 → 消费者:三条量车道(TPAFE / STM32 / 时基)平行流过五个阶段 | `STAGES` 五阶段 + `LANES` 三条车道 + `COLS` + `FOOT` | `docs/算法/采样有效性校验设计说明.md`:81 |
| `采样有效性位图与掩码.svg` | `gen_adc_health_bitmap_svg.py` | 出口位图与消费者掩码对照——同一 bit 在三张位图与四个掩码里落同一列(Mermaid 控不住列位,故必须等宽网格) | `GROUPS` 位图组 + `C_LEVEL` / `C_LATCH` / `C_EVENT` / `C_MASK` 四类位 + `WARN` / `FOOT` | `docs/算法/采样有效性校验设计说明.md`:303 |
| `采样有效性判定时间轴.svg` | `gen_adc_health_timeline_svg.py` | 四个工况的时序与门限(100 ms 门限线、静默计时线、电平位与锁存位的存续区间——按时间比例画,Mermaid 只画拓扑不保比例) | `PANELS` 四工况 + `T_MAX` / `V_MAX` 比例轴 + `WARN` / `FOOT` | `docs/算法/采样有效性校验设计说明.md`:212 |
| `采样环缓冲_为什么需要.svg` | `gen_sample_ring_why_svg.py` | 上游 1 kHz 覆盖写只交"最新一帧" vs 下游相量要一整周波(20 点):缺口 19 点与三个消费者 | `SUB1` + `CARDS` 对照卡 + `FOOTNOTE` | `docs/算法/采集与算法层设计说明.md`:162 |
| `采样环缓冲_环形布局.svg` | `gen_sample_ring_layout_svg.py` | 40 格环里哪 20 格是本窗、写指针指"下一格"而不是"最后一格"、整窗随每次写入右移一格与三条设计不变量 | `START` / `SUB3` + `CARDS` 三件事 + `FOOTNOTE` | `docs/算法/采集与算法层设计说明.md`:192 |
| `采样环缓冲_窗首下标.svg` | `gen_sample_ring_start_svg.py` | 窗首 `start = head − n` 的圆周走法,与"直接减 / 16 位回绕 / 先加 `DEPTH`"三种写法对照 | `START` / `SUB1` + `ROWS` 三种写法 + `FOOTNOTE` | `docs/算法/采集与算法层设计说明.md`:203 |
| `交流六轮速查.svg` | `gen_ac_rounds_svg.py` | 交流(正弦)动态验证六轮的总览卡:每轮注什么波形(六张波形缩略图)、判据一句话、主读数出口 | `SUB1` / `SUB2` + `CARDS` 六轮卡 + `FOOTNOTE` | `docs/测试说明/专项验证/ADC前端注入验证流程.md`:296 |
| `交流定数取中位数.svg` | `gen_ac_median_svg.py` | 为什么交流轮必须"连取 10 行心跳取中位数":机理(全周窗逐拍滑动 → 单行带拍频跳)与操作(中位数 vs 平均 vs 单行对真值) | `SUB1` + `VALS` 两栏数值 + `OPS_NOTE` / `FOOTNOTE` | `docs/测试说明/专项验证/ADC前端注入验证流程.md`:431 |
| **网络与协议** | | | | |
| `BSD网络栈分层.svg` | `gen_net_stack_svg.py` | BSD socket 分层在本仓落到哪一层(CH395F 之上) | `ROWS` 分层清单 + 标题 / 脚注文案 | `docs/网络/BSD_Socket_API_使用指南.md`:56 |
| `Net层阻塞模型.svg` | `gen_net_pending_svg.py` | 挂起(pending)请求模型:调用方两栏 + 主循环横带 + recv 五路 / send 四路判定带 | `CALLER_STEPS` / `FAST_PATH` / `LOOP_STEPS` / `PHASES` / `FOOT` | `docs/网络/Net层阻塞模型架构设计.md`:77 |
| `网络不稳根因总览.svg` | `gen_net_instability_svg.py` | 自愈架构复盘:左列七个误会(问题环)、右列对应拆法,水平箭头一一对应、竖箭头表示"叠加累积" | `RINGS` 七对 + `SUM_LEFT` / `SUM_RIGHT` 两个总结盒 + `FOOT` | `docs/网络/网络自愈架构设计.md`:233 |
| `RemoDispBus帧格式.svg` | `gen_frame_svg.py` | 协议帧字节级布局:字段宽严格 ∝ 字节数 + 逐字段标注 + 偏移标尺 | `FIELDS` / `TITLE` / `SUB` / `FOOT` | `docs/UI设计/RemoDispBus协议与接收设计说明.md`:60、`docs/产品需求/产品需求设计文档.md`:1204 |
| **存储与内存** | | | | |
| `存储栈分层.svg` | `gen_storage_stack_svg.py` | 存储栈三层:dhara FTL / FatFs / 应用落点(`gen_arch_svg.py` 的单栈副本) | `ROWS`(层数据在 `L_*` 常量)/ `TITLE` / `SUB` / `FOOT` | `docs/产品需求/产品需求设计文档.md`:299、`docs/架构设计/STM32F4-Base存储架构说明.md`:7 |
| `物理分区布局.svg` | `gen_partition_svg.py` | SPI NAND 物理分区:分区宽 ∝ MB 数 + 偏移标尺(帧图生成器的 MB 计量副本) | `FIELDS` / `TITLE` / `SUB` / `FOOT`(MB 计量) | `docs/架构设计/STM32F4-Base存储架构说明.md`:11 |
| `内存布局_RAM.svg` | `gen_memory_svg.py` | 192 KB SRAM(SRAM1/2)+ CCM 的分区归属与占用 | `RAM1_CATEGORIES` / `RAM2_CATEGORIES` | **零内嵌**——只在 `docs/内存管理/RAM使用分析与优化方案.md`:772 与本表被文字提到 |
| `内存布局_FLASH.svg` | `gen_memory_svg.py` | 1 MB Flash 的段划分与代码 / 常量占比 | `FLASH_CATEGORIES` / `FLASH_CODE_SUB` | `docs/内存管理/RAM使用分析与优化方案.md`:239 |
| `任务栈预算.svg` | `gen_memory_svg.py` | 9 个任务的栈配额与内核静态占用合计 | `TASK_STACKS` / `KERNEL_STACKS` | `docs/内存管理/RAM使用分析与优化方案.md`:101 |
| **时间 / 看门狗 / 录波** | | | | |
| `看门狗心跳模型.svg` | `gen_watchdog_svg.py` | IWDG + 任务心跳位图:置位 → 判定 → 喂狗,配一条时间轴 | `TASKS` / `REQ_BITS` / `POLL_STEPS` / `T_AXIS` / `TIMELINE` / `FOOT` | `docs/产品需求/产品需求设计文档.md`:397、`docs/子系统设计/看门狗设计说明.md`:151 |
| `故障录波数据流.svg` | `gen_wave_record_flow_svg.py` | 录波段数据的四个所有者与四条「不许」:谁独占写、谁只能读、标志怎么过界 | `CHAIN` 主链四段 + `EDGE` 跨边界标签 + `TRAPS` 三条陷阱 + `FORBID` 四条红线(所有权、段形态或红线变了才重画) | `docs/子系统设计/故障录波设计说明.md`:165 |
| **UI** | | | | |
| `菜单树总览.svg` | `gen_menu_tree_svg.py` | 菜单树 43 节点的层级 / 绑页 / 密码门鸟瞰 | **内嵌 `NODE_SRC`**(= `ui_menu_tree.txt` 的 43 行节点)+ `X_COL` 版面常量;在仓库里跑会与真值逐行互验、不一致 exit 1(临时目录读不到真值 → 用内嵌表,保证输出逐字节一致) | `docs/产品需求/产品需求设计文档.md`:1537 |
| `级联框总览.svg` | **无生成器(手工 SVG)** | 横向级联子框总览(主界面 → 参数定值 → 整定)的显示几何示意 | 直接改 SVG 文本(2026-09-08 入库 `891c9ef0`,2026-09-11 随配图规范收拢 `2429955d`);只作**显示几何示意**,不承载菜单树事实 | `docs/UI设计/菜单页面设计.md`:442 |
| `级联框几何计算.svg` | **无生成器(手工 SVG)** | `ui_menu_view_frame_build()` 逐框坐标推导:行剖面定框宽 → X 贴父框右缘 → Y 顶对齐选中行 → Y 溢出上移 | 同上;**坐标公式变了要重算重画,别在 SVG 上描字** | `docs/UI设计/菜单页面设计.md`:500 |
| **引用关系(另一个工具)** | | | | |
| `引用关系图.svg` | `tools/refgraph/gen_refgraph.py`(graphviz) | 文件级引用图(项目代码视图) | 跑 `& 'tools\refgraph\gen_refgraph.bat'` 重生成,**svg 与改动同一笔提交**,别只更新 `.dot` | **零内嵌**——`docs/架构设计/引用关系图说明.md`:47、`tools/refgraph/README.md`:23 以表格条目列出 |
| `引用关系图_模块.svg` | 同上 | 模块级概览图(目录 / 库聚合,边上 ×n = 引用条数) | 同上 | **零内嵌**——`docs/架构设计/引用关系图说明.md`:48 |
> **`OVERFLOW` 不算「数据区」**:它是生成器末尾的溢出预检累加器(非空即打 `OVERFLOW:` 并 exit 1),
> 不是给人改的内容。判据与预检用法 → **`draw-diagram` skill** §三。
>
> **本表怎么保持不漂**:新增生成器 = 同批在本表加一行(本目录的约定,也是 `draw-diagram` skill §五第 6 步);
> 图换挂载文档 = 同批改「挂在」列。门禁只兜**幂等性**不兜本表——`scripts/check_generated_fresh.py` 的
> `docs-svg` 条目按 `tools/arch_diagram/gen_*.py` **自动发现**重跑逐字节比对,**不必登记**;只有需要外部
> seed 的条目(`menu-gen` / `cn-chars` / `cn-font`)才在 `GENS` 里显式登记 → `docs/门禁说明/generated-fresh.md` §8。
## 使用方式
@@ -41,8 +75,14 @@
- 颜色/字体遵循 `docs/架构设计/图形绘制流程.md` 的规范
- 中文用 SVG `<text>` 直接写(需注意字体族声明)
- 改图**改脚本再重跑**,不手改 SVG(保证可复现)
- 改图**改脚本再重跑**,不手改 SVG(保证可复现);上表标「无生成器」的两张级联框图是**例外面**,
再多一张先说清为什么不能用生成器 → `docs/架构设计/图形绘制流程.md` §2.1
- 表里没有的 `docs/images/*.svg` 就是漂移——按 `grep -rn "gen_" tools/arch_diagram/*.py` 与
`ls docs/images/*.svg` 对账补齐本表,别另起一张
## 相关文档
- `docs/架构设计/图形绘制流程.md` — 配图规范、选型与检查清单
- `docs/架构设计/图形绘制流程.md` — 配图选型(什么图用什么工具)、绘制流程与检查清单
- `docs/文档规范.md` §4.4 — 配图与生成物的入库纪律(类别级在册清单,不逐脚本登记)
- `docs/门禁说明/generated-fresh.md` — 幂等性门禁查什么、盲区在哪
- **`draw-diagram` skill** — 画图时的操作入口(含大图碰撞审计判据)