栈整改不抬栈:删旧档迁移、FIL静态化、日志行缓冲按模块收紧、钩子脱离HAL,defaultTask链5312→2776B
This commit is contained in:
+1
-1
@@ -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) |
|
||||
|
||||
+4
-3
@@ -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` — 网络段
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 堆)
|
||||
|
||||
+70
-4
@@ -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 调用)
|
||||
* 函数说明:同样只把字节交给单写者路径;未注册写者时直发(与旧行为一致)
|
||||
|
||||
@@ -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 钩子,须为全局符号)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
+13
-2
@@ -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();
|
||||
|
||||
+3
-2
@@ -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 销项)。
|
||||
|
||||
## 设计要点
|
||||
|
||||
Reference in New Issue
Block a user