Files
STM32F4-Base/docs/文档规范.md
T
wandering1 75c234b0c2 docs: 项目审查报告移入 问题记录/,删除空的 审查记录/ 目录
让评审报告与 待处理内容.md 的分工更直观:
- git mv 项目审查与优化建议报告.md → docs/问题记录/(与 Trap 台账、
  错误码传播审计同处"专项审计"目录);rmdir 空的 docs/审查记录/。
- docs/README.md:§8 标题改为「评审报告 · 环境与部署 · 外部资料」,
  §8.1 改为「评审报告」,目录树删 审查记录/、补 问题记录/ 说明,
  按角色导航改为 §8.1/§8.3,补 2026-10-04 变更记录。
- 根 README.md 目录树同步。
- docs/文档规范.md §1.1 现有目录列表、§6 归属表同步。
- 看门狗设计说明.md / 待处理内容.md 的路径引用重定向。

pre-commit 17/17 Passed。
2026-10-04 02:34:40 +08:00

15 KiB
Raw Blame History

文档规范

适用对象:本仓库 docs/ 下的全部 Markdown 文档,以及根目录 README.md、AGENTS.md。 强制程度:§1~§6 为强制(pre-commit 机械校验,违反即拦截提交);§7~§8 为约定(评审时人工把关)。 相关文档:README.md(文档索引)、代码规范/pre-commit使用说明.md(钩子清单)、架构设计/图形绘制流程.md(配图流程)。


1. 目录与命名

1.1 目录

规则 说明
目录名一律不含空格 空格迫使脚本/链接/CI 处处加引号,且 URL 编码形态(UI%20设计)极易被漏改(D-6,2026-09-25 起强制;全库已无含空格目录)
按领域归入子目录 顶层不放散落 .md;新领域先建无空格子目录,再在 README.md 登记
现有目录 架构设计/ 子系统设计/ 网络/ 测试说明/ 代码规范/ 内存管理/ 问题记录/ 环境与部署/ UI设计/ 硬件平台/ 芯片手册/ images/

1.1b 代码目录的 README.md

每个自建代码目录(非第三方库、非 HAL/CMSIS 生成)必须有一份 README.md, 说明该目录的职责、文件清单与关键约束,让新接手者不必读遍代码即可建立认知。

规则 说明
覆盖范围 App/(含 log/ task/ util/)、Drivers/BSP/(含各芯片子目录)、Src/、Inc/、scripts/、tools/(含各子工具)、test/、MDK-ARM/、simulator/(含 sim/ tests/)、docs/
排除 第三方库与生成代码:Drivers/CMSIS/、Drivers/STM32F4xx_HAL_Driver/、Middlewares/Third_Party/、Lib/(FatFs/dhara/lvgl)、simulator/SDL2/、构建产物目录
必备内容 ① 一句话定位 + 是否自研 ② 文件/子目录清单表(每个一句话作用)③ 关键约束或陷阱(改前须知)④ 指向 docs/ 权威文档的链接
命名 一律 README.md(大写),放该目录根部
链接 目录间互链用同级相对路径(如 ../NET/README.md);指向 docs/ 用仓库根相对路径
门禁 README 内所有链接受 doc-links 钩子检查;新增/改名目录或文件后须同步更新对应 README

目的:目录即文档的入口。根 README.md 给全局地图,各目录 README.md 给局部细节, 二者构成"地图 + 地标"的导航体系(避免所有信息堆在单一 README)。

1.2 文件名

规则 说明
不含空格 同目录规则
主题词 + 类型后缀 xxx设计说明.md / xxx_Test_Guide.md / xxx_Trap_Records.md / xxx使用说明.md
中英混排 中文主题词直接写(如 系统墙钟时间维护说明.md);含专有名词/缩写可用下划线连接(如 BSD_Socket_API_使用指南.md)
只用 ASCII 与中文 不含 ()【】〔〕 等全角括号、不含 &、?、*、<、>、`
版本号写法 版本后缀用下划线连接,不用全角括号:xxx_V1.0.md(✅)/ xxx(V1.0).md(❌)

例外:docs/芯片手册/ 为外部芯片数据手册转录,文件名沿用上游原名(含空格等),不受本节约束。


2. 编码与换行

项 要求
编码 UTF-8;.md 文档不带 BOM
换行 与文件现状保持一致;新建文档用 LF
行尾空白 禁止(pre-commit trailing-whitespace 自动清理)
文件尾 必须以单个换行结束(end-of-file-fixer)
乱码 禁止出现 U+FFFD(替换字符,字节序列 EF BF BD)

⚠️ 本仓库 BOM 铁律(见 AGENTS.md):C 源码中 Drivers/BSP/UI/*、App/task/ui_task.c、App/cfg/cfg_file.c、Lib/lv_conf.h 等带 BOM,被工具改写后 BOM 会静默丢失 → ARMCC 改按 CP936 解码 → 中文字面量编译失败。 文档(.md)不受此限,一律用无 BOM UTF-8。但用脚本批量改写文档时,仍须按原样回写换行符(本仓库 core.autocrlf=true 且无 .gitattributes,工作区换行混杂),否则会产生整文件行尾漂移的巨型 diff。


3. 链接规范

3.1 文档间互链:仓库根相对路径

文档之间引用一律使用仓库根相对路径(形如 `docs/xxx/yyy.md` 或 [文本](docs/xxx/yyy.md)),不使用 ../ 相对链接。

理由:根相对路径对文档所在层级不敏感,迁移子目录时零改动;../ 形态在目录调整时会成片失效。

3.2 图片链接:文档所在目录相对

图片是例外——用相对当前文档的路径:

文档位置 图片写法
docs/xxx.md(docs 根下) ![标题](images/RemoDispBus帧格式.svg)
docs/子目录/xxx.md ![标题](../images/RemoDispBus帧格式.svg)

⚠️ 踩坑记录:2026-09-25 目录重组时,5 篇文档从 docs/ 迁入子目录,images/xxx.svg 未同步改为 ../images/xxx.svg → 7 处真实断链(由 D-7 门禁 check_doc_links.py 揪出)。迁移含图文档时务必检查此项。

3.3 引用尚未创建 / 已删除的文件

场景 写法 示例
计划中、尚未创建 反引号内加 [计划] 前缀 `[计划] scripts/gen_task_table.py`
已删除 写明「已删除」等状态词 删除 \tools/ui_mock/render_mockup.py`(已删除)`
引用报错样例 / 日志片段(含路径) 该行加 [示例] 标记 | **典型报错** | \[示例] docs/a.md:1 [markdown 链接] x.svg` |`

为什么:check_doc_links.py 会豁免这些标记;否则门禁会把"诚实标注了未创建"的引用误判为断链。

3.4 链接写法示例须放行内代码

讲「怎么写链接」的语法示例必须包在反引号里(行内代码 span):

  • ✅ 正确:写 `![标题](相对路径.svg)` 的形式
  • ❌ 错误:写 ![标题](相对路径.svg) 的形式(会被门禁当作真实链接去校验存在性)

check_doc_links.py 扫描前会剥离行内代码 span,故写法示例不会误报;但反引号内的仓库根相对路径(docs/xxx.md)仍会被校验——那是本工程的引用约定形态。


4. 门禁:文档-代码一致性(D-7)

三个层次,全部由 pre-commit 机械校验:

层次 钩子 检查内容 触发条件
存在性 doc-links docs/**/*.md 里的链接、反引号路径是否指向真实文件 改动任意 .md
数值 task-table README.md、AGENTS.md 的 FreeRTOS 任务表是否与 Src/freertos.c 一致 改动 README.md / AGENTS.md / Src/freertos.c
体积 mem-numbers 内存/Flash 数字是否与最新 .map 一致(受管区 + 陈旧散句数字) 改动内存文档 / App·Src·Inc 源码 / 脚本
体积 check-added-large-files 阻止 >1MB 大文件入库 任意文件

4.1 本地手动运行

# 全库文档链接存在性
& '.venv\Scripts\python.exe' scripts/check_doc_links.py --all

# 任务表一致性(只检查)
& '.venv\Scripts\python.exe' scripts/gen_task_table.py --check

# 任务表不一致时:自动重写受管表格区
& '.venv\Scripts\python.exe' scripts/gen_task_table.py --write

# 内存数字(受管快照 + 陈旧散句数字扫描)
& '.venv\Scripts\python.exe' scripts/check_mem_numbers.py --scan
& '.venv\Scripts\python.exe' scripts/check_mem_numbers.py --write   # 同步受管快照

# 只看期望内容,不写文件
& '.venv\Scripts\python.exe' scripts/gen_task_table.py --diff
& '.venv\Scripts\python.exe' scripts/check_mem_numbers.py --diff

# 生成完整内存台账(人工分析用)
& '.venv\Scripts\python.exe' scripts/ram_report.py -o docs/内存管理/data/ram_report_<日期>.md

4.2 受管区域(锚点)

文档里凡随代码变化的具体数值,都必须放进受管区,由脚本生成、禁止手改:

任务表(README.md / AGENTS.md)——表格外的说明文字原样保留:

<!-- TASK_TABLE:BEGIN generated by scripts/gen_task_table.py -->
| Task | 栈 (words) | 优先级 |
|---|---|---|
| ... |
<!-- TASK_TABLE:END -->

内存/Flash 快照(docs/内存管理/RAM使用分析与优化方案.md §2.1):

<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
| 区域 | 用量 | 容量 | 占比 |
|---|---|---|---|
| ... |
<!-- MEM_SNAPSHOT:END -->

改栈流程:先改 Src/freertos.c 的 osThreadAttr_t → 跑 gen_task_table.py --write → 提交。 改内存流程:先改代码 + @build 出 .map → 跑 check_mem_numbers.py --write → 提交。 钩子报不一致时不要手改受管区——跑 --write 让脚本重算。

陈旧数字扫描(mem-numbers --scan)

除受管区外,脚本还会扫正文里的陈旧区域数字:从 docs/内存管理/data/ram_report_*.md 历史快照提取「曾经是区域用量、现已变化」的值(如旧 RW_IRAM1 82,048), 若正文仍以陈述现状的口吻引用即告警。

允许保留旧数字的情况(脚本按行内关键词自动放行):该行含 「历史 / 旧 / 曾 / 此前 / 快照 / data/ / 修复前 / 优化前 / 迁入前 / 实施时 / 当时」等标记。 讲任务栈 / 内存池 / 峰值水位等非区域用量的行也自动跳过(那些数字语义不同)。

设计取舍:朴素地"扫所有 4~7 位数字"实测产生 45 处误报(栈配置 4096、堆配置 49,152、 峰值 1184 全是合法数字),门禁会被无视。改为"只报历史快照里出现过、当前已变的区域值"后 误报 0、真问题全中。宁可窄而准,不可宽而吵。

4.3 豁免机制

check_doc_links.py 的豁免(不算失效,不报错):

  • `[计划] ` 前缀标记
  • 该行含 [示例] 标记(引用报错样例 / 日志片段等含路径的引文)
  • 引用附近 ±40 字符内出现「未创建 / 尚未创建 / 已删除 / 待排期」等状态词
  • 含通配符 *、尖括号 <模块> 等占位符
  • 模板变量样式(NN_ / XX_ / 界面名 / 模块名 / ${...} / %s 等)
  • 行内代码 span 里的链接写法
  • 外部 URL(http/https/mailto)与纯锚点(#...)
  • docs/芯片手册/ 等外部资料目录

⚠️ 状态词按就近(±40 字符)判定,不是整行——否则文件名本身含「不存在」「删除」等字样时会误豁免同行的其它真实引用(2026-09-25 实测修正)。


5. 文档结构

5.1 必备要素

要素 要求
一级标题 文档首行为 # 标题,标题即主题,不写"文档""说明"等冗余后缀
开篇引言 可选 > 引用块,写明适用对象 / 阅读前提 / 相关文档
章节编号 多章节文档用 ## 1. ### 1.1 编号,便于交叉引用(§3.2)
变更记录 设计类、流程类文档建议末尾保留「变更记录」表(日期 | 变更 | 说明)

5.2 新增文档检查清单

新增一篇文档时逐项确认:

  • 放在正确的子目录(目录名无空格)
  • 文件名符合命名约定(无空格 / 主题词+类型后缀)
  • UTF-8 无 BOM、LF 换行
  • 互链用仓库根相对路径;图片用当前目录相对路径
  • 尚未创建/已删除的引用加 [计划] 或状态词
  • 已在 README.md 对应章节登记一行(否则视为未完成)
  • 若涉及任务表/栈,跑 gen_task_table.py --check
  • pre-commit run --files <新文档> 通过

6. 与代码文档的边界

内容 归属
项目级铁律、构建/烧录/测试命令、平台约束 AGENTS.md(AI 协作上下文,精简优先)
开发者入门、架构速览、目录导航 README.md
详细设计、专项说明、测试指南 docs/ 下对应子目录
跨文档待办登记 docs/待处理内容.md(统一登记簿)
评审报告与专项审计 docs/问题记录/

避免重复:同一事实只在一处详述,其它位置用链接指向。典型如 FreeRTOS 任务表——Src/freertos.c 是唯一事实源,README.md/AGENTS.md 的表由脚本生成,不在别处再抄一份。


7. 写作约定

项 约定
语气 陈述事实,不用"我们认为""大家注意"等口语
标点 中文正文用全角标点;代码、路径、命令、文件名用行内代码 `...`
术语 首次出现给全称 + 缩写(如"配置引擎(cfg_file)"),此后统一用同一术语
表格 对比、清单、参数优先用表格而非长段落
命令 用 powershell 代码块,含 & '.venv\Scripts\python.exe' 等本仓库统一入口
图 拓扑类用 Mermaid 代码块;技术配图走 SVG 生成器(见 架构设计/图形绘制流程.md)
状态标记 ✅ 已完成 / ⚠️ 注意事项 / ❌ 禁止 / 📌 要点(克制使用,不滥用 emoji)

8. 常见错误速查

现象 原因 修复
doc-links 报失效链接 文件被移动/删除后引用未同步 改引用路径,或加 [计划] / 状态词
doc-links 报语法示例行 链接示例没包反引号 把示例包进 `
task-table 报不一致 freertos.c 改栈后文档未同步 跑 gen_task_table.py --write
提交 diff 出现整文件行尾变化 脚本改写时强制了 LF/CRLF 改写须按原换行符回写(见 §2)
图片不显示 文档迁入子目录后未改 ../images/ 补 ../(见 §3.2)
引用"计划中"文件被拦 没加 [计划] 前缀 加前缀

变更记录

日期 变更 说明
2026-09-25 建立本文档 正式确立目录/命名/编码/链接/门禁/结构与写作约定;承接 D-6(去空格)与 D-7(一致性门禁),配套交付 scripts/check_doc_links.py、scripts/gen_task_table.py 两个门禁脚本与 doc-links/task-table 两个 pre-commit 钩子
2026-09-25 文件名风格统一(D-6 剩余) 代码规范/嵌入式C语言代码规范(V1.0).md → 嵌入式C语言代码规范_V1.0.md(全角括号 → 下划线),同步 5 个文档 + 1 个脚本共 9 处引用;§1.2 明确禁用全角括号与版本号写法;docs/芯片手册/ 作为外部资料例外
2026-09-26 体积档门禁落地(D-7 第三档) 交付 scripts/check_mem_numbers.py + pre-commit mem-numbers 钩子;§4.2 增「受管区域(锚点)」与「陈旧数字扫描」两节,记录误报取舍