a91640dc6e
前置来自 #57 SNTP 调研:旧 net_sendto / net_recvfrom 由调用方直调 SPI 且无限自旋收包,既违约「netTask 是芯片唯一访问者」,又把 IWDG 预算吃在自旋里。 改造面 - 新增 Drivers/BSP/NET/net_udp.c/.h(真机专属,模拟器不编译): bind/set_peer/sendto/recvfrom 四条执行体 + 挂起收包表 + tick; net_msg_type_t 加四型,公开 API 一律「入队 → 睡在通知上」。 - 源地址出参不搭 net_msg_t(按值拷贝,AGENTS 禁加回传字段):改住 net_udp.c 的 per-fd 槽,netTask 就地写回调用方内存,通知值只带 结果码;每条出口都清槽,泄漏 = 该 fd 永久 BUSY。 - 发送复用 net_send_locked,不写第二份分块逻辑;「会话是否已死」 收成一条判据 net_send_state_down()(TCP 看 ESTABLISHED、UDP 看 UDP_OPEN),原先 4 处各写一遍。 - 顺带修掉真缺陷(新条 TRAP-NET-22):旧 sendto 把 DesIP 写成具体 IP,芯片静默切 UDP Client,而旧 recvfrom 无条件剥 8 字节 → SNTP 这类 48 B 应答丢载荷前 8 字节并交出垃圾源地址。加 udp_mode(塞进 原有 padding,sizeof 不变)、bind 恒 SERVER、显式对端 sendto 切 CLIENT、set_peer(fd, NULL) 轻量回 SERVER,仅 SERVER 且 avail >= 8 才剥头。 - 截断定案:一次调用交付一个数据报,buf 装不下的尾巴用 64 B 栈上 scratch 排空(不用 clear_recv_buf——它连后面已到达的包一起丢)。 - 取消点接齐:net_init 重建 cancel_all、net_socket 分配 fd clear、 net_close settle_close + clear、重 bind 前先结算等包者, net_process_messages 第 5 个 tick 位挂 net_udp_tick。 - 收紧两处契约(原实现无生产调用者):UDP 未 bind 一律 -5; net_recv / _nb / _to 拒 DGRAM(绕过剥头就是静默吃 8 字节); NET_ERR_NOT_IN_NETTASK(-12) 退役为历史常量并写明原因。 验证 - 主机单测 test/host/net_socket 全套 616/616 绿(改造前 470):新 分片 ns_s7_udp.c 20 组,改写 440 / 555 / 560 组;覆盖率 net_udp.c 234/236(99.2%)、net_socket.c 956/969(98.7%), scripts/test_coverage_baseline.json 随本提交登记新文件。 - 测试抓到 4 个被测码真 bug:自等守卫误用调用侧谓词、芯片长度被读 两次、槽指针取在 fd 合法性检查之前、重 bind 静默作废等待者。 - Keil ARMCC 0 Error(s) 0 Warning(s);net_udp.o Code 1,358 / ZI 224 (8 fd × 28 B,其余模块零增长),全仓 RW_IRAM1 72.2%;内存台账 受管区按门禁提示用 --write / --update 机器回填,未手改数字。 - pre-commit 全量钩子(含 doc-links、coding-standard、mem-budget、 generated-fresh、bsp-err、registration、nested-comment)全绿。 限度 - 本轮无板子:真机回归 5 条(两端互通、set_peer(NULL) 能否恢复收 广播、截断排空后下一包完整性、挂起 recv 期间 IWDG 余量、bind 写 DesIP 与 open 先后的真芯片效果)已写进覆盖率口径「台架必验」。 - scripts/stack_report.py 退出码 1 是 10-26 起挂在账上的 iec104Task 栈债(margin 1,016 < 1,024,见 docs/代码规范/pre-commit使用说明.md: 122);本轮只让 net_bind 的 UDP 分支多一层静态帧(1,544 → 1,600), netTask margin 1,888 与 timeSyncTask 1,152 不受影响。抬栈要过 mem-budget 台账,不在本分支自行处理。 - 登记簿销项按仓库约定留给主工作树,本分支不动 docs/任务规划/**。
11 KiB
11 KiB
RAM 预算台账(配额 · 趋势 · 门禁)
定位:
docs/内存管理/RAM使用分析与优化方案.md§8.2 模板与 内存治理三件套的落地件(2026-10-12,登记簿条目「缩堆迁 CCM 后半(暂缓)」的已落地前半)。 回答三个问题:每个子系统还能用多少 RAM(配额)、总量趋势往哪走(基线 TSV)、 超了怎么拦(92% 门禁)。数字不手抄:下方受管区由
scripts/ram_baseline.py --write从.map生成, pre-commitmem-budget钩子校验一致性(同mem-numbers的"事实源唯一"思路)。 配额是规划值,本文件 §2 是配额与阈值的唯一权威(2026-09 体系评审提出、2026-10-12 落地后报告侧条目已销项),改动 = 先登记本文件 §6 变更记录,再改ram_baseline.py的QUOTAS。 区域放置与 DMA 可达性规则 →内存内容分配策略.md(本文件不重复)。
1. 区域预算与门禁(受管区)
| 区域 | 用量 | 容量 | 占比 | 门禁(≤92%) |
|---|---|---|---|---|
| ER_IROM1 (Flash) | 278,948 B | 1,048,576 B | 26.6% | 参考 |
| RW_CCM | 57,376 B | 65,280 B | 87.9% | PASS |
| UNINIT_CCM | 48 B | 256 B | 18.8% | 参考 |
| RW_IRAM1 | 94,624 B | 131,072 B | 72.2% | PASS |
| 子系统(静态 RW+ZI;除 RTOS 堆在 CCM 外均在 SRAM1) | 现值 | 配额 | 状态 |
|---|---|---|---|
| 网络 | 13,958 B | 12 KB | ⚠ 超 1.6 KB |
| 存储 | 7,072 B | 12 KB | OK |
| UI | 36,473 B | 16 KB | ⚠ 超 19.6 KB |
| RTOS 堆 | 57,376 B | 56 KB | 堆=配额 |
| 应用 | 26,333 B | 8 KB | ⚠ 超 17.7 KB |
| 其它 | 10,780 B | — | 参考 |
- 门禁: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早于最新源码(忘/keil-build)。 - 子系统归集为参考值:按对象名前缀归集(口径见 §2),合计与区域总量可差几十字节
(链接器填充行与
UNINIT_CCM等小区分段所致);区域行才是门禁事实源。
2. 子系统配额口径
配额值(ram_baseline.py 的 QUOTAS,本文件即唯一权威;
RTOS 堆 2026-10-12 保护任务 扩容 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/ 其余——前缀清单以 scripts/ram_baseline.py 的 subsystem_of() 为准:adc_* tpafe* sd2506 prot_* protect_task phasor sample_ring wave_* meas freq run_par iec104* soe_* cfg_* sys_* dbg_* console_log time_sync* sys_clock task_watchdog sha256 default_task test_task task_prof boot_stats vol_idle_sync |
App/task/ui_task*(首匹配算 UI) |
| 其它 | 内核对象、HAL、CMSIS、启动文件、C 库、链接器填充——不含 App/ 任何对象:漏登记会被 --gate 的兜底 WARN 逐条点名(2026-10-29 加) |
— |
现状判读(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 保护任务 由 48 KB 扩容,见 §6;heap_4.o另含 32 B 元数据,不计超);改堆 = 改配额,必须先过本文件 §6 登记。 - 应用 ⚠ 超配额(现值见 §1 受管区):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。 同日修正归集口径:subsystem_of()此前没有wave_iec104*soe_measfreqrun_par等前缀,12 个App/对象 9,445 B 被静默算进「其它」(当时「应用」行只有 16,888 B,看着离配额不远); 补齐后本行才真含录波环wave_ring.o(约 5.3 KB)。per-file 全貌 →docs/内存管理/内存内容分配策略.md§6。
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 保护任务 扩容 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)→ ② docs/内存管理/RAM使用分析与优化方案.md §4.2.2(阶段 2 第 2 项"缩堆"),再腾 24 KB;⚠ 2026-10-12 保护任务 反向扩容至 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)
- 每次
/keil-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 同步) |
保护任务 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 栈收口:保护定值持久化把 defaultTask 静态链推到 3016 B(余 1080 < 30% 线)、timeSyncTask 链 1264 B(余 784 < ISR 底线 1024);台架复测背书 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 |
| 2026-10-29 | 归集口径修正(非配额改动):subsystem_of() 补 wave_ iec104* soe_* meas freq run_par protect_task task_prof boot_stats vol_idle_sync 等前缀——12 个 App/ 对象 9,445 B 此前静默落「其它」;「应用」16,888 → 26,333 B、「其它」15,849 → 6,404 B,区域水位与 92% 红线均未变。同脚本加兜底:App/**/*.c 的对象落进「其它」时 --gate 逐条 WARN(不拦) |
配额表看不见录波/SOE 支路;口径依据本文件 §2「应用 = App/ 其余」 |