docs(部署): 删任务栈副本表改指针;纠 CCM/FPU 事实并刷新配图基线

范围:AGENTS.md 一处指针、部署环境要求 §2.2/§3.1/§3.3、RAM 方案 6 处现状
数字、内存配图生成器 + 3 张 SVG、两份报告脚本的行尾与路径修正、新增两份
.map/.htm 数据快照。未改任何 .c/.h(仍跑 @build 复核:0 错误 0 警告)。

部署环境要求.md
- §3.3 删"任务栈预算"副本表、改为指针:该表已缺 adcTask/iec104Task/
  protectTask,defaultTask/timeSyncTask 两值停在旧数,注释却写"由
  gen_task_table.py 同源"——该钩子的校验面只有 README.md / AGENTS.md
  两处受管块,抄出来的副本没有门禁、改栈后必漂。指针指向 Src/freertos.c
  + 两份受管表 + RAM 方案 §2.3/§0.6,并留一条"别再抄"的成因说明。
- §2.2 链接布局补 `RW_CCM 0x10000000`(scatter 给 0x0000FF00 = 65,280 B,
  2026-10-11 起承载 FreeRTOS 堆;另有 256 B UNINIT_CCM 尾区),写明 CCM
  不可 DMA。原文"SRAM3/CCM 故意未映射"与 STM32F407-Demo.sct 直接矛盾。
- §3.1 MCU 行更正为**单精度 FPU(VFPv4-SP,无硬件双精度)、无 TrustZone**
  (原写"双精度 FPU / TrustZone"是芯片事实错误,也正是报告 F-6 双精度软
  浮点被长期误判的土壤);SRAM 行改为"两块都在用,仅 SRAM3 未映射"。
- §3.3 资源预算表补 CCM 行,并把"主 SRAM 125,104 B / 95.4% / 极度紧张"
  更正为 75,264 B / 57.4%(余 55,808 B);红线改标在 CCM(余 7,904 B)。
- 变更记录补 2026-10-22 行(含上一提交里的资源表刷新那一笔)。

AGENTS.md:任务表注里 "RAM使用分析与优化方案.md §1.4" 是**指错小节**——§1.4 确实
存在(该文档 §4「方案」下的阶段 1 子项,讲 lftpd 大局部缓冲静态化),但栈余量
台账在 §2.3(任务栈配置与实测峰值)与 §0.6(静态最坏链与判定),故改指这两处
再加 内存内容分配策略.md §6。根因是该文档里 §1(背景)与 §4 下的 1.1~1.5 同号
撞面,人和 doc-links(自引用放过)都会看错——本会话我上一轮就被它带错过一次。

配图与数据(draw-diagram 流程:改生成器顶部数据 → 重跑 → 逐文本核越界)
- 新增 data/ram_report_20261022.md、data/stack_report_20261022.md;后者
  运行时水位取自 2026-10-22 真机 [STACK] 心跳(8 任务高水位 + heap
  free=15,800 / min_ever=8,464),静态侧来自同日 .htm(全局最深链 3,024 B)。
- gen_memory_svg.py:三组图数据从 2026-09-21 / 10-10 快照换成 2026-10-22
  实测;任务栈 6 → 9 行,堆总量 48KB → 56KB,判定 6/6 → 9/9 PASS,新增
  AboveNormal 配色;Flash 子条改为"窄段不压字 + 下方四列图例";任务栈
  画布 440 → 620 高。CCM 段总量按 scatter 用 65,280 B(与台账同口径)。
- 三张 SVG 重生成;用"CJK≈1.0em / 其余≈0.58em + 锚点"逐文本估算边界,
  修掉 5 处文字越界/压字(生成器内置 ElementTree 自检亦通过)。
- ram_report.py / stack_report.py 两处工具性修正:write_text 未指定 newline
  参数 → Windows 下把 data/ 快照写成 CRLF(与 .gitattributes 及既有快照
  不符);stack_report 的 relative_to 在传相对 -i 时抛 ValueError,且会把
  本机绝对路径写进入库快照 → 统一走 resolve+relative_to 的相对路径回退。

RAM 方案:6 处"当前状态"随 .map/[STACK] 更正——RW_IRAM1 89,168 → 75,264、
RW_CCM 49,184 → 57,376、FreeRTOS 堆 48KB → 56KB(两处)、CCM 余量 ~16KB →
7,904 B、min_ever 4,848 → 8,464 B、6 任务全过 → 9/9 PASS;S-1 历史句保留。

门禁:pre-commit 对全部改动文件 Passed(doc-links --sections-strict、
task-table、mem-numbers、mem-budget、id-check 增量拦截);字节卫生自查
BOM / CR / U+FFFD / 行尾空格全清。已提交本地,未推送。
This commit is contained in:
2026-10-22 12:09:54 +08:00
parent d4867ddbe2
commit f4b9bd57d5
11 changed files with 606 additions and 191 deletions
+3 -1
View File
@@ -365,7 +365,9 @@ def main():
if args.output:
pathlib.Path(args.output).parent.mkdir(parents=True, exist_ok=True)
pathlib.Path(args.output).write_text(report, encoding="utf-8")
# newline="\n":Windows 下 write_text 默认把 \n 翻成 \r\n,会跟 .gitattributes
# (* text=auto eol=lf)与 data/ 目录既有快照的行尾不一致(2026-10-22 实测)。
pathlib.Path(args.output).write_text(report, encoding="utf-8", newline="\n")
print(f"OK: Report written to {args.output}", file=sys.stderr)
else:
print(report)
+12 -3
View File
@@ -176,12 +176,20 @@ def main():
add = out.append
add('# Stack budget report')
add('')
add(f'- Source: `{html_path.relative_to(REPO_ROOT)}` (Keil static call graph)')
# 显示用相对路径:传相对 -i 时 relative_to 会抛 ValueError(2026-10-22 实测踩到),
# 且绝不把本机绝对路径写进入库的 data/ 快照。
def _disp(pth):
try:
return pathlib.Path(pth).resolve().relative_to(REPO_ROOT)
except (ValueError, OSError):
return pathlib.Path(pth).name
add(f'- Source: `{_disp(html_path)}` (Keil static call graph)')
if meta["updated"]:
add(f'- Linker run: {meta["updated"]}')
add(f'- Global maximum stack usage: **{meta["max_stack"]} B** (any call tree)')
if runtime:
add(f'- Runtime watermark: {len(runtime)} task(s) from `{args.serial}`')
add(f'- Runtime watermark: {len(runtime)} task(s) from 串口采集日志 `{_disp(args.serial)}`')
add('')
add('Rule: `margin = cfg - max(static_max_depth, runtime_peak)` must be '
f'>= max({args.isr_margin} B ISR, {args.min_free_pct}% of cfg).')
@@ -252,7 +260,8 @@ def main():
report = '\n'.join(out)
if args.output:
pathlib.Path(args.output).write_text(report, encoding='utf-8')
# newline="\n":避免 Windows 换行翻译污染 data/ 快照的 LF 行尾(与 .gitattributes 一致)。
pathlib.Path(args.output).write_text(report, encoding='utf-8', newline='\n')
print(f'written: {args.output}')
else:
print(report)