diff --git a/docs/子系统设计/控制台单写者日志设计说明.md b/docs/子系统设计/控制台单写者日志设计说明.md index 17f1c69b..42e2a21b 100644 --- a/docs/子系统设计/控制台单写者日志设计说明.md +++ b/docs/子系统设计/控制台单写者日志设计说明.md @@ -1,7 +1,7 @@ # 控制台单写者日志设计说明 -> **版本**:v1.1(已实施) -> **日期**:2026-09-25 +> **版本**:v1.5(已实施;修订史见文末「修订记录」) +> **日期**:2026-10-24(v1.5;初版 v1.0 于 2026-09-25) > **状态**:已实施并验证——`@build` 0 错误 0 警告、`@test` 硬件闭环 PASS(2026-09-25,见 §10);设计 2026-09-24 加固实施(当时位于 `Src/usart.c` USER CODE 区),2026-09-25 实现迁出至 `App/log/`(HAL 生成文件不含应用代码);同日写者任务体自 `Src/freertos.c` 迁至 `App/task/default_task.c`(与其余 5 任务文件同址归位) > **关联文档**:`项目架构总览.md` · `运行与自检记录设计说明.md`(姊妹模块:持久化日志,同一写者任务) · `测试说明/链路延迟测试说明.md`(D6 日志税 / S8 非阻塞日志,需求出处) · AGENTS.md「平台约束」 @@ -351,5 +351,5 @@ sequenceDiagram | v1.1 | 2026-09-25 | 文件拆分同步:写者任务体迁至 `App/task/default_task.c`(`Src/freertos.c` 只留 CubeMX 接线与崩溃钩子);§3.2 文件清单 / §4.3 / §6 / §11 位置引用更新 | | v1.2 | 2026-10-02 | 新增 §12 ORE 僵尸通道(台架 gen-288 实证:节奏性喂狗饥饿,非死等;缓解已做、TX-only 根治待办)+ §11 时间线两条 10-02 记录;§13 新增 O4;原 §12/§13 顺延为 §13/§14 | | v1.3 | 2026-10-10 | 栈链整改(**未抬栈**)三处:① 裸发改为纯寄存器轮询——DWT 不可用时走 `con_tx_counted`(计数上界),**不再回退 `HAL_UART_Transmit`**(tick 依赖不可信 + 其调用链污染所有任务最坏栈链);② 切断 `drain → syslog_post → write_line` **调用图成环**,改为置标志 + 写者任务在 drain 之外补记(新 API `dbg_console_tx_fault_log_take`);③ 行缓冲按模块可收紧(`dbg_log.h` 新增 `DBG_LINE_BUF_MAX`,深链模块 128)+ 时间戳缓冲并入行缓冲(32 → 24)。§4.4 / §5 / §6 / §7 / §8 同步;实测 defaultTask 静态最坏链 5312 → 2776 B | -| v1.5 | 2026-10-24 | **主机单测批次照出的四条现状全部处置**(生产码在 `App/log/console_log.c`,用例在 `test/host/console_log/`):① 冷却判据改用独立 `s_con_cooling` 标志,不再拿 `HAL_GetTick()` 的 0 值当哨兵——旧写法在 tick==0 那一拍(开机头 1 ms,或 49.7 天回绕到 0)冷却等于没记;② `con_append` 的空位判据 / 推进 head / 整行拷贝收进同一临界区——旧实现是临界区外 check-then-act,多生产者可在环 >95% 满时双双过判据把 head 推过容量 → 静默覆盖且**既不打 [ERR] 也不计 dropped**;③ `Instance == NULL`(未初始化)与僵尸通道**分诊**,未初始化绝不 reinit(旧路径会在 HAL 未就绪时经 MspInit 重配 RCC/GPIO);④ 三本账,见本文 §13-O2。**dropped 的单位口径变了**:一次 = 一行(缓冲满)或一个块(没能确认送达 / 通道不可用),故 `[ERR] CONSOLE dropped N lines` 的 N **不恒等于行数**(为兼容 `@test` 标记匹配,文案未改词)。本文 §3.1 与 §4.1 的「单生产者 vs 全上下文生产者」矛盾一并消除 | | v1.4 | 2026-10-10 | 新增 `dbg_console_writer_ready()`(写者就绪查询)并固化"未注册期只有 defaultTask 记日志、周期任务用就绪门控"纪律;更正 §3.4 / §7 / §9-D5 / §13-O1 的"只丢不交错"旧结论(裸发已改寄存器级轮询、无 `gState` 互斥) | +| v1.5 | 2026-10-24 | **主机单测批次照出的四条现状全部处置**(生产码在 `App/log/console_log.c`,用例在 `test/host/console_log/`):① 冷却判据改用独立 `s_con_cooling` 标志,不再拿 `HAL_GetTick()` 的 0 值当哨兵——旧写法在 tick==0 那一拍(开机头 1 ms,或 49.7 天回绕到 0)冷却等于没记;② `con_append` 的空位判据 / 推进 head / 整行拷贝收进同一临界区——旧实现是临界区外 check-then-act,多生产者可在环 >95% 满时双双过判据把 head 推过容量 → 静默覆盖且**既不打 [ERR] 也不计 dropped**;③ `Instance == NULL`(未初始化)与僵尸通道**分诊**,未初始化绝不 reinit(旧路径会在 HAL 未就绪时经 MspInit 重配 RCC/GPIO);④ 三本账,见本文 §13-O2。**dropped 的单位口径变了**:一次 = 一行(缓冲满)或一个块(没能确认送达 / 通道不可用),故 `[ERR] CONSOLE dropped N lines` 的 N **不恒等于行数**(为兼容 `@test` 标记匹配,文案未改词)。本文 §3.1 与 §4.1 的「单生产者 vs 全上下文生产者」矛盾一并消除 |