Files
STM32F4-Base/App/log
wandering1 d4867ddbe2 fix(algo): Q10 定值宏改单精度;收口 Flash 优化簇并更正审查报告三处误判
影响面:一个头文件宏(App/algo/prot_set.h)+ 七份文档口径;固件行为逐位
等价,无功能变化。门禁全绿后提交,未推送。

验证链
- @build:0 错 0 警;Code 213,520 → 213,188(−332 B),RO/RW/ZI 不变。
- 真机 @test PASS:戳 fw build: Oct 22 2026 10:36:15 suite=NONE;无
  [ERR]/ERROR/FAIL/Fault;708 ms 到 net init: OK;protect task start、
  i104: listening on 2404、[STACK] 三面水位齐。
- 主机单测:prot_set 90/90、prot_elm 47/47、iec104 97/97。
- 等价性穷举:宏内 42 个字面量;int32 全域 ÷1024 往返 4,494,305 例零
  差异;×1024 方向 20 万随机 float 零差异(×/÷1024 是 2^10 指数平移,
  不产生尾数舍入)→ 定值默认值/上下限、校验和、104 上送值全部不变。

F-6 双精度软浮点(已落地)
- 两个 Q10 宏去掉显式 (double)、1024.0 → 1024.0f:保护判据每 20 ms 每
  元件 3 次定值读取改走 F407 单精度 FPU,不再软件模拟。
- .map 里 dflti/d2f/f2d/dfixi/fepilogue 共 300 B 消失;自研侧对双精度
  helper 的引用归零。
- 更正报告归因:全库 0 处 %f(扫 App/Src/Inc/Drivers 共 173 个 .c/.h),
  剩下 dadd/dmul/ddiv/depilogue/dfixul = 1,018 B 由 MicroLIB printfa.o 的
  _printf_core → _fp_digits 无条件引用,只要还用 snprintf 就删不掉;
  报告"把 %f 改整数刻度"没有可执行对象。

F-4 LVGL 死代码(判定不做)
- 报告列的五项字节数逐字节仍准(合计 10,060 B),但没有一项有开关:
  根因是 lv_draw_sw.c 的 execute_drawing() 无条件 switch 引用全部 task
  类型,链接器 --remove 无从下手。
- 唯一总开关 LV_DRAW_SW_COMPLEX 被 ui_deco.c 的"浅 V"3 px 粗斜腿依赖
  (斜段与其所需 mask 核心都在该开关内);2026-09-03 已实测失败并把两端
  =1 固化 → UI_设计架构.md §1.4 第 7 条。
- 报告原"mask/grad 是文字与矩形绘制必经路径"证伪:字形走 blend 层
  mask_buf,不经 lv_draw_sw_mask_*。
- 剩余路线需给 Lib/lvgl 打本地补丁(上限 ≈16 KB),而 Flash 仅占 22.1%、
  无 OTA/双镜像预算 → 收益不抵代价;图片链同理不打补丁。

F-5 uvprojx 空 TU(降级为观察项)
- 实测 326 个 .c / LVGL 201 个 / .map 零产出 127 个;但增量构建 4~5 s、
  空 TU 只在全量重建或改 lv_conf.h 时才重编,且远程 CI 刻意不跑 @build。
- 报告原"编译时长 −40%"无基线记录,不复述;真要做用 Keil 原生
  <IncludeInBuild>0</IncludeInBuild>,且排在任何 lv_conf.h 改动之后。

文档与台账
- 审查报告 §0.1/§0.4/§1/注册表/§5.1/§5.4/§6.4/W4 行按实测更正,补
  2026-10-22 变更记录行与 F-4/F-6 记录去处行;登记簿 N-28 改写为"三项
  已判定、仅剩 F-5 观察项"。
- 更正 FTL 写回缓存旧口径(sys_log_mcu.c 注释、运行与自检记录设计说明
  §4.4、实机测试实施指南 §9.1):f_close 经 sync_fs → CTRL_SYNC →
  ftl_flush_cache 已落盘,"写另一个文件逼出脏页"不是必要条件;2026-10-02
  那次"复位后写入整段丢失"根因是 dhara resume 锚错 checkpoint。
- 部署环境要求 §3.3 资源预算由 2026-09-11 快照刷新为 2026-10-22 实测,
  并补 CCM 红线行(旧"SRAM 95.4%/极度紧张"的说法早已失效)。
- ram_baseline.py --update/--write、check_mem_numbers.py --write 已回填:
  mem-budget(SRAM1 57.4% / CCM 87.9%,阈值 92%)与 mem-numbers 转绿。
2026-10-22 11:03:05 +08:00
..

App/log/ — 日志子系统

两类日志:持久化运行日志(sys_log,落 NAND)与控制台日志(console_log,走串口)。 两者都遵循单写者模型,避免多任务交错输出。

文件一览

文件 作用
sys_log.h 日志接口(平台无关):定长 64B 记录写入 /log/run.log·selftest.log
sys_log_mcu.c sys_log 的 MCU 端后端实现(NAND + FatFs)
console_log.c/h 控制台单写者日志:多任务日志经队列汇入唯一写者,避免串口输出交错
soe_rec.c/h SOE 记录纯编解码(B9):64B 定长记录(CP56Time2a 时标 + 类型 + 元件号 + 单调序号 + 值 + sum8 撕裂校验),零 I/O 零 OS 依赖,主机单测覆盖
soe_store.c/h SOE 落盘胶水(B9):/log/soe.log,protectTask 投递(零文件系统)→ defaultTask 排空落盘

关键机制

syslog(运行/自检记录)

  • 唯一写者 = defaultTask;其它任务只投递,不直接写盘
  • 单记录定长 64 B,循环写;待机页可显示记录
  • 内核启动前的日志走无锁静态缓冲 s_preboot[8] 暂存(因为内核启动前不能建队列), 内核启动后由 syslog_drain 惰性创建真队列并排空
  • ⚠️ 写盘必须校验 f_write 返回的字节数(该 FatFs 移植在簇分配失败时返回 FR_OK + 短写, 不报错误码);追加写必须 FA_WRITE|FA_OPEN_APPEND(FA_OPEN_APPEND 单独用不含写位)

console_log(控制台单写者)

  • 多任务的生产者 → 单写者消费者,消除任务间日志行交错
  • 设计详见 docs/子系统设计/控制台单写者日志设计说明.md

soe(SOE 事件顺序记录,B9)

  • 记录 = 64 B 定长二进制(soe_rec.h 布局),落 /log/soe.log; 与 run.log 分文件——run.log 是文本记录、有 UI/主机读取方,二进制 SOE 混入会破坏读取器;分文件保持"定长 64B + 条数=fsize/64 + 满删重建 + FTP 下载 + 主机解码"同一套先例
  • 生产者 = protectTask(元件动作/返回、软压板投退、采样闭锁/恢复六类 边沿):soe_store_post() 纯 RAM(取时标 + 组记录 + 队列/待发环), 零 NAND I/O;⚠️ post 内禁 DBG_*——会把 protectTask 静态最坏链 垫高一帧(实证 872→1192 B FAIL),丢弃留痕由 drain(defaultTask)差值上报
  • 唯一写者 = defaultTask:挂 syslog_drain() 尾部(继承其卷就绪门), 50 ms 节拍 → SOE 落盘延迟 ≤50 ms;写盘纪律全套照 syslog(卷锁 try / FA_WRITE|FA_OPEN_APPEND / 校验字节数 / 满删重建 / 失败留痕去重), 绝不把名字/参数类错误码归入卷损坏触发集
  • 时标口径:sys_clock 秒域时基 → CP56 ms 域 = 秒×1000(亚秒恒 0, 不造假);墙钟未建 → IV 位如实置位;seq 仅上电生命周期内单调 (容量重建不重置,仅复位重置——主机解码按 boot 段分段断言)
  • 主机侧:test/host/soe/decode_soe.py 解码 + 断言(校验和/seq 单调/ CP56↔epoch UTC 交叉);⚠️ 交叉校验用 calendar.timegm,不是本地时区的 dt.timestamp()(+08 机差 28800 s,首跑实证坑)

相关文档

  • docs/子系统设计/控制台单写者日志设计说明.md
  • docs/子系统设计/运行与自检记录设计说明.md
  • FatFs 陷阱:AGENTS.md「平台约束」