Files
STM32F4-Base/AGENTS.md
T
wandering1 1355dbe1b1 fix(cfg): 配置热重载吞段缺陷修复 + 两点标定工具链与台架实测落档
修复运行期改配置被打回出厂值的缺陷:cfg_file_poll() 按段循环复用同一
份读缓冲,而 s_parse() 通过 s_split_line()/s_key_value() 就地改写缓冲
(把换行与等号换成 NUL)。第一个段解析完,缓冲里已没有键值行,后续 7
个段静默保持出厂值;随后 run_par_store_save() 又把这份出厂值写回
config.ini,用户的标定值被永久覆盖。开机路径 cfg_file_load() 只解析一
轮,所以该缺陷长期不可见,只在运行中改配置时发作。

- s_parse() 改为非破坏性:入参 const char *,逐行 memcpy 到栈缓冲
  (CFG_LINE_TEST_MAX + 1)后再交给会破坏缓冲的解析子函数;超长行跳
  过(保存侧已拒绝落盘超长受管键行)。
- 新增 TC-CONFIG-063:同时改两段内容,断言第二个注册段也重载成功、
  含负值 INT 键存活,把「热重载吞段」钉成机器面。

新增两点标定台架工具链(test/host/):
- cal_two_point.py:整数算术镜像 adc_cal_two_point(),支持单路模式与
  从执行卡 CALDATA 表批量求解(--from-doc),带合法带与零点自检拦截。
- cal_write.py:复用 iec104_master 作库,经 104 定值段写 r 后写 b 并
  读回校验,是所有写入的唯一入口。

adc_task 的 meas: 心跳行精度提到 4 位小数,标定读数需要。

文档:新增《采样数据校正全流程》(端到端导航)与《ADC 两点标定执行
流程》(台架执行卡,含 CALDATA 可填表);ADC通道映射说明新增 §7.3 台
架实测结果(UA 554.687914、IA 29.634259,出厂默认值保持不变);配置
文件设计说明新增解析器契约 v1.19;采集与算法层设计说明 §13 系列与
README 索引同步。

台架实测:UA r=554.687914(出厂 1000.0 偏大 1.80 倍,根因是接线分压
使 PT 一次侧只拿到一半电压,实测与参数算定 606.06 只差 8.5%)、IA
r=29.634259(与出厂 29.4118 只差 0.76%,反证链路未算错)。UN 按用户
裁定本轮不标定,保护闭锁(vl=0x11)是预期行为,未伪造 VALID。

同时入库 .dsh/roles 角色定义(原被 .gitignore 挡住)。
2026-11-13 01:35:58 +08:00

185 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# STM32F4-Base
**工业级嵌入式 DTU 平台固件**:STM32F407ZGTx @168MHz,集成以太网(CH395F)、SPI NAND 存储(GD5F)、电气量采集(TPAFE5160 + 片内 ADC)、RS-485、FTP 文件服务,自带远程显示(UI 推流)、墙钟对时、看门狗自恢复、运行/自检记录——既是可独立部署的现场设备,也是**可复用的平台底座**。产品基线 → `docs/产品需求/产品需求设计文档.md` §2.1。
**仅 Keil MDK-ARM v5 (ARMCC, C99)**;FreeRTOS V10.3.1 / CMSIS-RTOS2;192KB SRAM / 1MB Flash。
**任何代码修改后必须先 `/keil-build` 验证(0 错误 0 警告)再提交;硬件闭环用 `/serial-boot-test`。**
> 本文件 = agent 入口:宏观概况 + 每次都在场的铁律在这里,细节在 `docs/` 与 skills(文末索引)。同一事实只在一处详述。
## 项目概况
**现状一句话**:平台能力(网络/存储/时间/UI/日志/看门狗/FTP/配置)**已实现并台架验收**;采集主线已闭环到业务消费者;⚠ **保护判据现处于「未标定闭锁」态**(用户裁定 2026-10-25:保持闭锁);**RS-485 采集尚未接线**(按用户决策冻结)。
**数据主线**(分层图与跨层依赖表 → `docs/架构设计/项目架构总览.md`):
- **采集**:TPAFE5160 + ADC1 → TIM3 1kHz → adcTask → 语义取数 → 傅氏相量 → 测频/遥测快照 + 保护判据 → 104 上送
- **存储**:GD5F → dhara FTL → FatFs → 日志/配置/FTP
- **网络**:CH395F → netTask 串行 socket → FTP/RemoDispBus/IEC 60870-5-104;SNTP 对时
- **人机**:LVGL 160×160 单色菜单,与 PC 模拟器同一份 UI 源码
**目录地图**(只列顶层;细结构自己 `ls`;**仓库根不放一次性产物**,进 `ci-artifacts/`):
| 目录 | 职责 | 可改性 |
|---|---|---|
| `Src/` `Inc/` | CubeMX 生成 | **只写 `USER CODE` 区** |
| `App/` | 应用层(task/algo/cfg/log/fs/sync/util) | 手写 |
| `Drivers/BSP/` | 手写芯片驱动与服务 | 手写 |
| `Drivers/STM32F4xx_HAL_Driver/` `CMSIS/` `Middlewares/` | 第三方 | 只读 |
| `Lib/` | 第三方库(lvgl/FatFs/dhara) | 只读 |
| `MDK-ARM/` | Keil 工程 | UV4 抖动不入库 |
| `simulator/` | LVGL PC 模拟器 | 手写 → `lvgl-simulator` skill |
| `test/` | board/ 板级套件 · host/ 主机侧单测 | 手写 |
| `scripts/` `tools/` | 门禁脚本 · 生成器 | 手写 |
| `docs/` | 全量文档(索引 `docs/README.md`) | 手写 |
| `.dsh/` | skills · roles · plugins | 手写 |
**分层边界**:上层只依赖相邻下层(**单向**);新算法进 `App/algo/`,勿塞 `App/task/`;新 `.c` 必须双端注册(`new-source-file` skill)。
## 架构要点
启动流程与任务详情 → `docs/架构设计/项目架构总览.md`、`docs/架构设计/项目启动顺序管理.md`
<!-- TASK_TABLE:BEGIN generated by scripts/gen_task_table.py -->
| Task | 栈 (words) | 优先级 |
|---|---|---|
| defaultTask | 1280 | Normal |
| netTask | 960 | Normal |
| ftpTask | 1024 | Normal |
| testTask | 2048 | BelowNormal |
| uiTask | 4096 | BelowNormal |
| timeSyncTask | 640 | Normal |
| adcTask | 640 | AboveNormal |
| iec104Task | 640 | Normal |
| protectTask | 512 | Normal |
<!-- TASK_TABLE:END -->
(实际值以 `Src/freertos.c` 为准;RAM 台账 → `docs/内存管理/RAM预算台账.md`)
## 铁律:源码编辑与编码
- 改代码**只用 Edit 工具**;**绝不用 shell 重写含中文的文件**(乱码不可逆)
- **Edit 会剥 BOM**:带 BOM 文件编辑后须补回 → `bom-guard` 钩子自动拦截。带 BOM 名单(三处互指:本行、钩子 `files` 正则、`scripts/check_bom_drift.py` 的 `BOM_LIST`):`Drivers/BSP/UI/`(整目录)、`App/task/ui_task.c`、`App/cfg/cfg_file.c`、`Lib/lv_conf.h`
- **字符串字面量必须纯 ASCII**:中文只写注释
- **注释里别写星号形态的路径**(ARMCC 诊断 9-D)→ `nested-comment` 钩子
- 行尾由 `.gitattributes` 写死 LF;**不依赖 `core.autocrlf`**
- 代码规范 V1.0 → `docs/代码规范/`
- **SKILL.md 有 65536 字节写侧上限**:超限技能永久卡在「生成中」→ `skill-size` 钩子;深规程写进 `reference/`
## 构建与验证
- **门禁时机**:`/keil-build` / `ci_local.py` **只在准备提交时跑**,不是每次改动后都跑
- `/keil-build` / `/serial-boot-test` / `/task-worktree` 是 **DSH 技能调用名**,不是 shell 命令
- 编译 → `keil-build` skill;串口回归 → `serial-boot-test` skill
- **烧录必须 `-Rst -Run` + 回读校验**;`-CmpFile` 会复位目标,排在采日志之后 → `stlink-flash` skill
## Python 环境
- 统一入口 `& '.venv\Scripts\python.exe'`(3.12);PATH 上的 python 是 msys64 的,**不要用**
- 重建:`python -m venv .venv` + `pip install -r requirements.txt`;`requirements.txt` 必须纯 ASCII
## 提交门禁(pre-commit)
共 **52 个钩子**(提交期实跑 49 根,3 根慢钩子由远端 CI 强制)。**每种门禁一篇详解 → `docs/门禁说明/README.md` 索引**;通用机制 → `docs/代码规范/pre-commit使用说明.md`。
- 任一失败即拦截
- 范围 = 项目代码(第三方排除;`simulator/` 已纳入)
- pre-commit 4.x 已移除 `always: true`,想"总是跑"必须让 `files:` 覆盖
- 改写型钩子豁免 CubeMX/Keil 生成文件;只读检查不受影响
- 提交信息:标题 ≤100 字符、正文每行 ≤80;长说明用 `git commit -F <文件>`
- CI 只跑静态门禁 + 主机侧单测,**不跑 `/keil-build`** → [`docs/CI/README.md`](docs/CI/README.md)
## 平台约束
详细实现与实测坑 → 各子系统文档(见文末索引)。以下只列**禁令与关键数值**:
**CubeMX 与 Fault**
- 自定义代码**只写 USER CODE 区**;重生成会覆盖区外一切 → 每次重生成后跑 `cubemx-survival` 钩子
- ARMCC `__asm` 只有整函数形态合法 → `docs/子系统设计/看门狗设计说明.md` §10
- 4 个 Fault 全部采集现场;`fault_handler_enable()` 必须在 `app_main_init()` **第一行**
**RTOS 与内存**
- `osKernelStart` 之前**禁止**任何 RTOS 创建类 API
- 就绪屏障位必须 `osFlagsNoClear`
- **自研代码禁用 C 库堆分配**(MicroLIB 堆仅 512B)→ `coding-standard` 钩子拦截
- 新增任务/缓冲/栈前先核算 RAM 余量;`mem-budget` 钩子拦 >92%
- HAL 时基 = TIM7,tick = 1ms;NVIC 外设中断优先级 ≥ 5
**采集链**
- ADC 取数只用 `tpafe5160_snapshot()`(原子快照);消费者经 `adc_input_poll()` 按语义取数
- ADC1 必须用 TIM3 触发、DMA2 Stream4、`DMAContinuousRequests` ENABLE
- ADC 上电必须自校准(CubeMX 不生成)
- RS-485 接线门禁:驱动契约未修完前不得接消费者
**存储与网络**
- FatFs 追加写必须 `FA_WRITE|FA_OPEN_APPEND`;`f_write` 须校验写回字节数;`FF_USE_LFN=0` 仅 8.3 短名
- CH395F SPI 分频必须为 8;事务须 begin/end 包裹
**日志**
- `DBG_*` 每条约 90B Flash + 216B 栈;深调用链模块须预定义 `DBG_LINE_BUF_MAX`
- `*.uvprojx` 每次构建后被 UV4 改写,**一律不入库**
## 硬件引脚
- 完整引脚表 → `docs/架构设计/硬件规格与能力边界.md` §2
- ⚠ 网名 ≠ 板级 ADC ≠ 转换器通道号 → `docs/硬件平台/ADC通道映射说明.md`
- ⚠ V0.1 硬件缺陷:8 路分给两片转换器,**禁止**跨转换器做相位运算
## 模块约定
- CH395F 全局中断**整体读即清**,不得在 ISR 单独处理 → `docs/网络/网络自愈架构设计.md` §4.10
- `net_*` 操作经 `netMsgQueue` 串行;错误码经 `xTaskNotify` 回传
- 单连接 socket EOF 时**不得** `net_close`(net 层已 auto_relisten)
- 网口/FTP 配置 → `/config.ini` → `docs/子系统设计/网络配置说明.md`
- 新 .c 必须双端注册(uvprojx + CMakeLists.txt)→ `new-source-file` skill
- 测试构建套件互斥(`test_config.h`);破坏性测试默认关闭 → `board-test-suite` skill
- 改驱动前读 `docs/问题记录/*_Trap_Records.md`
- 改 UI 前读 I1 palette / 白底白字两条实证坑 → `ui-verify` skill
## 文档与图形
- 待办「完成即销项」:修复后删行,不保留"已消化"行;新条目用**语义短语**标识,**不再发编号** → `docs/任务规划/README.md` §0
- 图形走 `draw-diagram` skill;精确布局图用生成器,拓扑图用 Mermaid
- 改名/挪目录走 `scripts/rename_ref.py`;编号改名走 `scripts/rename_ids.py`;**绝不全局查找替换**
- 文档写作规范 → `docs/文档规范.md`;全量索引 → `docs/README.md`
## 委派策略(Agent Teams 优先)
**复杂任务一律用 Agent Teams**(`spawn_teammate` + `send_message`),不用单独的 `subagent` / `subagent_role`。
- **Lead**:拆解任务、分配 teammate、协调跨域、汇总结果。不直接做模块级实现。
- **Teammate**:专注自己领域,跨域问题告知 Lead 转交。
- **角色绑定**:prompt 第一行写 `@role:<角色id>`(如 `@role:algo-specialist`),插件自动注入 persona + 工具策略。**不得省略**。角色定义 → `.dsh/roles/README.md`。
- **判断标准**:涉及两个以上模块、需要构建+测试+文档联动 → Agent Teams。单文件小改 → `subagent_role` 可接受。
## 边界(Ask first / Never)
**Ask first**:`git commit/push` · 开 `ENABLE_DESTRUCTIVE_TESTS` · CubeMX 重生成 · 待办销项 · 建任务/抬栈/加大缓冲
**Never**:shell 重写中文文件 · `git checkout/reset --hard` 丢弃未提交工作 · USER CODE 区外写代码 · C 库堆分配 · 非 defaultTask 碰配置引擎 · 非 netTask 碰 CH395F · 提交 uvprojx 抖动 · 提交 `.mnemon/`
## 按主题查哪份文档
| 主题 | 去处 |
|---|---|
| 全量索引 / 推荐阅读顺序 | `docs/README.md` |
| 架构全景 / 启动时序 | `docs/架构设计/项目架构总览.md`、`项目启动顺序管理.md` |
| 产品需求基线 | `docs/产品需求/产品需求设计文档.md` |
| 看门狗 + CubeMX + ARMCC __asm | `docs/子系统设计/看门狗设计说明.md` §10 |
| ADC 采样 / 通道映射 / V0.1 缺陷 | `docs/子系统设计/ADC采样节拍设计说明.md`、`docs/硬件平台/ADC通道映射说明.md` |
| 存储栈 / FatFs 陷阱 | `docs/架构设计/STM32F4-Base存储架构说明.md` |
| RAM / 栈预算 | `docs/内存管理/RAM使用分析与优化方案.md`、`RAM预算台账.md` |
| 每个门禁详解 | `docs/门禁说明/README.md` |
| 编号规范(一律不发编号) | `docs/文档规范.md` §7.1 |
| 门禁通用机制 | `docs/代码规范/pre-commit使用说明.md` §2 |
| 代码规范 / cppcheck | `docs/代码规范/嵌入式C语言代码规范_V1.0.md`、`cppcheck使用说明.md` |
| 测试流程 / 板级套件 | `docs/测试说明/`、`board-test-suite` skill |
| 烧录与复位 | `docs/测试说明/测试工具/ST-LINK_CLI_复位使用说明.md` |
| 串口助手 | `serial-assistant` skill |
| UI / 模拟器 / 自动化回归 | `lvgl-simulator` skill、`ui-verify` skill |
| 板端 UI 交互 | `board-ui-nav` skill |
| 待办与推进顺序 | `docs/任务规划/README.md` |
| 并行开发 / worktree | `task-worktree` skill、`docs/环境与部署/并行任务工作树方案.md` |
| 换机 / 环境变量 | `docs/环境与部署/` |
| 远程 CI | [`docs/CI/README.md`](docs/CI/README.md) |