d64bbdc57f
数据面(App/algo,纯逻辑,双端编译) - wave_ring:8 路 × 320 点列优先环(1 kHz,预触发 160 + 后触发 160),adcTask 唯一写者;触发/冻结/封存/冷却四态,冻结持续到落盘回执才解冻,滞留 2 s 自弃 兜底——下一次真故障无波可录比丢一段更贵 - wave_store:段头编解码 + 拉模式打包游标 + 自带无表位运算 CRC-16/MODBUS(带 锚点自检)+ 段名与整段长度等式;格式不依赖平台类型宽度 - 段头只存原始码值与封存瞬间生效系数,工程量只当单位标签、不进任何算式 - 三套主机单测(环 113 / 编解码 170 / 触发状态机 110),全部无桩、生产源原样 纳入;新文件补 stddef 是 ARMCC 与主机差异,主机侧照不出这条分叉 - test/host/wave_read.py 是按 §6.2 的独立第二实现(dump/fft/shape/plot),92 条 自洽断言;三份合成段互读双校验全过、哈希钉死,格式面双向闭合 - 三套新单测不加专属钩子,由覆盖率总闸全量真跑(沿用既有裁定) 接线(任务层) - adc_cal:新增生效系数的 32 位定点原值入口(与既有浮点入口共用生效视图), 段头按最低有效位精确记账,不经浮点回算 - adcTask:每拍压 8 路语义原始码值并推进状态机,封存那一拍同拍交棒封存瞬间事实; 台架定周期自抓走双层编译门,产品镜像里零存在;串口新增一条 wave: 周期行 - defaultTask:卷空闲后一次心跳整段搬完(try 锁 + 256 字节分片 + 一次完整开档到 关档),成败都回执;失败先删半成品再计错,段号只在成功时推进;持锁超 50 ms 补一条告警并记历史峰值(喂狗余量可核) - Lead 复核补第四道并发陷阱:采集任务优先级高于落盘道,搬段中途它可能正好把滞留 超时的本段自弃、甚至封出下一段——数据区校验和是对「实际读到的字节」算的, 半新半旧的段照样自洽,故关档后复检环侧身份判废:删文件、不补账、段号不推进 - Lead 复核抓到触发挂号不是原子操作(旧实现分三个字节写,消费者可在窗口里读到 上一段的触发源与元件号):已把载荷压进一个字节,越界当场拒且不记任何计数; 段文件字节布局零改动,三份合成段哈希逐字节不变 - protectTask:保护启动上升沿同点请求录波,一拍一次、元件号取最低位;判据本体 零改动 人机(160×160 单色屏) - 菜单树节点 26「手动录波」绑页面 + 记录查询组末新增「录波回放」叶,重跑生成器 得 43 节点 / 34 叶 / 30 已绑,页面映射 28 → 30 - 回放页一屏一路、触发点前后各一周波共 40 点、每点 3 像素阶梯线(只用水平与 垂直两种线段——单色屏斜线会被阈值裁掉);零点虚线、触发光标、窗口峰值、 单位徽标与形状受限徽标;空态与坏段各一句显式文案,绝不用半截波形冒充数据 - ui_data 新增录波注入通道(六件操作表、三态返回);执行侧胶水带段头缓存、 手动请求后连缓存一起作废、逐点走全仓唯一的码值换算入口 - 模拟器接真实环与编解码合成两段(含坏段与空态旗标),6 张新黄金参考,既有 60 张逐字节零漂移未用更新模式;字库 218 → 224 字 / 319 字形 - 两份图形配置里图表组件仍为关;零堆分配;页面池水位不变 - 回放读路径的 uiTask 阻塞上界按实码写清:一次渲染 = 段表刷新 + 未缓存段头最坏 22 次小读;已验段只剩一次开窗读 + 40 点解码;无实测数不编,实测归台架、 仪器用已在跑的单轮工作耗时探针,不新加埋点 台账与文档 - 内存台账:录波环与落盘/回放静态逐条入册,三档对照 81,536 → 88,296 → 89,936 字节(62.2% → 68.6%),累计 +8,400;预估 5.9 KB 与实测 +6,760 的差额点名; 散列文件头注释同步;任务栈表核对后无需抬栈;体积趋势行与同码凭证由权威构建 重打(0 错误 0 警告,四项体积与上一轮相同——本轮改动只有注释与声明位置) - 设计说明:§5 补第四条并发陷阱;§6.3 定字段口径(两份独立实现的共同依据); §7 回填实测;§9 周期行写实;§10 台架判据改两段式且不比绝对相位;§12 补读路径 风险行;抬头状态改成「代码面已交付、未做完的只有板级那一轮」 - 卡片:软件闭环一栏列证据;台架三条按用户裁定保持未完成,不做虚假销项 - 口径同步:数据可信、UI 补齐、页面补齐规划、产品需求、采集短板评测、任务规划 索引与两份 README;陈旧现状句清扫 16 处(带日期戳的历史取数行一律不动) - 门禁说明:nested-comment 记仓库根探测必须兼容 linked worktree 的 gitdir 文件 形态(修前该钩子在任务树里恒报环境错、静默不可用);coding-standard 记 「函数头注释超过 24 行就把函数功能挤出回看窗口」这条机制与本次现场 - 覆盖率基线登记两个新覆盖模块(套件 41 → 44 套);环单测重打后该文件有效行 227 → 226、覆盖行 226 → 225,比率仍 99.6%,是分母变小不是覆盖率回退 为什么是单一提交:文档链接、双端注册、生成器幂等(菜单与字库)、内存数字与 体积事实源、编号门禁这五道整仓门禁要求代码、页面、菜单树、字库、文档与台账 同处一个提交才自洽,按数据面/接线/人机/台账拆成四笔必然红其中至少四道 编号门禁新增行 14 处命中已按语义改写:魔数常量按字符命名、段名样例改由格式串 生成、频谱表头改 f / 2x / 5x 并加一行图例;改写后自洽断言 92 条仍全过
102 lines
9.7 KiB
Markdown
102 lines
9.7 KiB
Markdown
# RAM 预算台账(配额 · 趋势 · 门禁)
|
||
|
||
> **定位**:`docs/内存管理/RAM使用分析与优化方案.md` §8.2 模板与
|
||
> 内存治理三件套的**落地件**(2026-10-12,登记簿条目「缩堆迁 CCM 后半(暂缓)」的已落地前半)。
|
||
> 回答三个问题:**每个子系统还能用多少 RAM**(配额)、**总量趋势往哪走**(基线 TSV)、
|
||
> **超了怎么拦**(92% 门禁)。
|
||
>
|
||
> **数字不手抄**:下方受管区由 `scripts/ram_baseline.py --write` 从 `.map` 生成,
|
||
> pre-commit `mem-budget` 钩子校验一致性(同 `mem-numbers` 的"事实源唯一"思路)。
|
||
> 配额是**规划值**,**本文件 §2 是配额与阈值的唯一权威**(2026-09 体系评审提出、2026-10-12 落地后报告侧条目已销项),改动 = 先登记本文件 §6 变更记录,再改 `ram_baseline.py` 的 `QUOTAS`。
|
||
> 区域放置与 DMA 可达性规则 → `内存内容分配策略.md`(本文件不重复)。
|
||
|
||
## 1. 区域预算与门禁(受管区)
|
||
|
||
<!-- MEM_BUDGET:BEGIN generated by scripts/ram_baseline.py -->
|
||
| 区域 | 用量 | 容量 | 占比 | 门禁(≤92%) |
|
||
|---|---|---|---|---|
|
||
| ER_IROM1 (Flash) | 272,336 B | 1,048,576 B | 26.0% | 参考 |
|
||
| RW_CCM | 57,376 B | 65,280 B | 87.9% | PASS |
|
||
| UNINIT_CCM | 48 B | 256 B | 18.8% | 参考 |
|
||
| RW_IRAM1 | 89,936 B | 131,072 B | 68.6% | PASS |
|
||
|
||
| 子系统(静态 RW+ZI;除 RTOS 堆在 CCM 外均在 SRAM1) | 现值 | 配额 | 状态 |
|
||
|---|---|---|---|
|
||
| 网络 | 13,702 B | 12 KB | ⚠ 超 1.4 KB |
|
||
| 存储 | 7,072 B | 12 KB | OK |
|
||
| UI | 36,428 B | 16 KB | ⚠ 超 19.6 KB |
|
||
| RTOS 堆 | 57,376 B | 56 KB | 堆=配额 |
|
||
| 应用 | 16,888 B | 8 KB | ⚠ 超 8.5 KB |
|
||
| 其它 | 15,849 B | — | 参考 |
|
||
<!-- MEM_BUDGET:END -->
|
||
|
||
- **门禁**:pre-commit `mem-budget` 钩子(`scripts/ram_baseline.py --gate`)——
|
||
RW_IRAM1 / RW_CCM 任一 >92% 即拦提交,并打印 Top-10 RW+ZI 对象定位增量;
|
||
无 `.map` 时自适应跳过(CI 侧跳过 `mem-numbers` 的边界 = `scripts/check_size_gate.py` 的 docstring,唯一正文)。
|
||
- **阈值依据**:92% 由 2026-09 体系评审提出、2026-10-12 落地为门禁(提出时的报告条目已随销项删除,闭环说明见 `RAM使用分析与优化方案.md` §4 阶段 3「长效机制」与本文)——留 ~8% 给突发缓冲与栈抬升,
|
||
触线即触发排期,而不是静默逼近溢出。
|
||
- **软提醒**(不拦提交):tsv 末行落后于 `.map`(忘跑 `--update`)、`.map` 早于最新源码(忘 `@build`)。
|
||
- **子系统归集为参考值**:按对象名前缀归集(口径见 §2),合计与区域总量可差几十字节
|
||
(链接器填充行与 `UNINIT_CCM` 等小区分段所致);区域行才是门禁事实源。
|
||
|
||
## 2. 子系统配额口径
|
||
|
||
配额值(`ram_baseline.py` 的 `QUOTAS`,**本文件即唯一权威**;
|
||
RTOS 堆 2026-10-12 B5 扩容 48→56 KB 见 §6):**网络 12 KB / 存储 12 KB /
|
||
UI 16 KB / RTOS 堆 56 KB / 应用 8 KB**。归集口径(按 `.map` 对象名,首匹配):
|
||
|
||
| 子系统 | 计入对象(前缀/精确名) | 不计入 |
|
||
|---|---|---|
|
||
| 网络 | `ch395f*` `net_*` `lftpd*` `ftp_task*` | `ui_net_sink`(算 UI) |
|
||
| 存储 | `gd5f*` `nand_*` `ff*` `diskio*` `vol_lock*` + dhara 裸名(`map/journal/nand/fctl/era.o`) | `cfg_*`(算应用) |
|
||
| UI | `lv_*` `ui_*`(含 `ui_net_sink`、`ui_task`) | — |
|
||
| RTOS 堆 | `heap_4.o`(CCM)——配额 = `configTOTAL_HEAP_SIZE` 本身 | 内核对象(`tasks/queue/timers/...` 归"其它") |
|
||
| 应用 | `App/` 其余:采集 `adc_*`、保护 `prot_*`、相量 `phasor/sample_ring`、配置 `cfg_*`、日志 `sys_/dbg_/console_log`、对时 `time_sync*`、`sys_clock`、`task_watchdog`、`sha256`、`tpafe*`、`sd2506`、`default_task` 等 | — |
|
||
| 其它 | 内核对象、HAL、CMSIS、启动文件、C 库、链接器填充 | — |
|
||
|
||
**现状判读(2026-10-12 建档)**:
|
||
|
||
- **UI ⚠ 超配额 = 已知长期挂账,不是新增违规**:LVGL 池 16 KB(2026-10-15 落地,由 40 KB 收缩)+
|
||
帧/远显缓冲 ≈12.8 KB,实测 30,412 B。配额 16 KB 描述的是 **把 UI 侧缓冲迁进 CCM 之后的目标态**,
|
||
而 **该搬迁的后半已按用户裁定 2026-10-15 整簇暂缓**(`docs/任务规划/登记簿.md` §5 保留重启条件)→
|
||
**这条 ⚠ 会长期挂着**,判读时按已知挂账处理,别每轮当新问题追;重开条件 → `RAM使用分析与优化方案.md` §4。
|
||
- **RTOS 堆 = 配额本身**:56 KB 即 `configTOTAL_HEAP_SIZE`(2026-10-12 B5 由 48 KB 扩容,见 §6;
|
||
`heap_4.o` 另含 32 B 元数据,不计超);**改堆 = 改配额**,必须先过本文件 §6 登记。
|
||
- **应用 ⚠ 小幅超**:8 KB 为报告规划值;2026-10-10 栈整改把 3 处 `FIL` 从栈搬进 BSS
|
||
(静态 +4,128 B,见 `docs/内存管理/RAM使用分析与优化方案.md` §4"2026-10-10 复测")——
|
||
属已评审的"以空间换栈安全",差额在此如实体现。2026-10-29 故障录波落盘道又把 `default_task.o`
|
||
推高 1,204 B(该行现值 16,888 B);**录波环本体 5,300 B 不计入本行**——`subsystem_of()`
|
||
没有 `wave_` 前缀,它落在「其它」,要读全貌看 `docs/内存管理/内存内容分配策略.md` §6 的 per-file 台账。
|
||
|
||
## 3. CCM 分配台账(谁能用 CCM)
|
||
|
||
| 项 | 值 | 说明 |
|
||
|---|---|---|
|
||
| CCM 容量 | `RW_CCM` Max 见受管区 | scatter `RW_CCM`;**仅 CPU 可达,DMA 不可达**(RM0090 §3.1.1) |
|
||
| 现占用 | 仅 FreeRTOS 堆 `heap_4`(56 KB,2026-09-21 迁入;2026-10-12 B5 扩容 48→56 KB) | 其余候选全部仍在 SRAM1 |
|
||
| 现余量 | 受管区 RW_CCM 容量 − 占用 = **7,904 B** | **不够** 迁 CCM 后半的 UI 侧待迁体量(缩池后 **29,570 B**)——⏸ 该搬迁已暂缓,见下行 |
|
||
| 迁 CCM 后半解锁链 | ⏸ **整簇暂缓(用户裁定 2026-10-15)**,本行保留作重开时的现状基线:① **缩池 ✅ 2026-10-15**:`LV_MEM_SIZE` 40→16 KB → 待迁体量 54,146 → **29,570 B**(SRAM1 74.9% → **56.1%**,实测池峰值 6,568 B)→ ② ~~现在卡在这一步~~:堆 56→32 KB(`docs/内存管理/RAM使用分析与优化方案.md` §4.2.2(阶段 2 第 2 项"缩堆"),再腾 24 KB;⚠ 2026-10-12 B5 反向扩容至 56 KB——9 任务栈 + 队列实测需要,缩回 32 KB 前必须重跑 `stack_report.py` + 上板 min_ever 复测)→ ③ CCM 余 ≈31.9 KB ≥ 29,570 B → 迁入 | **暂缓期间不启动**;重开条件 → `RAM使用分析与优化方案.md` §4。**若重开,顺序不可颠倒**;每步前后跑 `stack_report.py` / `ram_report.py`(铁律) |
|
||
| 迁入前置 | 目标缓冲必须过 DMA 可达性清单(`内存内容分配策略.md`) | 违例 = 静默传错(越界不校验的同类坑);克隆芯片 CCM 可靠性风险见 `docs/内存管理/RAM使用分析与优化方案.md` §7 |
|
||
|
||
## 4. 趋势基线(`scripts/ram_baseline.tsv`)
|
||
|
||
- **每次 `@build` 后**:`& '.venv\Scripts\python.exe' scripts/ram_baseline.py --update`
|
||
追加一行(Code/RO/RW/ZI + 三区水位 + Top-10 RW+ZI 对象;同日重跑覆盖当日行)。
|
||
- **看趋势 / 找增量**:`scripts/ram_baseline.py --trend`——高亮较上一行 RW+ZI 增长 >1 KB 的对象,
|
||
即 `docs/内存管理/RAM使用分析与优化方案.md` §4.0.3 "ZI 增量 >1KB 必须在提交说明中解释"的机械化;提交说明直接抄 `--trend` 输出行。
|
||
|
||
## 5. 超配额流程
|
||
|
||
新增/扩大静态缓冲导致子系统越过配额:**先登记再动手**——本文件 §6 加一行
|
||
(日期 / 子系统 / 现值→新值 / 原因 / 决定人),提交说明引用该行。
|
||
92% 门禁拦的是**总量**,配额管的是**结构**(谁挤占了谁),两者不可互替。
|
||
|
||
## 6. 变更记录
|
||
|
||
| 日期 | 变更 | 原因 / 出处 |
|
||
|---|---|---|
|
||
| 2026-10-12 | 建档:三件套落地(本台账 + `scripts/ram_baseline.py` + `scripts/ram_baseline.tsv` + pre-commit `mem-budget` 钩子) | 登记簿 N-27 前半 |
|
||
| 2026-10-12 | **RTOS 堆配额 48 KB → 56 KB**(`QUOTAS` 同步) | B5 protectTask 立项:iec104Task(2.5KB)+protectTask(2KB)+TCB 入堆后 48KB 池 min_ever 预估跌破 3,072 B 告警线 → `.ioc` 语义取数与有效性参数 `configTOTAL_HEAP_SIZE` 49152→57344(CCM 水位 75.3%→87.9%,仍 <92% 门禁;CCM 空闲降至 ≈8 KB)。连带影响见 §3 迁 CCM 后半链注记 |
|
||
| 2026-10-12 | **任务栈 +1536 B(堆内用量,配额 56 KB 不变)**:defaultTask 1024→1280 words(+1024 B)、timeSyncTask 512→640 words(+512 B);产品任务栈合计 37,632→39,168 B | 登记簿 N-33 栈收口:B7 定值持久化把 defaultTask 静态链推到 3016 B(余 1080 < 30% 线)、timeSyncTask 链 1264 B(余 784 < ISR 底线 1024);B6 台架背书 min_ever=10000 → 抬后实测 `heap free=16400 / min_ever=8464`(与预算 −1536 完全吻合,>3072 告警线);`stack_report` 9 任务 0 FAIL + `@test` PASS,见 `RAM使用分析与优化方案.md` §1.4 |
|
||
| 2026-10-29 | **故障录波数据面入册**:新增对象 `wave_ring.o` 5,300 B(ZI 5,256 + RW 44,落 SRAM1、CCM 增量 0);`default_task.o` 静态 2,736 → 3,940 B(+1,204 B,落盘道 `FIL` 528 + 分片缓冲 256 + 段头副本 136 + 段路径 17 + 打包上下文与 `DIR`/`FILINFO`);`RW_IRAM1` 81,536 → 89,936 B(62.2 % → 68.6 %,仍远低于 92 % 门禁);`RW_CCM` 三档恒 57,376 B | 决定人 lead。实测数字出自 lead 的权威构建(本工作树 `MDK-ARM/STM32F407-Demo/STM32F407-Demo.map`,0 错误 0 警告,`scripts/ram_baseline.py --update` 同批入 tsv);预估约 5.9 KB vs 实测数据面 +6,760 B 的差额构成与三档对照见 `docs/内存管理/内存内容分配策略.md` §6;**未抬栈**(`scripts/stack_report.py` 九任务全 PASS),判据出处 `docs/子系统设计/故障录波设计说明.md` §7 |
|