From 0779d3a075cf8149cdc014113f1cca2cfc0a8315 Mon Sep 17 00:00:00 2001
From: Wanderingss <1624155937@qq.com>
Date: Sat, 10 Oct 2026 10:17:00 +0800
Subject: [PATCH] =?UTF-8?q?=E6=A0=88=E6=95=B4=E6=94=B9=E4=B8=8D=E6=8A=AC?=
=?UTF-8?q?=E6=A0=88=EF=BC=9A=E5=88=A0=E6=97=A7=E6=A1=A3=E8=BF=81=E7=A7=BB?=
=?UTF-8?q?=E3=80=81FIL=E9=9D=99=E6=80=81=E5=8C=96=E3=80=81=E6=97=A5?=
=?UTF-8?q?=E5=BF=97=E8=A1=8C=E7=BC=93=E5=86=B2=E6=8C=89=E6=A8=A1=E5=9D=97?=
=?UTF-8?q?=E6=94=B6=E7=B4=A7=E3=80=81=E9=92=A9=E5=AD=90=E8=84=B1=E7=A6=BB?=
=?UTF-8?q?HAL=EF=BC=8CdefaultTask=E9=93=BE5312=E2=86=922776B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.cubemx_survival_baseline.json | 2 +-
AGENTS.md | 7 +-
App/README.md | 2 +-
App/cfg/README.md | 7 +-
App/cfg/cfg_file.c | 4 +
App/cfg/cfg_file_store.h | 4 +-
App/cfg/cfg_file_store_mcu.c | 24 +-
App/log/console_log.c | 74 +-
App/log/console_log.h | 6 +
App/log/sys_log_mcu.c | 11 +-
App/sync/time_sync.c | 3 +
App/task/default_task.c | 15 +-
App/util/README.md | 5 +-
Drivers/BSP/CH395F/ch395f.c | 5 +
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c | 4 +
Drivers/BSP/GD5F2GQ5UE/nand_ftl.c | 5 +
Drivers/BSP/NET/net_socket.c | 4 +
Drivers/BSP/NETCFG/README.md | 11 +-
Drivers/BSP/NETCFG/net_cfg.c | 19 +-
Drivers/BSP/NETCFG/net_cfg.h | 5 +-
Drivers/BSP/NETCFG/net_cfg_legacy.c | 125 -
Drivers/BSP/NETCFG/net_cfg_legacy.h | 35 -
Drivers/BSP/README.md | 2 +-
Drivers/BSP/dbg_log.h | 83 +-
MDK-ARM/STM32F407-Demo.uvprojx | 5 -
README.md | 2 +-
Src/freertos.c | 39 +-
docs/README.md | 2 +-
docs/images/任务栈预算.svg | 28 +-
docs/images/引用关系图.dot | 21 +-
docs/images/引用关系图.json | 191 +-
docs/images/引用关系图.svg | 3518 ++++++++++---------
docs/images/引用关系图_模块.dot | 14 +-
docs/images/引用关系图_模块.svg | 1096 +++---
docs/产品需求/产品需求设计文档.md | 11 +-
docs/内存管理/RAM使用分析与优化方案.md | 91 +-
docs/内存管理/data/ram_report_20261010.md | 197 ++
docs/内存管理/data/stack_report_20261010.md | 79 +
docs/子系统设计/控制台单写者日志设计说明.md | 19 +-
docs/子系统设计/网络配置说明.md | 25 +-
docs/子系统设计/运行与自检记录设计说明.md | 2 +-
docs/子系统设计/配置文件设计说明.md | 48 +-
docs/待处理内容.md | 36 +-
docs/架构设计/项目启动顺序管理.md | 2 +-
docs/架构设计/项目架构总览.md | 5 +-
docs/测试说明/测试开发标准流程.md | 3 +-
docs/环境与部署/项目部署环境要求.md | 18 +-
simulator/CMakeLists.txt | 1 -
simulator/README.md | 18 +-
simulator/main.c | 7 +-
simulator/sim/cfg_file_store_sim.c | 12 +-
simulator/tests/check_content_pages.py | 1 +
test/host/cfg_file/cfg_file_test.c | 2 -
tools/arch_diagram/gen_memory_svg.py | 18 +-
54 files changed, 3203 insertions(+), 2770 deletions(-)
delete mode 100644 Drivers/BSP/NETCFG/net_cfg_legacy.c
delete mode 100644 Drivers/BSP/NETCFG/net_cfg_legacy.h
create mode 100644 docs/内存管理/data/ram_report_20261010.md
create mode 100644 docs/内存管理/data/stack_report_20261010.md
diff --git a/.cubemx_survival_baseline.json b/.cubemx_survival_baseline.json
index a611a387..44c3a82f 100644
--- a/.cubemx_survival_baseline.json
+++ b/.cubemx_survival_baseline.json
@@ -8,7 +8,7 @@
"stack-overflow-check": "d4735e3a265e16ee",
"malloc-failed-hook": "6b86b273ff34fce1",
"assert-not-deadloop": "d4a00718ab2bd071",
- "assert-impl": "908de37a05c944ce",
+ "assert-impl": "5d862ceb21c77a86",
"stack-overflow-hook-impl": "a006edbd30d2c4d7",
"malloc-failed-hook-impl": "fcd7250e5cd6403b",
"stack-overflow-hook-helper": "cacd9fd028be9b5b",
diff --git a/AGENTS.md b/AGENTS.md
index 87d8623a..7914a3c2 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -55,7 +55,8 @@ STM32F407ZGTx @168MHz(HSE 8MHz → PLL M=4/N=168/P=2);**仅 Keil MDK-ARM v
- **FatFs 文件名约束(2026-09-20 台架实证,`.fschk` 无限重格式化事故根因)**:本移植 `Lib/FatFs/ffconf.h` 为 `FF_USE_LFN=0`,**只支持严格 8.3 短名**——主名≤8 字符、扩展≤3 字符、**不得以点开头**(`.fschk` 会被 `ff.c create_short` 把点后当扩展域解析超限 → `f_open` 恒返 `FR_INVALID_NAME`(6),纯 RAM 名字判定、不碰盘)。ff.c `create_short` 全部拒绝点已加 DEBUG 打印:`[ERR][FATFS] SFN reject (原因) seg='名字片段' bad_ch=坏字符`,非法名字调用看开机日志即可定位。自愈类逻辑**严禁**把名字/参数类错误码(`FR_INVALID_NAME` 等)归入卷损坏触发集(整卷重格式化不可逆)
- **ADC 取数只用 `tpafe5160_snapshot()`(原子快照)**(2026-10-10 修 E-44/E-45/E-58):旧的 `get_buf()` / `data_ready()` / `clear_ready()` 已从驱动**删除**——`get_buf` 只给缓冲区指针、任务再逐通道拷,两步之间被 BUSY EXTI 抢占并跨过一帧周期就拷回**两帧混合**数据(8 通道失去同一时刻性,且无错误指示);`s_ready` 电平标志有三个写者,`start_conv_irq` 触发前清 0 = **重触发本身就会抹掉一帧未消费数据**。现口径:帧序号只增不清(`tpafe5160_frame_seq()`)、取数=临界区内拷贝(`tpafe5160_snapshot(dst, count)` 返回 1/0/-1,**仅任务上下文**)、FRSTDATA 全程无跳变(芯片不驱动并行总线)由 `tpafe5160_frstdata_err()` 计数且 `tpafe5160_init()` 首帧自检直接返回 `-3` + `[ERR]`
- **接 ADC / RS-485 消费者前的强制门禁(E-59,2026-10-10 固化)**:`adc_task` / `rs485_task` 从空桩转为真实消费者**之前**必须确认——① 驱动契约已修:TPAFE **E-44 / E-45 / E-58 已修 ✅**、RS485 **E-36 / E-37 已修 ✅** 但 **E-50(单缓冲无同步 → 包撕裂)未修 ❌**、**E-49(TX 超时拉 DE)未修 ❌**;② 栈预算:两任务**尚未入 `Src/freertos.c` 栈表**,建任务前后各跑一次 `scripts/stack_report.py`。与"改栈前跑 `stack_report.py`"同级。另按 N-18:V0.1 上两片转换器之间**禁止**做相位/功率/功率因数类运算
-- **`DBG_*` 每条日志约 90 B Flash + 192 B 栈**(2026-10-02 S10 实测):`dbg_log.h` 的 `DBG_INFO/ERROR/DEBUG` 在**每个调用点内联** `char __con_line[DBG_CON_LINE_MAX]`(`console_log.h` 定义 **192 B**)+ 完整 `snprintf` 调用序列 → 单条约 **90 B Flash**(字符串常量另计)。给新模块接入日志时按"条数 × 90 B"估算 Flash 代价(实测 `sd2506_init` 加 6 条 = +576 B;`app_main` 加 3 条 = +180 B);**深调用链模块另需核算栈**(每条日志在栈上多占 192 B,会进 `stack_report.py` 的最坏链)。故**日志不是免费的**——已覆盖的步骤不要再加"进入前/完成后"重复锚点,只在真正黑洞(原先静默返回)处补
+- **`DBG_*` 每条日志约 90 B Flash + 216 B 栈**(2026-10-02 S10 实测;2026-10-10 修正栈量):`dbg_log.h` 的 `DBG_INFO/ERROR/DEBUG` 在**每个调用点内联**行缓冲 `char __con_line[DBG_LINE_BUF_MAX]`(默认 = `console_log.h` 的 `DBG_CON_LINE_MAX` **192 B**)+ 时间戳缓冲 **24 B**(已并入同一数组,原为独立 32 B)+ 完整 `snprintf` 调用序列 → 单条约 **90 B Flash**(字符串常量另计)。给新模块接入日志时按"条数 × 90 B"估算 Flash 代价(实测 `sd2506_init` 加 6 条 = +576 B;`app_main` 加 3 条 = +180 B);**深调用链模块另需核算栈**——每条日志在栈上多占一份行缓冲、会进 `stack_report.py` 的最坏链:实测 defaultTask 那条链上 9 个帧各含一份 → **约 1.5 KB 纯粹是日志行缓冲**(2026-10-10 把该链 5312 → 2776 B 的主要杠杆之一)。故**日志不是免费的**——已覆盖的步骤不要再加"进入前/完成后"重复锚点,只在真正黑洞(原先静默返回)处补
+- **深调用链模块收紧日志行缓冲:`#define DBG_LINE_BUF_MAX 128U`,写在 `#include "dbg_log.h"` 之前**(2026-10-10 加)。已收紧:`nand_ftl.c`/`gd5f2gq5ue.c`/`cfg_file.c`/`net_cfg.c`/`net_socket.c`/`ch395f.c`/`time_sync.c`/`default_task.c`。⚠ **取值必须 ≥ 该模块最长日志行**(时间戳 20 + 标签 + 正文),否则该行被截断——各文件注释已写出实测行长。改前/改后各跑一次 `stack_report.py`
| Task | 栈 (words) | 优先级 |
@@ -77,7 +78,7 @@ STM32F407ZGTx @168MHz(HSE 8MHz → PLL M=4/N=168/P=2);**仅 Keil MDK-ARM v
- `app_main_init`(时间子系统优先,使后续日志带时间戳):`sd2506_init` → `sys_clock_init`(墙钟;RTC 故障时降级默认时间基准并返回 -1 触发"时钟芯片异常"自检;`sys_clock_get` 每 30 天惰性再基准化防 49.7 天 tick 回绕)→ `rs485_init` → `gd5f2gq5ue_init` → `tpafe5160_init` → SD2506 诊断 → `tpafe5160_start_conv_irq`
- **就绪屏障**(`App/app/sys_events.h` Event Flags,取代魔法延时):`SYS_EVT_NET_READY`(netTask 置位)/ `STORAGE_READY`(defaultTask:卷挂载 + 网络配置加载完成)/ `FTP_READY` / `TIMESYNC_READY`;消费者用 `osEventFlagsWait` 阻塞等待
- netTask:`net_stack_bring_up`(配置已由 defaultTask 在屏障前加载,本任务只读 RAM 副本 → `net_init` + PHY 强制 100M 全双工 → 递增网络代次号)→ 置 NET_READY → 循环 `net_poll` + `net_process_messages`;消费 `SYS_EVT_NET_RECONFIG` → 立即重建网络(新 IP 免重启生效,各 TCP 服务据代次号重建监听)
-- defaultTask:`f_mount` forced(无卷自动 `f_mkfs` FAT32;挂载后卷健康探针:小写两击确认,FAT 区陈旧/擦除时自动重格式化自愈,`/config.ini` 回落工厂默认——2026-09-20 /log 写失败修复)→ 网络配置加载(`net_cfg_load`,首启含旧档迁移)→ STORAGE_READY → LED 闪烁;同时是 syslog(`/log/run.log`·`selftest.log`,定长 64B 记录)的**唯一写者**与**配置引擎属主**(`cfg_file` 静态态单任务收敛于此:UI 保存请求执行 `net_cfg_save_run` + 2s `cfg_file_poll`,经 `SYS_EVT_CFG_SAVE` 事件唤醒;netTask/uiTask 不得直接触碰配置引擎,见 P1-3)
+- defaultTask:`f_mount` forced(无卷自动 `f_mkfs` FAT32;挂载后卷健康探针:小写两击确认,FAT 区陈旧/擦除时自动重格式化自愈,`/config.ini` 回落工厂默认——2026-09-20 /log 写失败修复)→ 网络配置加载(`net_cfg_load`;旧档迁移已于 2026-10-10 删除,见「模块约定」网口配置条)→ STORAGE_READY → LED 闪烁;同时是 syslog(`/log/run.log`·`selftest.log`,定长 64B 记录)的**唯一写者**与**配置引擎属主**(`cfg_file` 静态态单任务收敛于此:UI 保存请求执行 `net_cfg_save_run` + 2s `cfg_file_poll`,经 `SYS_EVT_CFG_SAVE` 事件唤醒;netTask/uiTask 不得直接触碰配置引擎,见 P1-3)
- 全景 `docs/架构设计/项目架构总览.md`(六层分层 / 启动时序 / 存储·网络·UI 栈 / 目录组织)
## 硬件引脚
@@ -99,7 +100,7 @@ STM32F407ZGTx @168MHz(HSE 8MHz → PLL M=4/N=168/P=2);**仅 Keil MDK-ARM v
- 所有 `net_*` socket 操作经 `netMsgQueue` 消息队列在 netTask 串行执行(线程安全);非 netTask 任务直接调 `net_*` API,勿直接碰 CH395F 驱动
- **`net_*` 公开 API 的错误码经"任务通知值"回传**(2026-09-21 实证):`net_msg_t` 是**按值拷入队列**的,netTask 改的是自己那份副本,调用方永远看不到 → 错误码搭 `xTaskNotify()` 通知值回来(失败=负的具体错误码如 `NET_ERR_WOULDBLOCK`、成功=字节数/描述符),公开 API 恢复 errno 后对外统一返回 -1。**勿给 `net_msg_t` 加"回传用"字段**(调用方只会读到栈垃圾;曾据此"修"错误码,导致 `ui_net_sink` 每次空轮询都误判为真错误 → 连上即 `net_close`)
- **单连接 socket 的断开语义**:监听 Socket 在 CONNECT 后自身即数据通道(`g_client == g_listen`),EOF 时 net 层已 `auto_relisten`;应用层**不得**在 EOF 时 `net_close` 该 fd(会连监听一起毁掉 → 端口"连接被拒"),仅当数据 fd ≠ 监听 fd(模拟器多连接后端)时才关
-- 网口配置:`/config.ini` [network] 段(工厂默认 192.168.1.100/24、gw .1;MAC 全零 = 芯片内置;UI 保存立即生效;旧档 `/cfg/netcfg.bin` 首启自动迁移)→ `docs/子系统设计/网络配置说明.md`
+- 网口配置:`/config.ini` [network] 段(工厂默认 192.168.1.100/24、gw .1;MAC 全零 = 芯片内置;UI 保存立即生效;**旧档 `/cfg/netcfg.bin` 迁移已于 2026-10-10 删除**——`net_cfg_legacy.c/h` 整体移除,旧档若存在则被忽略(不读/不删/不迁移)、配置回落工厂默认;删除理由 = 该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏链 +600 B,且本仓库无携带旧档的设备)→ `docs/子系统设计/网络配置说明.md`
- **新 .c 文件必须手动注册到两处**才能双端编译:`MDK-ARM/STM32F407-Demo.uvprojx` + `simulator/CMakeLists.txt`(用 `new-source-file` skill)
- **`MDK-ARM/*.uvprojx` 每次 `@build` 后被 Keil UV4 自动改写,改动一律不入库**(2026-09-29 实测):UV4 构建时会把工程 XML 归一化成它本机风格的旧式写法(`` → ``、XML 声明加 `standalone="no"`),并把 `PackID` 降到**本机装的 DFP 版本**(本机实测 `3.1.1` → `3.0.0`,属**降级**)。这些差异是环境相关的,提交后会把别人的 Pack 版本也一起改掉。**判断方法**:`git diff MDK-ARM/STM32F407-Demo.uvprojx` 里若只见 XML 格式/`PackID` 差异而**无源文件挂载增删** → `git checkout -- MDK-ARM/STM32F407-Demo.uvprojx` 丢弃。只有真的新增/删除源文件(`grep 文件名` 计数变化)才提交
- 测试构建:`test/board/test_config.h` 的 `TEST_SUITE_CH395F/STORAGE/GD5F/RTC` **互斥**(一次只能启用一个,`#error`);全部注释 = 产品构建;**该开关受 pre-commit 钩子 `test-suite-switch` 门禁**(默认要求产品构建,跑完套件回归须改回;确需提交测试构建用 `ALLOW_TEST_BUILD=1` 显式放行——2026-10-01 实测已提交 HEAD 里 `TEST_SUITE_CH395F` 长期开启,纯靠人记得改,故补此门禁);**破坏性用例默认关闭**:同文件 `ENABLE_DESTRUCTIVE_TESTS`(默认注释)控制写/擦 NAND、格式化、坏块注入与 FatFS 写类用例——关闭时套件为**只读模式**(开机横幅 `mode: READ-ONLY`,可随时在在用设备上跑、不动卷内容与容量),只在**产品首次上电/产线首启**或明确需要时打开(`mode: DESTRUCTIVE`);2026-09-21 实测一轮破坏性 GD5F 运行即让 dhara 多记一个坏块(容量 95248 → 95200;该计数持久化在 dhara journal checkpoint 头里,普通恢复模式清不掉,需全片擦除——见 `docs/测试说明/存储维护与容量恢复.md`);CH395F 套件 `test/board/ch395f_test.h`:硬件层 Phase 1~5 与 NET 层 Phase 6~11 互斥;CH395F 硬件层模式下 netTask(基础线程:无条件创建、全构建唯一实例)入口自挂起(不运行),testTask 独占 CH395F
diff --git a/App/README.md b/App/README.md
index f2256772..9c925acc 100644
--- a/App/README.md
+++ b/App/README.md
@@ -14,7 +14,7 @@ FreeRTOS/CMSIS-RTOS API**(见 `AGENTS.md`「平台约束」)。
| 目录 | 内容 | README |
|---|---|---|
| `app/` | **应用入口与全局**:`app_main.c/h`(初始化入口)、`app_cfg.h`(编译开关)、`sys_events.h`(就绪事件) | [`app/README.md`](app/README.md) |
-| `cfg/` | **配置引擎**:`/config.ini` 解析 + 持久化 + 旧档迁移 | [`cfg/README.md`](cfg/README.md) |
+| `cfg/` | **配置引擎**:`/config.ini` 解析 + 原子持久化(旧二进制档已废弃,2026-10-10) | [`cfg/README.md`](cfg/README.md) |
| `sync/` | **时间同步任务**:`time_sync.c/h` | [`sync/README.md`](sync/README.md) |
| `log/` | **日志子系统**:syslog(NAND)+ 控制台单写者日志 | [`log/README.md`](log/README.md) |
| `task/` | **FreeRTOS 任务实现**(6 个任务) | [`task/README.md`](task/README.md) |
diff --git a/App/cfg/README.md b/App/cfg/README.md
index 472949de..f09a590c 100644
--- a/App/cfg/README.md
+++ b/App/cfg/README.md
@@ -1,6 +1,6 @@
# App/cfg/ — 配置引擎
-> **`/config.ini` 配置引擎**:分层解析、持久化(原子写)、旧档迁移。
+> **`/config.ini` 配置引擎**:分层解析、持久化(原子写)。
> 属主 = **defaultTask**(单任务收敛,静态态);其它任务不得直接触碰。
## 文件一览
@@ -18,10 +18,11 @@
- **零分配共享核心**:核心逻辑不含任何分配符号,动态内存收进平台后端
(`cfg_store_alloc/free`:MCU→`pvPortMalloc`,模拟器→宿主堆)
- **原子写**:写 `/config.TMP` 后 `f_rename` 替换,避免掉电损坏
-- **旧档迁移**:首启时把旧格式转换为当前格式(`net_cfg_legacy.c` 负责网络段)
+- **旧档迁移已删除(2026-10-10)**:旧格式 `/cfg/netcfg.bin` 不再读取——存在则被忽略(不读、
+ 不删、不迁移),配置回落工厂默认;`net_cfg_legacy.c/h` 与 `cfg_store_legacy_path()` 已移除
- **自研代码禁用 C 库堆分配**:MicroLIB 堆仅 512B(`malloc` 必返回 NULL)
## 相关文档
-- `docs/子系统设计/配置文件设计说明.md` — 完整设计(分层/解析/持久化/迁移)
+- `docs/子系统设计/配置文件设计说明.md` — 完整设计(分层/解析/持久化)
- `docs/子系统设计/网络配置说明.md` — 网络段
diff --git a/App/cfg/cfg_file.c b/App/cfg/cfg_file.c
index 47bec098..2b88c51a 100644
--- a/App/cfg/cfg_file.c
+++ b/App/cfg/cfg_file.c
@@ -41,6 +41,10 @@
#include "sys_log.h" /* 配置读写失败上报自检记录(双端共享接口,MCU 端 preboot/队列安全) */
+/* 深调用链模块(配置引擎在 defaultTask 启动链与保存链上,下接 FatFS → FTL):
+ * 日志行缓冲收到 128 B(默认 192)。本模块最长行 "load: file %luB > %uB, corrupt,
+ * factory template regenerated" 渲染后 ≈ 91 B(含时间戳 21 + 标签)< 128 → 不截断 */
+#define DBG_LINE_BUF_MAX 128U
#define DBG_TAG "[CFG]"
#include "dbg_log.h"
diff --git a/App/cfg/cfg_file_store.h b/App/cfg/cfg_file_store.h
index 23c2784f..8fc9ad9c 100644
--- a/App/cfg/cfg_file_store.h
+++ b/App/cfg/cfg_file_store.h
@@ -103,8 +103,8 @@ const char *cfg_store_config_path(void);
/* 函数功能:取配置文件临时文件路径(write_atomic 内部用) */
const char *cfg_store_tmp_path(void);
-/* 函数功能:取旧版配置遗留文件路径(net_cfg_legacy 迁移用) */
-const char *cfg_store_legacy_path(void);
+/* 注:旧版遗留档 getter `cfg_store_legacy_path()` 已于 2026-10-10 随旧档迁移
+ * net_cfg_legacy 一并删除(旧格式 /cfg/netcfg.bin 不再兼容、不再读取) */
#ifdef __cplusplus
}
diff --git a/App/cfg/cfg_file_store_mcu.c b/App/cfg/cfg_file_store_mcu.c
index 9d80fe41..b908fdd4 100644
--- a/App/cfg/cfg_file_store_mcu.c
+++ b/App/cfg/cfg_file_store_mcu.c
@@ -2,7 +2,7 @@
* 模块名称:cfg_file_store (MCU 后端)
* 模块功能:cfg_file 存储后端——NAND 上 FatFS 文件 /config.ini(卷根,8.3 合规);
* 原子写 = 临时文件 config.TMP(与目标同目录)+ f_rename;mtime 变更令牌 =
- * (fdate << 16) | fmtime;旧版遗留文件 /cfg/netcfg.bin 供迁移读取
+ * (fdate << 16) | fmtime
* 适用平台:STM32F407ZGTx
* 作者:王建锋
* 创建日期:2026-09-14
@@ -37,7 +37,6 @@
static const char s_path[] = "/config.ini";
static const char s_path_tmp[] = "/config.TMP";
-static const char s_path_legacy[] = "/cfg/netcfg.bin";
/* 函数定义区 */
@@ -49,9 +48,14 @@ static const char s_path_legacy[] = "/cfg/netcfg.bin";
* p_nread - 实际读字节数输出(不可为 NULL) size_t *
* 返回值:0 - 成功;-1 - 文件缺失/读失败 int
* 限定条件:卷已挂载(未挂载时 f_open 返回 FR_NO_SYSTEM,转 -1)
+ * 函数说明:FIL 为**函数级 static**而非局部——本 FatFs 移植 FF_FS_TINY=0,
+ * `FIL` 内含 `buf[FF_MAX_SS]`=512 B(Lib/FatFs/ff.h),一个局部对象就吃掉
+ * 528 B 栈,是配置/syslog 调用链栈深的主要来源(2026-10-10 栈预算整改)。
+ * 安全性:整个 FIL 生命周期都在 `vol_lock_wait()/release()` 区间内,
+ * 跨任务访问被卷锁串行化,且本函数不递归、不嵌套自身
*/
int cfg_store_read(const char *p_path, uint8_t *p_buf, size_t cap, size_t *p_nread) {
- FIL f;
+ static FIL f; /* static:省 528 B 栈;卷锁内串行使用 */
FRESULT fr;
UINT br = 0u;
@@ -116,9 +120,11 @@ static int s_build_tmp_path(const char *p_path, char *p_out, size_t cap) {
* len - 数据长度 size_t
* 返回值:0 - 成功;-1 - 写/改名失败(目标文件保持不动,临时文件清理) int
* 限定条件:卷已挂载;中途失败(含掉电)不损坏目标文件
+ * 函数说明:`FIL` 用函数级 static 而非局部(FF_FS_TINY=0 → 单个 FIL = 528 B 栈);
+ * 与 cfg_store_read 各持自己的 static 对象,互不共享,且全程在卷锁区间内
*/
int cfg_store_write_atomic(const char *p_path, const uint8_t *p_buf, size_t len) {
- FIL f;
+ static FIL f; /* static:省 528 B 栈;卷锁内串行使用 */
FRESULT fr;
UINT bw = 0u;
char tmp_path[CFG_STORE_TMP_PATH_MAX];
@@ -233,14 +239,10 @@ const char *cfg_store_tmp_path(void) {
}
/*
- * 函数功能:取旧版配置遗留文件路径
- * 入口参数:无
- * 返回值:"/cfg/netcfg.bin"(旧 NCFG 二进制格式) const char *
- * 限定条件:无
+ * 旧版遗留文件 /cfg/netcfg.bin 的路径 getter(cfg_store_legacy_path)已于
+ * 2026-10-10 随旧档迁移 net_cfg_legacy 一并删除:无调用者即无必要保留
+ * (留着"看起来还支持旧档"的入口会误导后续维护)
*/
-const char *cfg_store_legacy_path(void) {
- return s_path_legacy;
-}
/*
* 函数功能:分配共享核心临时缓冲(FreeRTOS 堆)
diff --git a/App/log/console_log.c b/App/log/console_log.c
index 46aa582c..5be43742 100644
--- a/App/log/console_log.c
+++ b/App/log/console_log.c
@@ -36,7 +36,9 @@
#include "task.h"
#include "cmsis_os.h"
#include "sys_events.h"
-#include "sys_log.h"
+/* 刻意不 include "sys_log.h":日志子系统不得回调本模块(调用图成环 →
+ * armlink 静态栈深在每个任务上虚高,见 dbg_console_drain 故障路径注释)。
+ * TX 故障留痕改由写者任务在 drain 之外补记 */
/* ===== 控制台单写者日志(2026-09-24 加固,HardFault 定位结论驱动)=====
* 背景:旧路径 DBG_* → printf → fputc **每字符一次** HAL_UART_Transmit。HAL 的锁只保证
@@ -66,6 +68,17 @@
* IWDG 误复位(round 8a 台架现场)。改用 DWT CYCCNT(内核硬件周期计数,不依赖任何
* 中断/uwTick)做判据;DWT 使能失败时退回 HAL_UART_Transmit(旧行为,功能不退化)。 */
#define CON_TX_TIMEOUT_CYC (SystemCoreClock / 10U) /* 发送硬上界 = 100ms 对应周期数 */
+/*
+ * DWT 不可用时的**指令计数**上界(替代 HAL_UART_Transmit 回退,2026-10-10)。
+ * 为什么不再回退 HAL:① HAL_UART_Transmit 的超时判据是 HAL_GetTick——断言/停摆
+ * 现场 tick 未必在走,等待无上界;② 它的调用链 `HAL_UART_Transmit →
+ * UART_WaitOnFlagUntilTimeout` 会被 armlink 挂进**每个**碰日志的任务的最坏链
+ * (configASSERT 在 FreeRTOS 内部可达 → 三个内核钩子都在链尾),实测每条链多背
+ * 64 B 栈。计数上界同样有界、零外部依赖。
+ * 取值:115200 bps 下一字节 87 µs;轮询循环 ~5 周期 → 每字节约 3000 次迭代,
+ * 取 20000 留 6 倍余量(单字节卡死最多数毫秒级即放弃,不无限自旋)
+ */
+#define CON_TX_GUARD_MAX 20000u
#define CON_APPEND_WAIT_CYC (SystemCoreClock / 5U) /* 缓冲满等待硬上界 = 200ms 对应周期数 */
static uint8_t s_con_ring[DBG_CON_RING_SIZE];
@@ -73,6 +86,7 @@ static volatile uint16_t s_con_head; /* 生产者写入位置 */
static volatile uint16_t s_con_tail; /* 写者读取位置 */
static volatile uint32_t s_con_drop; /* 因缓冲满丢弃的行数 */
static volatile uint32_t s_con_tx_fault; /* TX 失败(僵尸通道)次数,均经外设软复位自愈 */
+static volatile uint8_t s_con_tx_fault_log; /* TX 故障留痕待上报(由写者任务在 drain 之外补记 run.log) */
static volatile uint32_t s_con_cool_until; /* 故障冷却截止 tick(0 = 无冷却) */
static volatile uint8_t s_con_draining; /* 1 = 处于 drain 中(重入保护) */
static volatile uint8_t s_con_writer_up; /* 1 = 写者已注册(此后走环形缓冲) */
@@ -109,13 +123,45 @@ static void con_dwt_ensure(void) {
}
}
+/*
+ * 函数功能:DWT 不可用时的计数上界发送(每字节/TC 各数 CON_TX_GUARD_MAX 次)
+ * 入口参数:u - USART 寄存器基址(调用方已判非 NULL) USART_TypeDef *
+ * p_buf - 待发数据;len - 字节数
+ * 返回值:HAL_OK - 已发出;HAL_TIMEOUT - 计数上界内未完成(本块放弃)
+ * 限定条件:USART1 已初始化
+ * 函数说明:刻意不用 HAL_UART_Transmit——理由见 CON_TX_GUARD_MAX 处注释
+ * (tick 依赖不可信 + 其调用链污染所有任务的最坏栈链)
+ */
+static HAL_StatusTypeDef con_tx_counted(USART_TypeDef *u, const uint8_t *p_buf, uint16_t len) {
+ uint32_t guard;
+ uint16_t i;
+
+ for (i = 0U; i < len; i++) {
+ guard = 0U;
+ while ((u->SR & USART_SR_TXE) == 0U) {
+ if (++guard >= CON_TX_GUARD_MAX) {
+ return HAL_TIMEOUT;
+ }
+ }
+ u->DR = (uint16_t)p_buf[i];
+ }
+ guard = 0U;
+ while ((u->SR & USART_SR_TC) == 0U) {
+ if (++guard >= CON_TX_GUARD_MAX) {
+ return HAL_TIMEOUT;
+ }
+ }
+ return HAL_OK;
+}
+
/*
* 函数功能:有界裸发送(不依赖 uwTick / HAL 超时)
* 入口参数:p_buf - 待发数据;len - 字节数(调用方已限 ≤ DBG_CON_CHUNK_MAX)
* 返回值:HAL_OK - 已全部写入发送寄存器;HAL_TIMEOUT - 有界上界内未完成
* 限定条件:USART1 已初始化
* 函数说明:寄存器级轮询 TXE/TC,超时判据用 DWT CYCCNT(CON_TX_TIMEOUT_CYC);
- * DWT 未使能时退回 HAL_UART_Transmit(旧行为)。本函数只做 TX,
+ * DWT 未使能时走 con_tx_counted(指令计数上界,2026-10-10 取代
+ * HAL_UART_Transmit 回退)。本函数只做 TX,
* 不触碰 RX/错误标志——僵尸通道自愈由调用方按返回值处理。
* ⚠ USART1 未初始化(huart1.Instance == NULL,如 HAL_Init 早期或
* 断言/故障上报路径)时立即返回 HAL_ERROR:否则会解引用 NULL 去读写
@@ -131,7 +177,7 @@ static HAL_StatusTypeDef con_tx_bounded(const uint8_t *p_buf, uint16_t len) {
return HAL_ERROR; /* USART1 未初始化:无可用通道,安全让位 */
}
if (s_con_dwt_up == 0U) {
- return HAL_UART_Transmit(&huart1, (uint8_t *)p_buf, len, DBG_CON_TX_TIMEOUT_MS);
+ return con_tx_counted(huart1.Instance, p_buf, len);
}
u = huart1.Instance;
@@ -254,7 +300,14 @@ void dbg_console_drain(void) {
if (s_con_tx_fault == 1U) {
static const char note[] = "\r\n[WARN] CONSOLE tx fault: UART reinit (self-healed)\r\n";
- syslog_post(SYSLOG_RUN, "console tx fault, uart reinit"); /* 仅 run.log,不入自检判定 */
+ /* 刻意**不在这里**调 syslog_post():syslog_post → dbg_console_write_line
+ * → con_append → dbg_console_drain 会与本函数构成**调用图成环**。运行时
+ * 有 s_con_draining 重入标志挡着,不会真递归;但 armlink 静态调用图会把
+ * 整条日志尾巴在每个任务的最坏链上多叠一层(实测 6 个任务的最坏链末尾
+ * 全是这个环)→ 栈深数字虚高、真实风险反而被掩盖。
+ * 改法:只置标志,由写者任务(defaultTask 主循环,本就是 syslog 唯一
+ * 写者)在 drain **之外**补记 run.log(见 dbg_console_tx_fault_log_take) */
+ s_con_tx_fault_log = 1U;
(void)dbg_console_write_raw(note, (unsigned)sizeof(note) - 1U);
}
break; /* 故障即止:本轮 drain 到此为止,让位主循环 */
@@ -401,6 +454,19 @@ uint32_t dbg_console_tx_fault(void) {
return s_con_tx_fault;
}
+/*
+ * 函数功能:取走"控制台 TX 故障待上报"标志(读后清)
+ * 返回值:1 - 需要补记一条 run.log 证据,0 - 无
+ * 限定条件:**写者任务**(defaultTask)在 dbg_console_drain() 之外调用
+ * 函数说明:断调用图成环用,见 dbg_console_drain 故障路径注释
+ */
+uint8_t dbg_console_tx_fault_log_take(void) {
+ uint8_t pending = s_con_tx_fault_log;
+
+ s_con_tx_fault_log = 0U;
+ return pending;
+}
+
/*
* 函数功能:MicroLIB printf 底层重定向(库内部/遗留 printf 调用)
* 函数说明:同样只把字节交给单写者路径;未注册写者时直发(与旧行为一致)
diff --git a/App/log/console_log.h b/App/log/console_log.h
index e24eda62..dfde647e 100644
--- a/App/log/console_log.h
+++ b/App/log/console_log.h
@@ -37,6 +37,11 @@ extern "C" {
* dbg_console_drain - 写者任务排空缓冲并发送(单次有界;TX 失败自动软复位自愈)
* dbg_console_dropped - 因缓冲满丢弃的行数(诊断)
* dbg_console_tx_fault - 因僵尸通道软复位自愈的次数(诊断)
+ * dbg_console_tx_fault_log_take
+ * - 取走"TX 故障待上报"标志(读后清)。**必须**由写者任务在
+ * dbg_console_drain() 之外调用后自行 syslog_post——本模块
+ * 刻意不调日志子系统,否则形成 write_line→con_append→drain
+ * →syslog_post→write_line 调用图成环,静态栈深全线虚高
*/
#define DBG_CON_LINE_MAX 192U /* 单行文本上限(含结尾 '\0',超出截断) */
int dbg_console_write_line(const char *line, unsigned len);
@@ -45,6 +50,7 @@ void dbg_console_writer_attach(void);
void dbg_console_drain(void);
uint32_t dbg_console_dropped(void);
uint32_t dbg_console_tx_fault(void);
+uint8_t dbg_console_tx_fault_log_take(void);
/*
* 函数功能:MicroLIB printf 底层重定向(C 库 retarget 钩子,须为全局符号)
diff --git a/App/log/sys_log_mcu.c b/App/log/sys_log_mcu.c
index f6b883f9..701d99bc 100644
--- a/App/log/sys_log_mcu.c
+++ b/App/log/sys_log_mcu.c
@@ -67,7 +67,8 @@ static volatile uint8_t s_mount_fail_reported; /* P2-9:建目录失败日
* 限定条件:仅 defaultTask(唯一写者)调用;卷已挂载
*/
static int s_append(syslog_id_t id, const char *desc) {
- FIL f;
+ static FIL f; /* static:FF_FS_TINY=0 → 局部 FIL 吃 528 B 栈;
+ * 本函数全程在 vol_lock 区间内,跨任务被卷锁串行化 */
FRESULT fr;
UINT bw = 0u;
uint8_t rec[SYSLOG_REC_SIZE];
@@ -168,7 +169,8 @@ static int s_append(syslog_id_t id, const char *desc) {
* 心跳,绝不能阻塞等锁;busy = 本次读失败(UI 下轮刷新重读,非故障)。
*/
static int s_read_raw(syslog_id_t id, uint32_t idx, uint8_t *p_rec) {
- FIL f;
+ static FIL f; /* static:省 528 B 栈;open~close 全在卷锁区间内
+ * (uiTask 与写者任务由 vol_lock 串行化,见上方 P2-10 说明) */
FRESULT fr;
UINT br = 0u;
int rc;
@@ -439,11 +441,12 @@ int syslog_last_epoch(syslog_id_t id, uint32_t *p_epoch) {
* 容量护栏:> 8KB 先 unlink 重建,防长跑无界增长(8.3 合法名 wdev.log)。
*/
int sys_log_evidence(const char *p_desc) {
- FIL f;
+ static FIL f; /* static:省 528 B 栈(FF_FS_TINY=0 → FIL=528 B) */
+ static char line[192]; /* static:省 192 B 栈;本函数只有 poller(defaultTask)
+ * 一个调用者(task_wd_poll 内),且全程在卷锁区间内 */
FRESULT fr;
UINT bw = 0u;
UINT line_len;
- char line[192];
char ts[SYSLOG_TS_LEN + 1u];
int n;
int rc = 0;
diff --git a/App/sync/time_sync.c b/App/sync/time_sync.c
index 00ec840a..2dc95070 100644
--- a/App/sync/time_sync.c
+++ b/App/sync/time_sync.c
@@ -23,6 +23,9 @@
#include "sys_events.h"
#include "task_watchdog.h"
+/* 深调用链模块(timeSyncTask 栈仅 2048 B,本任务链 = 建监听 → net_bind → CH395F):
+ * 日志行缓冲收到 128 B(默认 192),本模块最长行渲染后 < 128 → 不截断 */
+#define DBG_LINE_BUF_MAX 128U
#define DBG_TAG "[TIME_SYNC]"
#include "dbg_log.h"
diff --git a/App/task/default_task.c b/App/task/default_task.c
index 0783e410..7c43fd60 100644
--- a/App/task/default_task.c
+++ b/App/task/default_task.c
@@ -33,6 +33,10 @@
#include "cfg_file.h"
#include "sys_log.h"
#include "sys_events.h"
+/* 深调用链模块(本任务 = 存储 bring-up + 配置引擎属主 + syslog 唯一写者,
+ * 全项目最深链在此):日志行缓冲收到 128 B(默认 192),本模块最长行渲染后
+ * < 128 → 不截断 */
+#define DBG_LINE_BUF_MAX 128U
#include "dbg_log.h"
#include "task_watchdog.h"
#include "vol_lock.h"
@@ -191,6 +195,12 @@ void default_task_func(void *argument) {
/* 控制台唯一发送点:把环形缓冲中的日志按块发出(无待发时立即返回) */
task_wd_seg(TASK_WD_SEG_DRAIN);
dbg_console_drain();
+ /* 控制台 TX 故障留痕:由本任务(syslog 唯一写者)在 drain **之外**补记 run.log。
+ * console_log 内部刻意不调 syslog_post —— 那会构成日志调用图成环,
+ * 让 armlink 静态栈深在每个任务上都多叠一条日志尾巴(见 console_log.c) */
+ if (dbg_console_tx_fault_log_take() != 0U) {
+ syslog_post(SYSLOG_RUN, "console tx fault, uart reinit");
+ }
/* 执行待处理保存(配置引擎属主:写盘 + 成功后立即应用);无请求 = 空操作 */
#if !defined(TEST_SUITE_STORAGE)
task_wd_seg(TASK_WD_SEG_CFGSAVE);
@@ -405,7 +415,8 @@ static FRESULT storage_bring_up(FATFS *fs) {
* 判定、不碰盘)→ 曾误入下方结构性错误集合 → 每 boot 假失败 →
* 无限重格式化。探针名必须严格 8.3:名≤8、扩展≤3、不以点开头。 */
#define FS_VOL_PROBE(h) do { \
- FIL __chk; \
+ static FIL __chk; /* static:FF_FS_TINY=0 → 局部 FIL 吃 528 B 栈;探针只在 \
+ * defaultTask 启动/自愈路径跑,无并发 */ \
static const uint8_t __chkbuf[8] = { 0 }; \
UINT __bw = 0u; \
FRESULT __wr; \
@@ -465,7 +476,7 @@ static FRESULT storage_bring_up(FATFS *fs) {
DBG_INFO("[FS] FATFS mounted");
/* 日志引擎挂载后处理:建 /log 目录 + 写"上电/重启"分类记录(唯一写者) */
syslog_mcu_mounted();
- /* 加载网络配置进 RAM 副本(配置引擎属主 = 本任务;首启含旧档迁移;
+ /* 加载网络配置进 RAM 副本(配置引擎属主 = 本任务;只读 INI,
* 文件缺失/损坏 = 工厂默认,不阻塞组网)。须在置位 STORAGE_READY 前,
* 使"存储就绪"屏障蕴含"配置已就绪",netTask 组网时配置恒有效 */
(void)net_cfg_load();
diff --git a/App/util/README.md b/App/util/README.md
index 27121d7c..93e94ac0 100644
--- a/App/util/README.md
+++ b/App/util/README.md
@@ -10,8 +10,9 @@
| `task_watchdog.c/h` | **独立看门狗(IWDG)判定状态机**:任务心跳位图 + defaultTask 单一喂狗者 |
> **已删除(2026-10-02)**:`crc.c/h`(CRC-16 Modbus / CRC-8)与 `ringbuf.c/h`(SPSC 环形缓冲)
-> 两模块**零调用者**且未编入任何构建——CRC 唯一使用点 `net_cfg_legacy.c` 自带静态
-> `s_crc16_modbus()`,环形缓冲由 `App/log/console_log.c` 内联实现(`s_con_ring`)。
+> 两模块**零调用者**且未编入任何构建——CRC 从未被链接使用:名义上的关联点 `net_cfg_legacy.c`
+> (旧档 `/cfg/netcfg.bin` 迁移,**该文件亦已于 2026-10-10 删除**)自带静态 `s_crc16_modbus()`,
+> 从不调用本模块;环形缓冲由 `App/log/console_log.c` 内联实现(`s_con_ring`)。
> 保留只会造成"有统一实现"的误导,故整体移除(详见 `docs/待处理内容.md` E-15 销项)。
## 设计要点
diff --git a/Drivers/BSP/CH395F/ch395f.c b/Drivers/BSP/CH395F/ch395f.c
index c98b7c00..31466ca1 100644
--- a/Drivers/BSP/CH395F/ch395f.c
+++ b/Drivers/BSP/CH395F/ch395f.c
@@ -24,7 +24,12 @@
/*
* 调试输出配置
+ * 深调用链模块(ch395f_spi_fault_set 等出现在 netTask/ftpTask/timeSyncTask
+ * 最坏链尾部):日志行缓冲收到 128 B(默认 192)。本模块最长行
+ * "HAL_SPI_TransmitReceive_DMA FAIL: %d, SPI_State=%d, SPI_Error=0x%lX, DMA_State=%d"
+ * 渲染后 ≈ 102 B(含时间戳 21 + 标签)< 128 → 不截断
*/
+#define DBG_LINE_BUF_MAX 128U
#define DBG_TAG "[CH395]"
#include "dbg_log.h"
diff --git a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c
index 6eaab887..5cc50fdd 100644
--- a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c
+++ b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c
@@ -16,7 +16,11 @@
/*
* 调试输出配置
+ * 深调用链模块(NAND 驱动在 FTL 之下):日志行缓冲收到 128 B(默认 192)。
+ * 本模块最长行 "ID mismatch: expected MID=0x.. DID=0x.., got MID=0x.. DID=0x.."
+ * 渲染后 ≈ 103 B(含时间戳 21 + 标签)< 128 → 不截断
*/
+#define DBG_LINE_BUF_MAX 128U
#define DBG_TAG "[NAND]"
#include "dbg_log.h"
diff --git a/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c b/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c
index a6e69d62..3fd4850b 100644
--- a/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c
+++ b/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c
@@ -26,6 +26,11 @@
#define FTL_FATFS_OFFSET 0U
/* 调试输出配置 */
+/* 深调用链模块(FatFS → 本 FTL → dhara → NAND 是 defaultTask 最坏链的主干):
+ * 日志行缓冲收到 128 B(默认 192)。本模块最长行 "[2026-10-10 08:00:00][ERR][NAND_FTL]
+ * Cache flush failed: LPN=4294967295 err=-2147483648" ≈ 84 B < 128 → 不截断。
+ * 核算 scripts/stack_report.py,见 docs/内存管理/RAM使用分析与优化方案.md */
+#define DBG_LINE_BUF_MAX 128U
#define DBG_TAG "[NAND_FTL]"
#include "dbg_log.h"
diff --git a/Drivers/BSP/NET/net_socket.c b/Drivers/BSP/NET/net_socket.c
index 9163b797..3eb63e9b 100644
--- a/Drivers/BSP/NET/net_socket.c
+++ b/Drivers/BSP/NET/net_socket.c
@@ -25,7 +25,11 @@
/*
* 调试输出配置
+ * 深调用链模块(net_bind/net_send/net_poll 是 netTask/ftpTask/timeSyncTask
+ * 最坏链的主干):日志行缓冲收到 128 B(默认 192)。本模块最长行渲染后
+ * ≈ 100 B(含时间戳 21 + 标签)< 128 → 不截断
*/
+#define DBG_LINE_BUF_MAX 128U
#define DBG_TAG "[NET]"
#include "dbg_log.h"
diff --git a/Drivers/BSP/NETCFG/README.md b/Drivers/BSP/NETCFG/README.md
index f036fbe0..09c09d5d 100644
--- a/Drivers/BSP/NETCFG/README.md
+++ b/Drivers/BSP/NETCFG/README.md
@@ -1,6 +1,6 @@
# Drivers/BSP/NETCFG/ — 网络配置
-> 网络参数的**加载 / 保存 / 旧档迁移**(IP、掩码、网关等)。
+> 网络参数的**加载 / 保存**(IP、掩码、网关等)。
> 本模块是**网络配置的持久化层**,与 `App/cfg/cfg_file.c`(配置引擎)配合工作。
## 文件一览
@@ -8,12 +8,17 @@
| 文件 | 作用 |
|---|---|
| `net_cfg.c/h` | 网络配置加载(`net_cfg_load`)/ 保存(`net_cfg_save_run`)+ RAM 副本管理 |
-| `net_cfg_legacy.c/h` | **旧版配置档迁移**(首启时把旧格式转换为当前格式) |
+
+> **已删除(2026-10-10)**:`net_cfg_legacy.c/h`——旧二进制档 `/cfg/netcfg.bin` 的"首启自动迁移"。
+> 现口径:旧档若存在则被**忽略**(不读、不删、不迁移),配置直接回落工厂默认(`/config.ini`
+> `[network]` 段)。删除理由:该一次性路径把整条配置写链(`net_cfg_save → cfg_file_save →
+> cfg_store_write_atomic → f_rename → FatFS → dhara FTL`)挂进启动期调用图,使 defaultTask 的
+> armlink 静态最坏栈链 +600 B,而本仓库不存在携带旧档的设备。
## 工作流
```
-defaultTask:net_cfg_load(含旧档迁移)→ 置 STORAGE_READY
+defaultTask:net_cfg_load → 置 STORAGE_READY
↓ (网络配置在屏障前已加载)
netTask:只读 RAM 副本 → net_stack_bring_up(不在 netTask 里读盘)
↓
diff --git a/Drivers/BSP/NETCFG/net_cfg.c b/Drivers/BSP/NETCFG/net_cfg.c
index 218d11bb..d3b893cb 100644
--- a/Drivers/BSP/NETCFG/net_cfg.c
+++ b/Drivers/BSP/NETCFG/net_cfg.c
@@ -2,8 +2,7 @@
* 模块名称:Network Configuration Core (配置核心)
* 模块功能:RAM 配置副本 + 工厂默认 + 加载/保存编排 + 实际 MAC 影子 +
* IPv4 字符串转换;存储经 cfg_file 通用配置文件引擎(INI [network]
- * 段:ip/mask/gw/mac);旧版 NCFG 二进制格式归 net_cfg_legacy
- * (首启一次性迁移)
+ * 段:ip/mask/gw/mac)
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:王建锋
* 创建日期:2026-09-10
@@ -12,6 +11,12 @@
* v1.1 2026-09-14 王建锋 存储迁移至 cfg_file 引擎(INI);旧 NCFG 代码移至 net_cfg_legacy
* v1.2 2026-09-15 王建锋 保存改跨任务交接(request/state/run + 通知回调);
* 引擎属主 = defaultTask(P1-3 竞态修复)
+ * v1.3 2026-10-10 王建锋 **删除旧档 NCFG 迁移**(net_cfg_legacy 整体移除):该兼容
+ * 路径把整条配置写链(net_cfg_save → cfg_file_save →
+ * cfg_store_write_atomic → f_rename → FTL)挂进启动期调用图,
+ * 使 defaultTask 静态最坏链 +600 B;本仓库无携带
+ * /cfg/netcfg.bin 的设备,故按"不保留旧档兼容"处置。
+ * 旧档若存在 → 被忽略(不读、不删、不迁移),配置回落工厂默认
*/
/* 头文件包含区 */
@@ -23,10 +28,11 @@
#include "net_cfg.h"
-#include "net_cfg_legacy.h"
-
#include "cfg_file.h"
+/* 深调用链模块(net_cfg_load/save 在 defaultTask 启动链与保存链上):
+ * 日志行缓冲收到 128 B(默认 192),本模块最长行渲染后 < 128 → 不截断 */
+#define DBG_LINE_BUF_MAX 128U
#define DBG_TAG "[NET_CFG]"
#include "dbg_log.h"
@@ -140,9 +146,8 @@ static bool s_mac_is_zero(const uint8_t *p_mac) {
int net_cfg_load(void) {
s_net_register();
- /* 首启先迁旧档 NCFG(有效 → 旧值物化进新文件);新文件已存在则跳过 */
- (void)net_cfg_legacy_migrate();
-
+ /* 旧档 NCFG 迁移已于 2026-10-10 删除(net_cfg_legacy 移除;理由见文件头 v1.3)。
+ * 若卷上仍残留 /cfg/netcfg.bin:不读、不删、不迁移 → 配置回落工厂默认 */
if (cfg_file_load() != 0) {
/* 严重错误:引擎已将 RAM 副本复位工厂默认,行为仍安全 */
DBG_ERROR("load: cfg_file_load FAIL");
diff --git a/Drivers/BSP/NETCFG/net_cfg.h b/Drivers/BSP/NETCFG/net_cfg.h
index 129717e4..625225d7 100644
--- a/Drivers/BSP/NETCFG/net_cfg.h
+++ b/Drivers/BSP/NETCFG/net_cfg.h
@@ -7,8 +7,9 @@
* = 不覆盖芯片内置 MAC。cfg_file 引擎为静态单任务设计,调用收敛于
* 单一属主任务(MCU = defaultTask:就绪屏障前加载 / 保存执行 / 2s
* poll;模拟器 = 主循环);UI 保存只投递请求,netTask 只读 RAM 副本
- * 函数说明:旧版 NCFG 二进制格式(magic+ver+CRC-16+18B 字段)归 net_cfg_legacy,
- * 首启一次性迁移进通用配置文件
+ * 函数说明:旧版 NCFG 二进制格式(magic+ver+CRC-16+18B 字段)的迁移路径
+ * (net_cfg_legacy)**已于 2026-10-10 删除** → 旧档 /cfg/netcfg.bin
+ * 不再读取/迁移,携带旧档的设备升级后回落工厂默认(理由见 net_cfg.c v1.3)
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:王建锋
* 创建日期:2026-09-10
diff --git a/Drivers/BSP/NETCFG/net_cfg_legacy.c b/Drivers/BSP/NETCFG/net_cfg_legacy.c
deleted file mode 100644
index fb195d3a..00000000
--- a/Drivers/BSP/NETCFG/net_cfg_legacy.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 模块名称:net_cfg_legacy
- * 模块功能:旧版 NCFG 二进制配置一次性迁移——读遗留文件 → 校验 magic/ver/CRC →
- * 填网络配置 RAM 副本 → 经 cfg_file 引擎生成新文件(带旧值)→ 删旧文件
- * 适用平台:STM32F407ZGTx / PC 模拟器(两端共用;平台路径经 cfg_file_store 后端)
- * 作者:王建锋
- * 创建日期:2026-09-14
- * 修改记录:
- * v1.0 2026-09-14 王建锋 创建初始版本(P3:net_cfg 引擎化,旧格式代码迁入)
- */
-
-/* 头文件包含区 */
-#include
-
-#include "net_cfg_legacy.h"
-
-#include "net_cfg.h"
-
-#include "cfg_file.h"
-
-#include "cfg_file_store.h"
-
-#define DBG_TAG "[NET_CFG]"
-#include "dbg_log.h"
-
-/* 常量定义区 */
-
-#define NET_CFG_MAGIC 0x4647434Eu /* 'NCFG'(文件字节序 N,C,G,F;小端装载) */
-#define NET_CFG_VER 1u /* 磁盘格式版本 */
-
-/* 旧磁盘格式(两端布局一致:u32 4 对齐;字段区 18B 连续,CRC 覆盖之) */
-typedef struct {
- uint32_t magic; /* NET_CFG_MAGIC */
- uint16_t ver; /* 格式版本 */
- uint16_t crc; /* CRC-16/MODBUS(覆盖 ip..mac 共 18B) */
- uint8_t ip[4];
- uint8_t mask[4];
- uint8_t gw[4];
- uint8_t mac[6];
-} net_cfg_blob_t;
-
-/* 静态函数声明区 */
-static uint16_t s_crc16_modbus(const uint8_t *p_data, size_t len);
-
-/* 函数定义区 */
-
-/*
- * 函数功能:CRC-16/MODBUS(无查表逐位算法)
- * 入口参数:p_data - 数据指针 const uint8_t *
- * len - 数据长度 size_t
- * 返回值:CRC-16 值 uint16_t
- * 限定条件:p_data 非空(len 可为 0,返回初始值 0xFFFF)
- * 函数说明:文件私有(数据量 ≤32B,性能无关)
- */
-static uint16_t s_crc16_modbus(const uint8_t *p_data, size_t len) {
- uint16_t crc = 0xFFFFu;
-
- for (size_t i = 0u; i < len; i++) {
- crc = (uint16_t)(crc ^ (uint16_t)p_data[i]);
- for (int b = 0; b < 8; b++) {
- if (crc & 0x0001u) {
- crc = (uint16_t)((crc >> 1) ^ 0xA001u);
- }
- else {
- crc = (uint16_t)(crc >> 1);
- }
- }
- }
- return crc;
-}
-
-/*
- * 函数功能:旧 NCFG 二进制配置一次性迁移到通用配置文件
- * 入口参数:无
- * 返回值:0 - 迁移成功,或无旧文件/新文件已存在(正常);-1 - 迁移失败 int
- * 限定条件:调用方须已注册 [network] 段(net_cfg_load 内部完成)
- * 函数说明:见 net_cfg_legacy.h 同名函数说明
- */
-int net_cfg_legacy_migrate(void) {
- net_cfg_blob_t blob;
- uint8_t buf[32];
- size_t nread = 0u;
- cfg_file_stat_t st;
- net_cfg_t tmp;
- const char *p_legacy;
-
- /* 新文件已存在 = 已迁移过(或已有配置):跳过 */
- if (cfg_store_stat(cfg_store_config_path(), &st) == 0) {
- return 0;
- }
-
- p_legacy = cfg_store_legacy_path();
- if (cfg_store_read(p_legacy, buf, sizeof(buf), &nread) != 0
- || nread != sizeof(net_cfg_blob_t)) {
- DBG_INFO("legacy: no legacy file, skip");
- return 0;
- }
-
- (void)memcpy(&blob, buf, sizeof(blob));
- if (blob.magic != NET_CFG_MAGIC || blob.ver != NET_CFG_VER
- || s_crc16_modbus(blob.ip, 18u) != blob.crc) {
- DBG_INFO("legacy: blob invalid (magic/ver/crc), file kept for inspection");
- return 0;
- }
-
- /* 填 RAM 副本(net_cfg_get 只读,经 net_cfg_set 可写接口整体回灌)
- * → 经引擎物化旧值到新文件(此时新文件必缺失 → 生成模板带旧值) */
- (void)memcpy(&tmp, net_cfg_get(), sizeof(tmp));
- (void)memcpy(tmp.ip, blob.ip, 4u);
- (void)memcpy(tmp.mask, blob.mask, 4u);
- (void)memcpy(tmp.gw, blob.gw, 4u);
- (void)memcpy(tmp.mac, blob.mac, 6u);
- net_cfg_set(&tmp);
-
- if (net_cfg_save() != 0) {
- DBG_ERROR("legacy: migrate save FAIL");
- return -1;
- }
- (void)cfg_store_remove(p_legacy);
-
- DBG_INFO("legacy: migrated to config file (ip=%u.%u.%u.%u)",
- (unsigned)blob.ip[0], (unsigned)blob.ip[1],
- (unsigned)blob.ip[2], (unsigned)blob.ip[3]);
- return 0;
-}
diff --git a/Drivers/BSP/NETCFG/net_cfg_legacy.h b/Drivers/BSP/NETCFG/net_cfg_legacy.h
deleted file mode 100644
index 076c4fcb..00000000
--- a/Drivers/BSP/NETCFG/net_cfg_legacy.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 模块名称:net_cfg_legacy
- * 模块功能:旧版 NCFG 二进制配置一次性迁移到通用配置文件(net_cfg 旧磁盘格式
- * 的拥有者:magic 'NCFG' + ver + CRC-16/MODBUS + 18B 字段)
- * 适用平台:STM32F407ZGTx / PC 模拟器(两端共用;平台路径经 cfg_file_store 后端)
- * 作者:王建锋
- * 创建日期:2026-09-14
- * 修改记录:
- * v1.0 2026-09-14 王建锋 创建初始版本(P3:net_cfg 引擎化,旧格式代码迁入)
- */
-
-#ifndef NET_CFG_LEGACY_H
-#define NET_CFG_LEGACY_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * 函数功能:旧 NCFG 二进制配置(28B)一次性迁移到通用配置文件
- * 入口参数:无
- * 返回值:0 - 迁移成功,或无旧文件/新文件已存在(正常);
- * -1 - 迁移失败(新文件未生成) int
- * 限定条件:调用方须已注册 [network] 段(net_cfg_load 内部完成)
- * 函数说明:新文件已存在 → 跳过(已迁移过);旧文件有效 → 填网络配置 RAM
- * 副本 → 经引擎生成新文件(带旧值)→ 删旧文件;旧文件缺失/无效 →
- * 不动旧文件(留人工检查),新文件按工厂默认生成
- */
-int net_cfg_legacy_migrate(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* NET_CFG_LEGACY_H */
diff --git a/Drivers/BSP/README.md b/Drivers/BSP/README.md
index 502e47dc..52ebfd18 100644
--- a/Drivers/BSP/README.md
+++ b/Drivers/BSP/README.md
@@ -13,7 +13,7 @@
| `SD2506/` | SD2506 RTC | I2C | 实时时钟驱动 | `docs/问题记录/SD2506_Trap_Records.md` |
| `RS485/` | RS-485 半双工 | UART5 | 收发方向控制(DE 引脚)+ 时序 | — |
| `NET/` | BSD Socket 网络抽象层 | — | Socket API + select + 轻量 FTP 服务器 | `docs/网络/`(含 `Net层阻塞模型架构设计.md`) |
-| `NETCFG/` | 网络配置 | — | `/config.ini` 网络段的加载/保存 + 旧档迁移 | `docs/子系统设计/网络配置说明.md` |
+| `NETCFG/` | 网络配置 | — | `/config.ini` 网络段的加载/保存(旧 NCFG 档已删除,2026-10-10) | `docs/子系统设计/网络配置说明.md` |
| `UI/` | LVGL UI 组件 | — | 菜单/内容页/组件/中文字体 | `docs/UI设计/` |
## 根级文件
diff --git a/Drivers/BSP/dbg_log.h b/Drivers/BSP/dbg_log.h
index e4314442..2a81b91b 100644
--- a/Drivers/BSP/dbg_log.h
+++ b/Drivers/BSP/dbg_log.h
@@ -42,12 +42,49 @@ extern "C" {
*/
#ifdef DBG_ENABLE
+/*
+ * 行缓冲上限(栈预算旋钮,2026-10-10 加)
+ * 默认 = 控制台单行上限 DBG_CON_LINE_MAX(192)。
+ * ⚠ 本数组是**在每个日志调用点的栈帧里内联**的,会进 armlink 最坏调用链:
+ * 实测存储/配置那条链上 9 个帧各含 192 B 行缓冲 + 32 B 时间戳缓冲
+ * → defaultTask 静态最坏链 5312 B 里约 1.5 KB 纯粹是日志行缓冲。
+ * 故**深调用链模块**(存储 FTL/NAND、配置引擎、网络驱动、时间同步)应在
+ * 包含本文件前显式收紧,例如 `#define DBG_LINE_BUF_MAX 128U`;
+ * 取值须 ≥ 该模块最长日志行(含时间戳 20 + 标签 + 正文),否则该行被截断。
+ * 核算:scripts/stack_report.py(改前/改后各跑一次)
+ */
+#ifndef DBG_LINE_BUF_MAX
+#define DBG_LINE_BUF_MAX DBG_CON_LINE_MAX
+#endif
+
+/*
+ * 时间戳文本缓冲上限:sys_clock_get_str() 恒写 "----/--/-- --:--:--" 或
+ * "%04d-%02d-%02d %02d:%02d:%02d" = 19 字符 + '\0' → 24 足够(原 32 是随手取整,
+ * 每个日志调用点白占 8 B 栈)
+ */
+#define DBG_TS_BUF_MAX 24U
+
+/*
+ * 有界格式化 + 交单写者控制台(行缓冲由调用方提供,便于与时间戳缓冲共用数组)
+ */
+#define DBG_EMIT(p_line, ...) do { \
+ int __con_n = snprintf((p_line), DBG_LINE_BUF_MAX, __VA_ARGS__); \
+ if (__con_n > 0) { \
+ unsigned __con_len = (__con_n >= (int)DBG_LINE_BUF_MAX) \
+ ? (unsigned)(DBG_LINE_BUF_MAX - 1u) : (unsigned)__con_n; \
+ (void)dbg_console_write_line((p_line), __con_len); \
+ } \
+} while (0)
+
/*
* 可重定向的打印函数,用户可在编译选项或 net_config.h 中预定义
* #define DBG_PRINT(...) my_printf(__VA_ARGS__)
+ * ⚠ 2026-10-10 起:带时间戳的 DBG_ERROR/DBG_INFO/DBG_DEBUG 走 **DBG_EMIT**
+ * (与行缓冲共用一个数组,省一帧栈);要整体改道请重定义 `DBG_EMIT(p_line, ...)`
+ * ——它是所有日志的唯一落地点。只定义 DBG_PRINT 仅影响不带时间戳的 DBG_PRINT。
*
* 默认走单写者控制台(App/log/console_log.c):
- * DBG_PRINT 在调用点用库 snprintf 有界格式化整行,再一次性交给 dbg_console_write_line
+ * DBG_EMIT 在调用点用库 snprintf 有界格式化整行,再一次性交给 dbg_console_write_line
* 入环形缓冲,由 defaultTask 唯一发送——
* ① 行与行不会字符级交错(旧 printf→fputc 每字符一次 HAL_UART_Transmit 会交错);
* ② 进 UART 的缓冲恒为控制台内部缓冲,调用方脏指针到不了 UART
@@ -55,13 +92,8 @@ extern "C" {
*/
#ifndef DBG_PRINT
#define DBG_PRINT(...) do { \
- char __con_line[DBG_CON_LINE_MAX]; \
- int __con_n = snprintf(__con_line, sizeof(__con_line), __VA_ARGS__); \
- if (__con_n > 0) { \
- unsigned __con_len = (__con_n >= (int)sizeof(__con_line)) \
- ? (unsigned)(sizeof(__con_line) - 1u) : (unsigned)__con_n; \
- (void)dbg_console_write_line(__con_line, __con_len); \
- } \
+ char __con_line[DBG_LINE_BUF_MAX]; \
+ DBG_EMIT(__con_line, __VA_ARGS__); \
} while (0)
#endif
@@ -75,29 +107,34 @@ extern "C" {
#ifdef APP_TIMESTAMP_ENABLE
/*
- * 时间戳输出宏 — 在日志行首追加 [YYYY-MM-DD HH:MM:SS] 格式的系统墙钟时间
- * sys_clock_get_str() 线程安全(内部使用 DWT US 计数,无锁)
+ * 兼容宏:单独取时间戳文本(当前无调用者;缓冲为复合字面量,仅在本表达式内有效)
*/
-#define DBG_TS() sys_clock_get_str((char[32]){0}, 32)
+#define DBG_TS() sys_clock_get_str((char[DBG_TS_BUF_MAX]){0}, DBG_TS_BUF_MAX)
+/*
+ * DBG_ERROR / DBG_INFO / DBG_DEBUG(带时间戳版)
+ * 时间戳缓冲与行缓冲**共用一个数组**(每个调用点省一帧 24 B 栈):行文本占前
+ * DBG_LINE_BUF_MAX 字节,时间戳文本切片自其后。snprintf 的全部实参先于其执行
+ * 求值完毕,故"先写时间戳切片、再格式化行首"不冲突。
+ */
/*
* DBG_ERROR - 错误输出,受 DBG_ENABLE + APP_TIMESTAMP_ENABLE 控制
*/
#define DBG_ERROR(fmt, ...) do { \
- char __ts_buf[32]; \
- (void)__ts_buf; \
- DBG_PRINT("[%s]" "[ERR]" DBG_TAG " " fmt "\r\n", \
- sys_clock_get_str(__ts_buf, sizeof(__ts_buf)), ##__VA_ARGS__); \
+ char __con_line[DBG_LINE_BUF_MAX + DBG_TS_BUF_MAX]; \
+ DBG_EMIT(__con_line, "[%s]" "[ERR]" DBG_TAG " " fmt "\r\n", \
+ sys_clock_get_str(__con_line + DBG_LINE_BUF_MAX, DBG_TS_BUF_MAX), \
+ ##__VA_ARGS__); \
} while (0)
/*
* DBG_INFO - 信息输出,受 DBG_ENABLE + APP_TIMESTAMP_ENABLE 控制
*/
#define DBG_INFO(fmt, ...) do { \
- char __ts_buf[32]; \
- (void)__ts_buf; \
- DBG_PRINT("[%s]" DBG_TAG " " fmt "\r\n", \
- sys_clock_get_str(__ts_buf, sizeof(__ts_buf)), ##__VA_ARGS__); \
+ char __con_line[DBG_LINE_BUF_MAX + DBG_TS_BUF_MAX]; \
+ DBG_EMIT(__con_line, "[%s]" DBG_TAG " " fmt "\r\n", \
+ sys_clock_get_str(__con_line + DBG_LINE_BUF_MAX, DBG_TS_BUF_MAX), \
+ ##__VA_ARGS__); \
} while (0)
/*
@@ -105,10 +142,10 @@ extern "C" {
*/
#ifdef DBG_DEBUG_ENABLE
#define DBG_DEBUG(fmt, ...) do { \
- char __ts_buf[32]; \
- (void)__ts_buf; \
- DBG_PRINT("[%s]" DBG_TAG "(%s:%d) " fmt "\r\n", \
- sys_clock_get_str(__ts_buf, sizeof(__ts_buf)), __func__, __LINE__, ##__VA_ARGS__); \
+ char __con_line[DBG_LINE_BUF_MAX + DBG_TS_BUF_MAX]; \
+ DBG_EMIT(__con_line, "[%s]" DBG_TAG "(%s:%d) " fmt "\r\n", \
+ sys_clock_get_str(__con_line + DBG_LINE_BUF_MAX, DBG_TS_BUF_MAX), \
+ __func__, __LINE__, ##__VA_ARGS__); \
} while (0)
#else
#define DBG_DEBUG(fmt, ...)
diff --git a/MDK-ARM/STM32F407-Demo.uvprojx b/MDK-ARM/STM32F407-Demo.uvprojx
index a101b29d..f42ef840 100644
--- a/MDK-ARM/STM32F407-Demo.uvprojx
+++ b/MDK-ARM/STM32F407-Demo.uvprojx
@@ -1458,11 +1458,6 @@
1
..\Drivers\BSP\NETCFG\net_cfg.c
-
- net_cfg_legacy.c
- 1
- ..\Drivers\BSP\NETCFG\net_cfg_legacy.c
-
nand_ftl.c
1
diff --git a/README.md b/README.md
index b1100eb2..afa87f0c 100644
--- a/README.md
+++ b/README.md
@@ -130,7 +130,7 @@ STM32F4-Base/
│ │ │ ├── net_socket.c/h # Socket API
│ │ │ ├── net_select.c/h # select/poll 多路复用
│ │ │ └── lftpd/ # 轻量 FTP 服务器
-│ │ ├── NETCFG/ # 网络配置(加载/保存/旧档迁移)
+│ │ ├── NETCFG/ # 网络配置(/config.ini [network] 段加载/保存)
│ │ ├── UI/ # LVGL UI 组件
│ │ └── dbg_log.h / dbg_cfg.h # 调试日志(DBG_INFO 等)
│ ├── STM32F4xx_HAL_Driver/ # ST HAL 库
diff --git a/Src/freertos.c b/Src/freertos.c
index 2f2f1d57..305d6c8b 100644
--- a/Src/freertos.c
+++ b/Src/freertos.c
@@ -94,15 +94,24 @@ static int hook_ptr_ok(const void *p)
* defaultTask 1024 words:扛 mount+mkfs+FAT 探针+cfg 加载+syslog 写+配置引擎
* (全深层 FatFS I/O)。原 512,2KB 实测峰值溢出——开启
* configCHECK_FOR_STACK_OVERFLOW=2 后被钩子抓到(2026-09-21)。
- * netTask 960 words:静态最坏链 2664 B(发送停滞→断连→重监听→SPI 故障→日志尾,
- * 真实直调链,日志主导:链上 5 帧各含 192 B __con_line + 尾部 ~696 B);3840 B
- * 配置余量 1176 B(30.6%),过 stack_report 规则。运行时水位仅 ~1.1 KB(错误尾未
+ * 2026-10-10 栈整改(**未抬栈**,靠削链达标):静态最坏链 5312 → 2776 B、
+ * 实测峰值 3392 → 2152 B(余 1944 B / 47%)。四个杠杆:① 删旧档 NCFG 迁移
+ * (net_cfg_legacy,−600 B 链);② 6 处局部 `FIL` 改函数级 static(FF_FS_TINY=0
+ * → 单个 FIL = 528 B 栈);③ 日志行缓冲按模块收紧 `DBG_LINE_BUF_MAX 128`
+ * + 时间戳缓冲并入行缓冲(每个日志调用点原内联 192+32 B);④ 断言/故障钩子
+ * 脱离 HAL 发送回退 + 缓冲静态化(configASSERT 在 FreeRTOS 内部可达 →
+ * 钩子在**每个**任务的最坏链尾)。详见 docs/内存管理/RAM使用分析与优化方案.md
+ * netTask 960 words:静态最坏链 1872 B(2026-10-10 整改后;整改前 2664 B:
+ * 发送停滞→断连→重监听→SPI 故障→日志尾,日志主导);3840 B 配置余量 1968 B
+ * (51%),过 stack_report 规则。运行时水位仅 ~0.9 KB(错误尾未
* 触发,不可作依据)。曾试 net_drain_chip_rx scratch 静态化,实测仅省 16 B 栈
* (ARMCC 已叠放不重叠局部量)反增 256 B BSS,已回退——见 net_socket.c 注释。
* testTask 2048 words:存储套件 deep call chain + 局部缓冲,原 1024(4 KB)实测溢出
* (2026-09-20)。仅启用测试套件时创建。
* timeSyncTask 512 words:本区下方手工定义(不在 `.ioc` 的 Tasks01 里 → 重生成会丢,
- * 靠审计 WARN 提示),只做读 RTC + 置就绪事件位,无深调用链。
+ * 靠审计 WARN 提示),建监听 → net_bind → CH395F → 日志尾。2026-10-10 整改后
+ * 静态最坏链 1024 B(整改前 1736 B)、实测峰值 616 B;⚠ 余量 1024 B **正好**
+ * 等于 ISR 底线 → 本任务链上再加任何调用(或新日志行)都必须先抬栈。
*/
/* 存储测试变量(g_storage_stats / s_perf_buf)已迁至 test/board/storage_test_task.c */
osThreadId_t timeSyncTaskHandle;
@@ -435,7 +444,10 @@ void vApplicationAssertFailed(const char *file, long line)
{
static const char msg_head[] = "\r\n[ERR] ASSERT FAILED ";
const char *p = file;
- char num[16];
+ /* 缓冲一律 static(不放栈上):本钩子是"内核状态已不可信"的终点路径,打印完即
+ * 复位,不存在并发/重入;放栈上会让 armlink 把这 81 B 挂进每个任务的最坏链
+ * (configASSERT 在 FreeRTOS 内部可达 → 每条链尾都有本钩子) */
+ static char num[16];
int i;
/* 文件名只取末段(全路径太长且无信息量) */
@@ -449,8 +461,8 @@ void vApplicationAssertFailed(const char *file, long line)
}
/* 有界拷贝:上限 48 字符 */
{
+ static char name[49]; /* static 存储(见上),作用域收到本块 */
uint16_t len = 0u;
- char name[49];
while ((len < 48u) && (p[len] != '\0')) {
name[len] = p[len];
len++;
@@ -471,21 +483,26 @@ void vApplicationAssertFailed(const char *file, long line)
if (line <= 0) {
num[i++] = '0';
} else {
- char rev[16];
int n = 0;
+ int j;
+
while ((line > 0) && (n < 15)) {
- rev[n++] = (char)('0' + (line % 10));
+ num[n++] = (char)('0' + (line % 10)); /* 先逆序填入 */
line /= 10;
}
- while (n > 0) {
- num[i++] = rev[--n];
+ for (j = 0; j < n / 2; j++) { /* 原地反转:省一个 16 B 缓冲 */
+ char t = num[j];
+ num[j] = num[n - 1 - j];
+ num[n - 1 - j] = t;
}
+ i = n;
}
dbg_console_write_raw(num, (unsigned)i);
dbg_console_write_raw(" (resetting)\r\n", 15u);
- HAL_Delay(200); /* 等 UART 移位寄存器排空 */
+ /* 无需 HAL_Delay:dbg_console_write_raw → con_tx_bounded 已等到 TC(移位寄存器
+ * 排空)才返回;去掉 HAL_Delay 亦少一条 HAL 依赖(断言现场 tick 未必可信) */
NVIC_SystemReset();
}
/* USER CODE END Application */
diff --git a/docs/README.md b/docs/README.md
index 330844e5..8acaf87a 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -80,7 +80,7 @@ docs/
| 文档 | 内容 |
|---|---|
-| [`配置文件设计说明.md`](子系统设计/配置文件设计说明.md) | `/config.ini` 配置引擎:分层、解析、持久化与旧档迁移 |
+| [`配置文件设计说明.md`](子系统设计/配置文件设计说明.md) | `/config.ini` 配置引擎:分层、解析、原子持久化(旧 NCFG 档已废弃) |
| [`网络配置说明.md`](子系统设计/网络配置说明.md) | 网口设置页:IP/掩码/网关,UI 保存即时生效 |
| [`系统墙钟时间维护说明.md`](子系统设计/系统墙钟时间维护说明.md) | `sys_clock`:RTC 基准、tick 回绕防护、30 天惰性再基准化 |
| [`控制台单写者日志设计说明.md`](子系统设计/控制台单写者日志设计说明.md) | 控制台日志单写者模型(避免多任务交错输出) |
diff --git a/docs/images/任务栈预算.svg b/docs/images/任务栈预算.svg
index ed02c6e0..1dee4bb5 100644
--- a/docs/images/任务栈预算.svg
+++ b/docs/images/任务栈预算.svg
@@ -8,39 +8,39 @@
FreeRTOS 任务栈预算(48KB 堆,2026-09-21 已迁 CCM)
-数据: 2026-09-21 @build + FTP 128KB 实测(data/stack_report_20260921.md)
+数据: 2026-10-10 @build + 开机/空闲实测(data/stack_report_20261010.md);最坏 = max(静态最坏链, 实测峰值)
浅色条 = 分配栈 深色条 = 最坏占用(max(静态最坏, 实测峰值)) 下方文字 = 实测余量/判定
defaultTask
- 配置 4096B | 实测峰值 2136B | 最坏 2776B | 余量 1320B (32%) PASS
+ 配置 4096B | 实测峰值 2152B | 最坏 2776B | 余量 1320B (32%) PASS
netTask
-
-
- 配置 4096B | 实测峰值 588B | 最坏 588B | 余量 3508B (85%) PASS
+
+
+ 配置 3840B | 实测峰值 920B | 最坏 1872B | 余量 1968B (51%) PASS
ftpTask
-
- 配置 4096B | 实测峰值 1184B | 最坏 1184B | 余量 2912B (71%) PASS
+
+ 配置 4096B | 实测峰值 740B | 最坏 1216B | 余量 2880B (70%) PASS
testTask
-
- 配置 8192B | 实测峰值 348B | 最坏 348B | 余量 7844B (95%) PASS
+
+ 配置 8192B | 实测峰值 496B | 最坏 496B | 余量 7696B (93%) PASS
uiTask
-
- 配置 16384B | 实测峰值 3824B | 最坏 3824B | 余量 12560B (76%) PASS
+
+ 配置 16384B | 实测峰值 4016B | 最坏 4016B | 余量 12368B (75%) PASS
timeSyncTask
-
- 配置 2048B | 实测峰值 420B | 最坏 420B | 余量 1628B (79%) PASS
+
+ 配置 2048B | 实测峰值 616B | 最坏 1024B | 余量 1024B (50%) PASS
idle
512B(未实测)
timer
1024B(未实测)
-堆总量: 49152B (48KB, RW_CCM) 任务栈合计: 38912B (38.0KB) + 内核栈 1536B
+堆总量: 49152B (48KB, RW_CCM) 任务栈合计: 38656B (37.8KB) + 内核栈 1536B
实测: free=8784B / min_ever=4848B(2026-09-21,含 FTP 负载) 判定: 6/6 PASS(余量 ≥ max(1024B, 配置×30%))
Normal 优先级
diff --git a/docs/images/引用关系图.dot b/docs/images/引用关系图.dot
index c5a3c9dd..5440d533 100644
--- a/docs/images/引用关系图.dot
+++ b/docs/images/引用关系图.dot
@@ -47,8 +47,6 @@ digraph refgraph_full {
"Drivers/BSP/NET/net_types.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/NETCFG/net_cfg.c" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/NETCFG/net_cfg.h" [fillcolor="#dbeafe", color="#1d4ed8"];
- "Drivers/BSP/NETCFG/net_cfg_legacy.c" [fillcolor="#dbeafe", color="#1d4ed8"];
- "Drivers/BSP/NETCFG/net_cfg_legacy.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/RS485/rs485.c" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/RS485/rs485.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/SD2506/sd2506.c" [fillcolor="#dbeafe", color="#1d4ed8"];
@@ -93,6 +91,7 @@ digraph refgraph_full {
"Drivers/BSP/dbg_log.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h" [fillcolor="#f3f4f6", color="#9ca3af"];
+ "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h" [fillcolor="#f3f4f6", color="#9ca3af"];
@@ -106,6 +105,7 @@ digraph refgraph_full {
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Inc/FreeRTOSConfig.h" [fillcolor="#dbeafe", color="#1d4ed8"];
+ "Inc/adc.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Inc/dma.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Inc/gpio.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Inc/i2c.h" [fillcolor="#dbeafe", color="#1d4ed8"];
@@ -124,6 +124,7 @@ digraph refgraph_full {
"Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [fillcolor="#f3f4f6", color="#9ca3af"];
+ "Src/adc.c" [fillcolor="#dbeafe", color="#1d4ed8"];
"Src/dma.c" [fillcolor="#dbeafe", color="#1d4ed8"];
"Src/freertos.c" [fillcolor="#dbeafe", color="#1d4ed8"];
"Src/gpio.c" [fillcolor="#dbeafe", color="#1d4ed8"];
@@ -207,7 +208,6 @@ digraph refgraph_full {
"App/fs/vol_lock.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"App/log/console_log.c" -> "App/app/sys_events.h" [color="#2563eb", penwidth=1.0];
"App/log/console_log.c" -> "App/log/console_log.h" [color="#2563eb", penwidth=1.0];
- "App/log/console_log.c" -> "App/log/sys_log.h" [color="#2563eb", penwidth=1.0];
"App/log/console_log.c" -> "Inc/usart.h" [color="#2563eb", penwidth=1.0];
"App/log/console_log.c" -> "Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h" [color="#94a3b8", penwidth=0.7];
"App/log/console_log.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7];
@@ -343,16 +343,9 @@ digraph refgraph_full {
"Drivers/BSP/NET/net_types.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Drivers/BSP/NETCFG/net_cfg.c" -> "App/cfg/cfg_file.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NETCFG/net_cfg.c" -> "Drivers/BSP/NETCFG/net_cfg.h" [color="#2563eb", penwidth=1.0];
- "Drivers/BSP/NETCFG/net_cfg.c" -> "Drivers/BSP/NETCFG/net_cfg_legacy.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NETCFG/net_cfg.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NETCFG/net_cfg.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Drivers/BSP/NETCFG/net_cfg.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
- "Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "App/cfg/cfg_file.h" [color="#2563eb", penwidth=1.0];
- "Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "App/cfg/cfg_file_store.h" [color="#2563eb", penwidth=1.0];
- "Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "Drivers/BSP/NETCFG/net_cfg.h" [color="#2563eb", penwidth=1.0];
- "Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "Drivers/BSP/NETCFG/net_cfg_legacy.h" [color="#2563eb", penwidth=1.0];
- "Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
- "Drivers/BSP/NETCFG/net_cfg_legacy.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Drivers/BSP/RS485/rs485.c" -> "Drivers/BSP/RS485/rs485.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/RS485/rs485.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/SD2506/sd2506.c" -> "Drivers/BSP/SD2506/sd2506.h" [color="#2563eb", penwidth=1.0];
@@ -363,6 +356,9 @@ digraph refgraph_full {
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Drivers/BSP/TPAFE5160/tpafe5160.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
+ "Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7];
+ "Drivers/BSP/TPAFE5160/tpafe5160.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [color="#94a3b8", penwidth=0.7];
+ "Drivers/BSP/TPAFE5160/tpafe5160.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Drivers/BSP/TPAFE5160/tpafe5160.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/UI/ui_content_page.c" -> "Drivers/BSP/UI/ui_content_page.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/UI/ui_content_page.c" -> "Drivers/BSP/UI/ui_deco.h" [color="#2563eb", penwidth=1.0];
@@ -409,6 +405,7 @@ digraph refgraph_full {
"Drivers/BSP/UI/ui_net_sink.c" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/UI/ui_net_sink.c" -> "Drivers/BSP/UI/ui_net_sink.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/UI/ui_net_sink.c" -> "Drivers/BSP/UI/ui_net_sink_backend.h" [color="#2563eb", penwidth=1.0];
+ "Drivers/BSP/UI/ui_net_sink.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/UI/ui_net_sink.c" -> "test/board/net_latency_test.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/UI/ui_net_sink.c" -> "test/board/test_config.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/UI/ui_net_sink.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
@@ -456,12 +453,14 @@ digraph refgraph_full {
"Drivers/BSP/dbg_log.h" -> "Drivers/BSP/dbg_cfg.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/dbg_log.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Inc/FreeRTOSConfig.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
+ "Inc/adc.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
"Inc/dma.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
"Inc/gpio.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
"Inc/i2c.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
"Inc/iwdg.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
"Inc/main.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h" [color="#94a3b8", penwidth=0.7];
"Inc/spi.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
+ "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h" [color="#94a3b8", penwidth=0.7];
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h" [color="#94a3b8", penwidth=0.7];
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h" [color="#94a3b8", penwidth=0.7];
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h" [color="#94a3b8", penwidth=0.7];
@@ -476,6 +475,7 @@ digraph refgraph_full {
"Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h" [color="#94a3b8", penwidth=0.7];
"Inc/stm32f4xx_hal_conf.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Inc/usart.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
+ "Src/adc.c" -> "Inc/adc.h" [color="#2563eb", penwidth=1.0];
"Src/dma.c" -> "Inc/dma.h" [color="#2563eb", penwidth=1.0];
"Src/freertos.c" -> "App/app/sys_events.h" [color="#2563eb", penwidth=1.0];
"Src/freertos.c" -> "App/sync/time_sync.h" [color="#2563eb", penwidth=1.0];
@@ -508,6 +508,7 @@ digraph refgraph_full {
"Src/main.c" -> "Drivers/BSP/SD2506/sd2506.h" [color="#2563eb", penwidth=1.0];
"Src/main.c" -> "Drivers/BSP/TPAFE5160/tpafe5160.h" [color="#2563eb", penwidth=1.0];
"Src/main.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
+ "Src/main.c" -> "Inc/adc.h" [color="#2563eb", penwidth=1.0];
"Src/main.c" -> "Inc/dma.h" [color="#2563eb", penwidth=1.0];
"Src/main.c" -> "Inc/gpio.h" [color="#2563eb", penwidth=1.0];
"Src/main.c" -> "Inc/i2c.h" [color="#2563eb", penwidth=1.0];
diff --git a/docs/images/引用关系图.json b/docs/images/引用关系图.json
index 30458400..9e36ca10 100644
--- a/docs/images/引用关系图.json
+++ b/docs/images/引用关系图.json
@@ -221,14 +221,6 @@
"path": "Drivers/BSP/NETCFG/net_cfg.h",
"class": "fp"
},
- {
- "path": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
- "class": "fp"
- },
- {
- "path": "Drivers/BSP/NETCFG/net_cfg_legacy.h",
- "class": "fp"
- },
{
"path": "Drivers/BSP/RS485/rs485.c",
"class": "fp"
@@ -537,6 +529,14 @@
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h",
"class": "tp"
},
+ {
+ "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
+ "class": "tp"
+ },
+ {
+ "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h",
+ "class": "tp"
+ },
{
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h",
"class": "tp"
@@ -621,6 +621,10 @@
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h",
"class": "tp"
},
+ {
+ "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h",
+ "class": "tp"
+ },
{
"path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_bus.h",
"class": "tp"
@@ -677,6 +681,14 @@
"path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c",
"class": "tp"
},
+ {
+ "path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c",
+ "class": "tp"
+ },
+ {
+ "path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c",
+ "class": "tp"
+ },
{
"path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c",
"class": "tp"
@@ -757,6 +769,10 @@
"path": "Inc/FreeRTOSConfig.h",
"class": "fp"
},
+ {
+ "path": "Inc/adc.h",
+ "class": "fp"
+ },
{
"path": "Inc/dma.h",
"class": "fp"
@@ -4725,6 +4741,10 @@
"path": "Middlewares/Third_Party/FreeRTOS/Source/timers.c",
"class": "tp"
},
+ {
+ "path": "Src/adc.c",
+ "class": "fp"
+ },
{
"path": "Src/dma.c",
"class": "fp"
@@ -5883,12 +5903,6 @@
"kind": "fp-fp",
"include": "sys_events.h"
},
- {
- "from": "App/log/console_log.c",
- "to": "App/log/sys_log.h",
- "kind": "fp-fp",
- "include": "sys_log.h"
- },
{
"from": "App/log/console_log.h",
"to": "外部/系统头文件",
@@ -7029,12 +7043,6 @@
"kind": "fp-fp",
"include": "net_cfg.h"
},
- {
- "from": "Drivers/BSP/NETCFG/net_cfg.c",
- "to": "Drivers/BSP/NETCFG/net_cfg_legacy.h",
- "kind": "fp-fp",
- "include": "net_cfg_legacy.h"
- },
{
"from": "Drivers/BSP/NETCFG/net_cfg.c",
"to": "App/cfg/cfg_file.h",
@@ -7059,42 +7067,6 @@
"kind": "fp-ext",
"include": "stddef.h"
},
- {
- "from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
- "to": "外部/系统头文件",
- "kind": "fp-ext",
- "include": "string.h"
- },
- {
- "from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
- "to": "Drivers/BSP/NETCFG/net_cfg_legacy.h",
- "kind": "fp-fp",
- "include": "net_cfg_legacy.h"
- },
- {
- "from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
- "to": "Drivers/BSP/NETCFG/net_cfg.h",
- "kind": "fp-fp",
- "include": "net_cfg.h"
- },
- {
- "from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
- "to": "App/cfg/cfg_file.h",
- "kind": "fp-fp",
- "include": "cfg_file.h"
- },
- {
- "from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
- "to": "App/cfg/cfg_file_store.h",
- "kind": "fp-fp",
- "include": "cfg_file_store.h"
- },
- {
- "from": "Drivers/BSP/NETCFG/net_cfg_legacy.c",
- "to": "Drivers/BSP/dbg_log.h",
- "kind": "fp-fp",
- "include": "dbg_log.h"
- },
{
"from": "Drivers/BSP/RS485/rs485.c",
"to": "Drivers/BSP/RS485/rs485.h",
@@ -7143,6 +7115,12 @@
"kind": "fp-fp",
"include": "main.h"
},
+ {
+ "from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
+ "to": "外部/系统头文件",
+ "kind": "fp-ext",
+ "include": "string.h"
+ },
{
"from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
"to": "Drivers/BSP/TPAFE5160/tpafe5160.h",
@@ -7155,6 +7133,18 @@
"kind": "fp-fp",
"include": "main.h"
},
+ {
+ "from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
+ "to": "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h",
+ "kind": "fp-tp",
+ "include": "FreeRTOS.h"
+ },
+ {
+ "from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
+ "to": "Middlewares/Third_Party/FreeRTOS/Source/include/task.h",
+ "kind": "fp-tp",
+ "include": "task.h"
+ },
{
"from": "Drivers/BSP/TPAFE5160/tpafe5160.c",
"to": "Drivers/BSP/dbg_log.h",
@@ -7473,6 +7463,12 @@
"kind": "fp-fp",
"include": "net_latency_test.h"
},
+ {
+ "from": "Drivers/BSP/UI/ui_net_sink.c",
+ "to": "Drivers/BSP/dbg_log.h",
+ "kind": "fp-fp",
+ "include": "dbg_log.h"
+ },
{
"from": "Drivers/BSP/UI/ui_net_sink.h",
"to": "外部/系统头文件",
@@ -8397,6 +8393,30 @@
"kind": "tp-tp",
"include": "stm32f4xx_hal_conf.h"
},
+ {
+ "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
+ "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h",
+ "kind": "tp-tp",
+ "include": "stm32f4xx_hal_def.h"
+ },
+ {
+ "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
+ "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h",
+ "kind": "tp-tp",
+ "include": "stm32f4xx_ll_adc.h"
+ },
+ {
+ "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
+ "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h",
+ "kind": "tp-tp",
+ "include": "stm32f4xx_hal_adc_ex.h"
+ },
+ {
+ "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h",
+ "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h",
+ "kind": "tp-tp",
+ "include": "stm32f4xx_hal_def.h"
+ },
{
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h",
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h",
@@ -8583,6 +8603,12 @@
"kind": "tp-tp",
"include": "stm32f4xx_hal_def.h"
},
+ {
+ "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_adc.h",
+ "to": "Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h",
+ "kind": "tp-tp",
+ "include": "stm32f4xx.h"
+ },
{
"from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_bus.h",
"to": "Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h",
@@ -8667,6 +8693,18 @@
"kind": "tp-tp",
"include": "stm32f4xx_hal.h"
},
+ {
+ "from": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c",
+ "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h",
+ "kind": "tp-tp",
+ "include": "stm32f4xx_hal.h"
+ },
+ {
+ "from": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c",
+ "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h",
+ "kind": "tp-tp",
+ "include": "stm32f4xx_hal.h"
+ },
{
"from": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c",
"to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h",
@@ -8787,6 +8825,12 @@
"kind": "fp-ext",
"include": "stdint.h"
},
+ {
+ "from": "Inc/adc.h",
+ "to": "Inc/main.h",
+ "kind": "fp-fp",
+ "include": "main.h"
+ },
{
"from": "Inc/dma.h",
"to": "Inc/main.h",
@@ -8855,8 +8899,8 @@
},
{
"from": "Inc/stm32f4xx_hal_conf.h",
- "to": "外部/系统头文件",
- "kind": "fp-ext",
+ "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h",
+ "kind": "fp-tp",
"include": "stm32f4xx_hal_adc.h"
},
{
@@ -38853,6 +38897,12 @@
"kind": "fp-tp",
"include": "lvgl.h"
},
+ {
+ "from": "Src/adc.c",
+ "to": "Inc/adc.h",
+ "kind": "fp-fp",
+ "include": "adc.h"
+ },
{
"from": "Src/dma.c",
"to": "Inc/dma.h",
@@ -38991,6 +39041,12 @@
"kind": "fp-tp",
"include": "cmsis_os.h"
},
+ {
+ "from": "Src/main.c",
+ "to": "Inc/adc.h",
+ "kind": "fp-fp",
+ "include": "adc.h"
+ },
{
"from": "Src/main.c",
"to": "Inc/dma.h",
@@ -39970,13 +40026,13 @@
"stddef.h",
"stdint.h"
],
- "Drivers/BSP/NETCFG/net_cfg_legacy.c": [
- "string.h"
- ],
"Drivers/BSP/SD2506/sd2506.c": [
"stdio.h",
"string.h"
],
+ "Drivers/BSP/TPAFE5160/tpafe5160.c": [
+ "string.h"
+ ],
"Drivers/BSP/UI/ui_content_page.c": [
"string.h"
],
@@ -40145,7 +40201,6 @@
"stdint.h"
],
"Inc/stm32f4xx_hal_conf.h": [
- "stm32f4xx_hal_adc.h",
"stm32f4xx_hal_can.h",
"stm32f4xx_hal_can_legacy.h",
"stm32f4xx_hal_cec.h",
@@ -41600,13 +41655,13 @@
]
},
"stats": {
- "files_indexed": 1420,
- "includes_parsed": 5700,
- "resolved": 4630,
- "unresolved": 1070,
+ "files_indexed": 1425,
+ "includes_parsed": 5706,
+ "resolved": 4637,
+ "unresolved": 1069,
"nodes_fp": 147,
- "nodes_tp": 1259,
- "ext_names": 352
+ "nodes_tp": 1264,
+ "ext_names": 351
},
"include_dirs": [
"Inc",
diff --git a/docs/images/引用关系图.svg b/docs/images/引用关系图.svg
index 0620af1b..ab0679a5 100644
--- a/docs/images/引用关系图.svg
+++ b/docs/images/引用关系图.svg
@@ -4,3941 +4,3947 @@
-