Files
STM32F4-Base/AGENTS.md
T
wandering1 40a2816a99
CI / 静态门禁 (pre-commit) (push) Failing after 4m15s
CI / 主机侧单测 (MSVC) (push) Failing after 1m41s
feat(adc): UN 标定完成、标定脚本归集到 test/host/cal/
- UN 通道 5 点最小二乘标定完成:r=555.382141, b=-1, 残差 0.038%, R²=0.99999967
- UA/IA/UN 三路 VALID 置位,保护解卡
- ROM 默认值更新为当前标定值(ADC_CAL_R_Q16_VOLT=555.144958)
- UB/UC/UN 通过 104 写入 ROM 默认值,config.ini 同步
- cal_fit.py 新增 ROLD 表自动读取,不再需要手传 --r-old
- 执行卡精简至 126 行,新增 cal_collect.py 采集脚本与 ROLD 填表
- 标定脚本(cal_fit/cal_write/cal_collect)归集到 test/host/cal/
- 全库文档路径引用同步更新(8 文件)
- UN 当前态文档改写:明确零序电压 U0 语义、本台架未接线状态
- 删除已失效的外部知识底座文档链接
2026-11-13 11:26:36 +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/配置)**已实现并台架验收**;采集主线已闭环到业务消费者(UA/IA 两路已由 5 点最小二乘标定落盘,见 `docs/硬件平台/ADC通道映射说明.md` §7.5);⚠ **保护判据现处于「未标定闭锁」态**——`adc_cal_prot_blocked()` 要求 UA/UN/IA 三路 VALID 齐,**UN 通道在本台架永久无数据**(台架无接线、该端子只读噪声底,用户裁定 2026-11-13 不再测),故保护永久闭锁、不许伪造 VALID;**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) |