新增产品需求设计文档:完整产品需求基线
基于项目全量内容编写 docs/产品需求/产品需求设计文档.md,作为面向 产品的需求基线,覆盖: - 产品概述:定位、形态与部署、设计目标与原则、产品范围 - 系统架构:六层分层、六任务模型、就绪屏障、启动时序、线程间通信 - 硬件规格:主控/内存、V0.1 外设引脚、存储器件、版本差异、平台约束 - 功能需求:网络/存储/时间/配置/日志/UI/看门狗/LED(已实现)+ ADC/RS-485(待实现) - 接口规范:端口、RemoDispBus、对时、FTP、配置格式、串口、对外 API - 非功能需求:可靠性、性能指标、内存预算、测试门禁、双端、权限 - UI 规格:屏幕/菜单树 42 节点/内容页/密码/字体 - 待实现项与路线图(阶段 B/C/D)、验收判据(构建/自检/现场/台架) 同步在 docs/README.md 新增 §3 产品需求、§2 阅读顺序置顶、§1 目录树 登记产品需求/,后续章节号顺延。
This commit is contained in:
+41
-30
@@ -12,6 +12,7 @@
|
||||
docs/
|
||||
├── README.md 本索引(阅读顺序 + 全量清单)
|
||||
├── 待处理内容.md 统一待办登记簿(高频入口,保留在顶层)
|
||||
├── 产品需求/ 产品需求设计文档(面向产品的需求基线)
|
||||
├── 架构设计/ 全局架构与设计方法论
|
||||
├── 子系统设计/ 各功能子系统的设计说明
|
||||
├── 网络/ BSD Socket API 使用与内部实现
|
||||
@@ -38,23 +39,32 @@ docs/
|
||||
|
||||
| 顺序 | 文档 | 读它能得到什么 |
|
||||
|:---:|---|---|
|
||||
| 1 | [`项目架构总览.md`](架构设计/项目架构总览.md) | 六层分层、启动时序、存储/网络/UI 三栈、目录组织 |
|
||||
| 2 | [`项目启动顺序管理.md`](架构设计/项目启动顺序管理.md) | Event Flags 就绪屏障(取代魔法延时)的任务启动模型 |
|
||||
| 3 | [`项目部署环境要求.md`](环境与部署/项目部署环境要求.md) | 开发机/目标板/现场部署的完整环境核对清单 |
|
||||
| 4 | [`项目部署环境要求.md`](环境与部署/项目部署环境要求.md) → 构建 | 跑通 `@build` / `@test`(见根 `AGENTS.md`) |
|
||||
| 5 | [`测试开发标准流程.md`](测试说明/测试开发标准流程.md) | 测试分层 L0~L3 与门禁决策表 |
|
||||
| 6 | [`嵌入式C语言代码规范_V1.0.md`](代码规范/嵌入式C语言代码规范_V1.0.md) | 命名/格式/注释规范(提交门禁强制) |
|
||||
| 7 | [`项目架构总览.md`](架构设计/项目架构总览.md) → 按需 | 进入具体子系统设计文档 |
|
||||
| 1 | [`产品需求设计文档.md`](产品需求/产品需求设计文档.md) | 产品定位、功能/非功能需求、接口规范、UI 规格、路线图与验收判据 |
|
||||
| 2 | [`项目架构总览.md`](架构设计/项目架构总览.md) | 六层分层、启动时序、存储/网络/UI 三栈、目录组织 |
|
||||
| 3 | [`项目启动顺序管理.md`](架构设计/项目启动顺序管理.md) | Event Flags 就绪屏障(取代魔法延时)的任务启动模型 |
|
||||
| 4 | [`项目部署环境要求.md`](环境与部署/项目部署环境要求.md) | 开发机/目标板/现场部署的完整环境核对清单 |
|
||||
| 5 | [`项目部署环境要求.md`](环境与部署/项目部署环境要求.md) → 构建 | 跑通 `@build` / `@test`(见根 `AGENTS.md`) |
|
||||
| 6 | [`测试开发标准流程.md`](测试说明/测试开发标准流程.md) | 测试分层 L0~L3 与门禁决策表 |
|
||||
| 7 | [`嵌入式C语言代码规范_V1.0.md`](代码规范/嵌入式C语言代码规范_V1.0.md) | 命名/格式/注释规范(提交门禁强制) |
|
||||
| 8 | [`项目架构总览.md`](架构设计/项目架构总览.md) → 按需 | 进入具体子系统设计文档 |
|
||||
|
||||
**按角色**:
|
||||
- **应用/驱动开发** → §3 架构设计 → §4 子系统设计 → §6 问题记录(**改驱动前必读对应 Trap Records**)
|
||||
- **测试/验证** → §5 测试说明 → §2 环境与部署
|
||||
- **UI 开发** → §7 UI 设计 → §5 测试说明(串口助手、UI 自动化测试流程)
|
||||
- **接手/评审** → §8.1 评审报告 → §8.3 待处理内容(统一待办登记簿)
|
||||
- **应用/驱动开发** → §4 架构设计 → §5 子系统设计 → §7 问题记录(**改驱动前必读对应 Trap Records**)
|
||||
- **测试/验证** → §6 测试说明 → §9.2 环境与部署
|
||||
- **UI 开发** → §8 UI 设计 → §6 测试说明(串口助手、UI 自动化测试流程)
|
||||
- **接手/评审** → §9.1 评审报告 → §9.3 待处理内容(统一待办登记簿)
|
||||
|
||||
---
|
||||
|
||||
## 3. 架构设计
|
||||
## 3. 产品需求
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
| [`产品需求设计文档.md`](产品需求/产品需求设计文档.md) | **面向产品的需求基线**:产品定位与形态、六层架构与任务模型、V0.1 硬件规格、功能需求(网络/存储/时间/配置/日志/UI/看门狗/LED + 待实现的 ADC/RS-485)、接口规范(RemoDispBus / 对时 / FTP / 配置 / 串口)、非功能需求(可靠性/性能/内存/门禁/双端)、UI 规格、待实现项与路线图、验收判据 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 架构设计
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
@@ -66,7 +76,7 @@ docs/
|
||||
|
||||
---
|
||||
|
||||
## 4. 子系统设计
|
||||
## 5. 子系统设计
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
@@ -81,7 +91,7 @@ docs/
|
||||
| [`网络/Net层阻塞模型架构设计.md`](网络/Net层阻塞模型架构设计.md) | **等待模型**:pending 请求架构、五路完成语义、设计边界与性能特征 |
|
||||
---
|
||||
|
||||
## 5. 测试说明
|
||||
## 6. 测试说明
|
||||
|
||||
**总流程与规范**
|
||||
|
||||
@@ -125,9 +135,9 @@ docs/
|
||||
|
||||
---
|
||||
|
||||
## 6. 代码规范 · 文档规范 · 内存管理 · 问题记录
|
||||
## 7. 代码规范 · 文档规范 · 内存管理 · 问题记录
|
||||
|
||||
### 6.1 代码规范(提交门禁相关)
|
||||
### 7.1 代码规范(提交门禁相关)
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
@@ -135,13 +145,13 @@ docs/
|
||||
| [`pre-commit使用说明.md`](代码规范/pre-commit使用说明.md) | 提交门禁配置、检查范围与排除项 |
|
||||
| [`cppcheck使用说明.md`](代码规范/cppcheck使用说明.md) | cppcheck 配置与告警处置 |
|
||||
|
||||
### 6.1b 文档规范(写/改文档前必读)
|
||||
### 7.1b 文档规范(写/改文档前必读)
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
| [`文档规范.md`](文档规范.md) | **文档体系强制约定**:目录/命名(无空格)、编码换行、链接形态(互链用根相对、图片用目录相对)、`[计划]` 标记、门禁三档、结构要素与常见错误速查 |
|
||||
|
||||
### 6.2 内存管理(**新增任务/缓冲/栈前必读**)
|
||||
### 7.2 内存管理(**新增任务/缓冲/栈前必读**)
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
@@ -150,7 +160,7 @@ docs/
|
||||
| [`存储栈RAM优化调研.md`](内存管理/存储栈RAM优化调研.md) | 存储栈 RAM 优化调研与结论 |
|
||||
| `data/` | `ram_report_*.md` / `stack_report_*.md` 快照数据(由 `scripts/` 生成) |
|
||||
|
||||
### 6.3 问题记录(**改驱动前必读**)
|
||||
### 7.3 问题记录(**改驱动前必读**)
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
@@ -161,7 +171,7 @@ docs/
|
||||
|
||||
---
|
||||
|
||||
## 7. UI 设计
|
||||
## 8. UI 设计
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
@@ -177,21 +187,21 @@ docs/
|
||||
|
||||
---
|
||||
|
||||
## 8. 评审报告 · 环境与部署 · 外部资料
|
||||
## 9. 评审报告 · 环境与部署 · 外部资料
|
||||
|
||||
### 8.1 评审报告
|
||||
### 9.1 评审报告
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
| [`问题记录/项目审查与优化建议报告.md`](问题记录/项目审查与优化建议报告.md) | 项目全景审查:文档/代码/架构/可靠性问题清单(D-1~D-7、N-xx、Px-xx)——**体系层评审报告,非待办池**(待办见 §8.3 `待处理内容.md`) |
|
||||
| [`问题记录/项目审查与优化建议报告.md`](问题记录/项目审查与优化建议报告.md) | 项目全景审查:文档/代码/架构/可靠性问题清单(D-1~D-7、N-xx、Px-xx)——**体系层评审报告,非待办池**(待办见 §9.3 `待处理内容.md`) |
|
||||
|
||||
### 8.2 环境与部署
|
||||
### 9.2 环境与部署
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
| [`项目部署环境要求.md`](环境与部署/项目部署环境要求.md) | 开发机软件环境、目标板资源预算、现场部署与验收步骤 |
|
||||
|
||||
### 8.3 台账与外部资料
|
||||
### 9.3 台账与外部资料
|
||||
|
||||
| 位置 | 内容 |
|
||||
|---|---|
|
||||
@@ -202,7 +212,7 @@ docs/
|
||||
|
||||
---
|
||||
|
||||
## 9. 新增文档约定
|
||||
## 10. 新增文档约定
|
||||
|
||||
1. **目录归属**:按上表选目录;新子领域先建**无空格**目录名(如 `xxx设计/`),并在此索引登记。
|
||||
2. **命名**:主题词 + 类型后缀(`xxx设计说明.md` / `xxx_Test_Guide.md` / `xxx_Trap_Records.md`)。
|
||||
@@ -216,7 +226,7 @@ docs/
|
||||
|
||||
---
|
||||
|
||||
## 10. 已知文档问题(待清理)
|
||||
## 11. 已知文档问题(待清理)
|
||||
|
||||
> 来源:《项目审查与优化建议报告》D-3/D-7。
|
||||
> **D-3 / D-6 / D-7 已处理完毕**(2026-09-25):全库链接存在性检查通过(66 文档 0 失效)、任务表与
|
||||
@@ -234,13 +244,14 @@ docs/
|
||||
|
||||
---
|
||||
|
||||
## 11. 变更记录
|
||||
## 12. 变更记录
|
||||
|
||||
| 日期 | 变更 | 说明 |
|
||||
|---|---|---|
|
||||
| 2026-10-05 | 新增产品需求文档 | 新建 `docs/产品需求/产品需求设计文档.md`(面向产品的需求基线);本索引新增 §3 产品需求、§2 推荐阅读顺序置顶、§1 目录树补 `产品需求/`;后续章节号顺延(架构设计 §4 … 变更记录 §12) |
|
||||
| 2026-09-25 | 目录重组 + 索引建立 | 顶层 16 篇散落 md 归入 5 个新目录(`架构设计/` `子系统设计/` `网络/` `审查记录/` `环境与部署/`);全仓库 90 处引用同步;新建本索引(D-5) |
|
||||
| 2026-09-25 | D-6 目录去空格 | `docs/UI 设计/` → `docs/UI设计/`;全仓库 67 处引用同步(含 URL 编码形态 `UI%20设计`);命名约定写入 §9 |
|
||||
| 2026-09-25 | D-6 目录去空格 | `docs/UI 设计/` → `docs/UI设计/`;全仓库 67 处引用同步(含 URL 编码形态 `UI%20设计`);命名约定写入 §10 |
|
||||
| 2026-09-25 | D-7 文档-代码一致性门禁 | 新建 `scripts/check_doc_links.py`(链接存在性,含行内代码豁免/就近状态词/`[计划]` 标记)、`scripts/gen_task_table.py`(任务表由 `Src/freertos.c` 生成/校验,锚点 `TASK_TABLE:BEGIN/END`);接入 pre-commit `doc-links`/`task-table` 钩子;全库 66 文档 0 失效 |
|
||||
| 2026-09-26 | D-7 体积档落地 | 新建 `scripts/check_mem_numbers.py`(内存/Flash 数字以 `.map` 为事实源,锚点 `MEM_SNAPSHOT:BEGIN/END` + 陈旧散句数字扫描);接入 pre-commit `mem-numbers` 钩子;上线即抓出 6 处真实失真(RW_IRAM1 82,048→87,040、ROM 249,432→262,660 等) |
|
||||
| 2026-09-25 | 新建 `文档规范.md` | 正式确立文档体系规范(目录命名/编码换行/链接形态/门禁/结构/写作约定);补入本索引 §6.1b |
|
||||
| 2026-09-25 | 新建 `文档规范.md` | 正式确立文档体系规范(目录命名/编码换行/链接形态/门禁/结构/写作约定);补入本索引 §7.1b |
|
||||
| 2026-10-04 | 待办文档合并 + 报告归档 | 4 份待办文档(`待处理内容.md` / `项目审计改进清单.md` / `下一步任务规划.md` / `测试与架构改进建议.md`)合并为**统一待办登记簿** `待处理内容.md`;`项目审查与优化建议报告.md` 移入 `问题记录/`,删除 `审查记录/` 目录;全仓库引用同步 |
|
||||
|
||||
@@ -0,0 +1,890 @@
|
||||
# STM32F4-Base 产品需求设计文档
|
||||
|
||||
> **文档定位**:本项目**面向产品的需求基线**——把散落在架构、子系统、测试、问题记录各文档中的
|
||||
> "产品做什么 / 做到什么程度 / 依据是什么"收敛成一份可评审、可追溯的需求说明,供甲方、产品、
|
||||
> 开发、测试与评审者建立统一认知。
|
||||
> **范围**:硬件规格、系统架构、功能需求(FR)、接口规范、非功能需求(NFR)、UI 规格、平台约束、
|
||||
> 待实现项与路线图、验收判据。
|
||||
> **事实来源**:本文所有数值与结论均取自仓库内**受管事实源**(代码、`.ioc`、`.map`、网表分析报告与
|
||||
> 各模块设计文档),凡与其它文档冲突处,以本文标注的权威来源为准。
|
||||
> **版本**:v1.0 **日期**:2026-10-05 **状态**:现状基线(含已实现项 + 待实现项)
|
||||
> **阅读前提**:建议先读 [`docs/README.md`](../../docs/README.md)(文档索引)与
|
||||
> [`docs/架构设计/项目架构总览.md`](../../docs/架构设计/项目架构总览.md)(全景架构)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 文档说明
|
||||
|
||||
### 1.1 目的与范围
|
||||
|
||||
本文回答三个问题:
|
||||
|
||||
1. **产品是什么**——一块工业级嵌入式 DTU 平台固件,做什么、面向谁、部署在哪;
|
||||
2. **产品要做到什么程度**——每一项功能/接口/性能/可靠性的**可验收要求**;
|
||||
3. **产品当前做到哪一步**——已实现、已验收、待实现的**明确边界**。
|
||||
|
||||
**不含**:具体代码实现细节(见各模块设计文档)、测试用例步骤(见 `docs/测试说明/`)、
|
||||
未闭环事项的逐条跟踪(见 [`docs/待处理内容.md`](../../docs/待处理内容.md))。
|
||||
|
||||
### 1.2 术语与缩写
|
||||
|
||||
| 术语 | 全称 / 含义 |
|
||||
|---|---|
|
||||
| **DTU** | Data Transfer Unit,数据传输单元;本产品的设备角色 |
|
||||
| **MCU** | STM32F407ZGTx(Cortex-M4,LQFP144) |
|
||||
| **FTL** | Flash Translation Layer,闪存转换层(本项目用 dhara 实现) |
|
||||
| **BBT** | Bad Block Table,NAND 坏块表(持久化在保留块池) |
|
||||
| **FatFs** | 通用 FAT 文件系统模块(`Lib/FatFs`) |
|
||||
| **BSD Socket API** | 本项目在 CH395F 之上封装的 `net_socket` 接口(`socket/bind/listen/accept/recv/send/close`) |
|
||||
| **RemoDispBus** | 远程显示总线协议(MCU 无屏,UI 以 1bpp 帧经 TCP 推流到远端客户端) |
|
||||
| **cfg_file** | 通用配置引擎(INI 段键表,MCU/模拟器双端共享核心) |
|
||||
| **sys_clock** | 系统墙钟时间服务(RTC 基准 + tick 推进) |
|
||||
| **sys_log** | 定长 64B 记录引擎(运行/自检日志) |
|
||||
| **IWDG** | Independent Watchdog,独立看门狗(LSI 时钟源) |
|
||||
| **就绪屏障** | 用 CMSIS-RTOS2 Event Flags 表达"子系统就绪"的启动顺序机制 |
|
||||
| **双端** | MCU(Keil/ARMCC)与 PC 模拟器(CMake/MSVC)共用同一份 UI/配置源码 |
|
||||
| **@build / @test** | 仓库约定的构建 / 自动化测试命令别名 |
|
||||
|
||||
### 1.3 读者与相关文档
|
||||
|
||||
| 角色 | 建议读法 |
|
||||
|---|---|
|
||||
| 甲方 / 产品 | §2 产品概述 → §5 功能需求 → §9 待实现项与路线图 → §10 验收判据 |
|
||||
| 开发 | 全文;深入时按 §11 指向各模块设计文档 |
|
||||
| 测试 / 验证 | §5、§6、§7、§10 + `docs/测试说明/` |
|
||||
| 评审 | §2、§7、§8、§9 + [`docs/问题记录/项目审查与优化建议报告.md`](../../docs/问题记录/项目审查与优化建议报告.md) |
|
||||
|
||||
---
|
||||
|
||||
## 2. 产品概述
|
||||
|
||||
### 2.1 产品定位
|
||||
|
||||
**STM32F4-Base 是一块工业级嵌入式 DTU 平台固件**,基于 STM32F407ZGTx,集成
|
||||
**以太网通信、SPI NAND 存储、ADC 采集、RS-485 通信与 FTP 文件服务**,并自带
|
||||
**远程显示(UI 推流)、墙钟对时、看门狗自恢复、运行/自检记录**等工业现场能力。
|
||||
|
||||
它既是一台可独立部署的现场设备(通过以太网与远端客户端交互),也是一套
|
||||
**可复用的平台底座**——后续产品(保护测控、馈线自动化终端等)在此底座上补齐采集与协议。
|
||||
|
||||
> **产品现状一句话**:平台能力(网络 / 存储 / 时间 / UI / 日志 / 看门狗 / FTP / 配置)
|
||||
> **已实现并台架验收**;DTU 的**核心采集职责(ADC / RS-485)尚未接线**,是当前最大功能缺口
|
||||
> (见 §9)。这不是缺陷难修,而是**产品定义未落定**。
|
||||
|
||||
### 2.2 产品形态与部署
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph DEV["开发机(Windows)"]
|
||||
K[Keil MDK-ARM v5<br/>编译/烧录]
|
||||
SIM[LVGL PC 模拟器<br/>CMake + SDL2]
|
||||
PY[Python .venv<br/>脚本/测试]
|
||||
end
|
||||
subgraph TGT["目标板(DTU 硬件)"]
|
||||
M[STM32F407ZGTx @168MHz]
|
||||
P[CH395F / GD5F2GQ5UE / TPAFE5160 / SD2506 / RS-485 / LED×6]
|
||||
end
|
||||
subgraph RMT["远端客户端(PC/浏览器)"]
|
||||
C[DTU-RemoteLCD 或任意 TCP 客户端]
|
||||
end
|
||||
DEV -- "USB:ST-Link 下载器" --> TGT
|
||||
DEV -- "USB 串口 USART1 @115200 调试日志" --> TGT
|
||||
TGT -- "以太网 CH395F<br/>FTP:21 / 对时:8888 / 远程显示:7003" --> RMT
|
||||
```
|
||||
|
||||
| 环境 | 角色 | 必需性 |
|
||||
|---|---|---|
|
||||
| ① 开发机 | 编译/烧录、UI 模拟器、脚本工具链 | 开发/测试必需 |
|
||||
| ② 目标板 | 运行固件的 DTU 硬件 | 上机必需 |
|
||||
| ③ 远端客户端 | 远程看图/按键、对时推送、FTP 文件操作 | 现场使用必需 |
|
||||
|
||||
**关键产品特征**:**MCU 端无物理屏幕**——UI 画面以 160×160 单色位图(1bpp)经 TCP 推送到远端
|
||||
客户端渲染,按键亦由远端下发(见 §5.6、§8)。
|
||||
|
||||
### 2.3 设计目标与原则
|
||||
|
||||
| # | 目标 | 落地手段 |
|
||||
|---|---|---|
|
||||
| G1 | **可靠**:现场死机可自恢复、掉电不丢配置、错误可追溯 | IWDG + 任务心跳位图、原子写 + 迁移、错误码通道四要素 |
|
||||
| G2 | **可维护**:分层解耦、单一事实源、双端复用、门禁强制 | 六层架构、就绪屏障、生成器(菜单/字体/任务表)、pre-commit 18 钩子 |
|
||||
| G3 | **可移植**:UI/配置源码 MCU 与 PC 模拟器共用 | 平台后端抽象(`*_mcu.c` / `*_sim.c`),核心零平台依赖 |
|
||||
| G4 | **可扩展**:新子系统/新配置段/新页面按模板接入 | 事件位扩展、段注册三步、页面插件描述符、`App/protocol/` 预留 |
|
||||
| G5 | **可验收**:每项能力有明确判据与自动化门禁 | `@build` / `@test` / L0 静态 / L0.5 主机侧单测 / 台架验证 |
|
||||
|
||||
**设计原则**(贯穿全项目):
|
||||
|
||||
1. **上层只依赖相邻下层(单向)**;禁止反向依赖(例外经登记)。
|
||||
2. **状态位常驻、命令位消费**——Event Flags 就绪位必须 `osFlagsNoClear`。
|
||||
3. **能推导的就不存**——持久化"不可推导"的状态(导航历史、配置、日志),其余现算。
|
||||
4. **单写者**——配置文件属主 = `defaultTask`;syslog 唯一写者 = `defaultTask`;控制台唯一发送者 = `defaultTask`。
|
||||
5. **一切写入 = 临时文件 + rename**(原子替换),半截窗口结构消除。
|
||||
|
||||
### 2.4 产品范围
|
||||
|
||||
**本期(已实现)**:网络通信与配置、NAND 存储栈、时间子系统、运行/自检记录、UI 远程显示、
|
||||
看门狗、FTP 服务、LED 指示、启动屏障与任务调度。
|
||||
|
||||
**非本期(待实现 / 待定义)**:ADC 采集链路、RS-485 采集链路与协议状态机、DTU 核心转发职责
|
||||
(MODBUS RTU / 上行 TCP 等,取决于产品定义)、UI 部分叶子内容页、SNTP 客户端等。
|
||||
|
||||
---
|
||||
|
||||
## 3. 系统总体架构
|
||||
|
||||
### 3.1 六层分层架构
|
||||
|
||||

|
||||
|
||||
> 上图由 `tools/arch_diagram/gen_arch_svg.py` 生成(手绘 SVG,零连线交叉);改架构后编辑脚本顶部
|
||||
> `ROWS` 数据重跑即可,源数据与下表一致。
|
||||
|
||||
分层原则:**上层只依赖相邻下层(单向)**;**① 业务层为顶层**(仅 `net_cfg`,被 UI 与基础服务共用),
|
||||
**② UI 层与 ③ 基础服务层同级并列**。
|
||||
|
||||
| 层 | 目录 | 职责 | 关键模块 |
|
||||
|---|---|---|---|
|
||||
| ① 业务层 | `Drivers/BSP/NETCFG/` | 顶层共享配置(被 UI 与基础服务共用) | `net_cfg` |
|
||||
| ② UI 层 | `Drivers/BSP/UI/` | LVGL 界面(与 PC 模拟器共用源码) | `ui_port` `ui_menu` `ui_menu_view` `ui_menu_tab` `ui_content_page` `ui_page_*` `ui_net_sink` `ui_font_cn_12` `ui_deco` |
|
||||
| ③ 基础服务层 | `App/`、`Drivers/BSP/NET/lftpd/` | 应用侧服务与编排 | `app_main` `sys_events` `app_cfg` `task/*` `lftpd` `time_sync` |
|
||||
| ④ 中间件层 | `Drivers/BSP/NET/`、`Lib/`、`App/util/` | 通用库 / 协议栈 | `net_socket` `net_select` `FatFs` `nand_ftl`(dhara) `LVGL` `sys_clock` |
|
||||
| ⑤ 驱动层 | `Drivers/BSP/{CH395F,GD5F2GQ5UE,TPAFE5160,SD2506,RS485}/` | 芯片寄存器 / 时序 / 中断 | `ch395f` `gd5f2gq5ue` `tpafe5160` `sd2506` `rs485` |
|
||||
| ⑥ 内核 / HAL | `Middlewares/`、`Drivers/STM32F4xx_HAL_Driver/`、`Drivers/CMSIS/` | 任务调度、外设 HAL、启动 | FreeRTOS V10.3.1 · STM32 HAL · CMSIS |
|
||||
| ⑦ 硬件 | — | STM32F407ZGTx @168MHz | SPI1 / SPI2 / I2C1 / UART4 / USART1 / DMA / GPIO / TIM7 |
|
||||
|
||||
### 3.2 运行时任务模型
|
||||
|
||||
六个 FreeRTOS 任务(`Src/freertos.c` 创建,任务体在 `App/task/`、`App/sync/`):
|
||||
|
||||
| 任务 | 栈 | 优先级 | 职责 |
|
||||
|---|---|---|---|
|
||||
| `defaultTask` | 4096 B | Normal | FatFS 挂载(无卷 `f_mkfs`)→ 卷健康探针/自愈 → `net_cfg_load`(配置引擎属主)→ 置 `STORAGE_READY` → 日志落盘(唯一写者)+ 配置保存执行/2s poll + LED 闪烁 + 栈水位观测 + **看门狗唯一喂狗者** |
|
||||
| `netTask` | 4096 B | Normal | 等存储 → `net_stack_bring_up()` → 置 `NET_READY` → `net_poll` 轮询(CH395F 操作串行化) |
|
||||
| `ftpTask` | 4096 B | Normal | 等网络**且**存储(`WaitAll`)→ `lftpd_start("/", 21)` → 单客户端会话循环 |
|
||||
| `testTask` | 8192 B | BelowNormal | 测试套件入口(`test/board/test_config.h` 选择)。**产品构建不创建**(未选套件时立即 `vTaskDelete` 回收其 8 KB CCM 栈) |
|
||||
| `uiTask` | 16384 B | BelowNormal | 等网络 → `ui_port_init`/`ui_menu_init`/`ui_standby_init`(空闲 60s 切待机屏)/`ui_net_sink` → 10 ms 刷新 |
|
||||
| `timeSyncTask` | 2048 B | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC |
|
||||
|
||||
> `idle`(128 words)/ `timer`(256 words)由 FreeRTOS 内核创建。所有任务栈从 48 KB `heap_4` 堆(CCM)分配。
|
||||
> 任务表与 `Src/freertos.c` 的 `osThreadAttr_t` 一致,由 `scripts/gen_task_table.py` 生成并门禁校验。
|
||||
|
||||
### 3.3 就绪屏障(Event Flags)
|
||||
|
||||

|
||||
|
||||
用 CMSIS-RTOS2 Event Flags(`sys_evtHandle`)表达"子系统就绪",取代魔法延时与全局标志轮询。
|
||||
生产者与消费者互不知晓,只经事件组解耦;新增子系统只需定义新 bit + 各自 wait/set。
|
||||
|
||||
| 位 | 名称 | 类型 | 语义 |
|
||||
|---|---|---|---|
|
||||
| bit0 | `SYS_EVT_NET_READY` | 状态位 | netTask:`net_init` + PHY 稳定完成 |
|
||||
| bit1 | `SYS_EVT_STORAGE_READY` | 状态位 | defaultTask:FTL/FatFS 挂载 + 配置就绪 |
|
||||
| bit2 | `SYS_EVT_FTP_READY` | 状态位 | ftpTask:`lftpd_start` 完成 |
|
||||
| bit3 | `SYS_EVT_TIMESYNC_READY` | 状态位 | timeSyncTask:首次时间同步完成 |
|
||||
| bit4 | `SYS_EVT_NET_RECONFIG` | 命令位 | UI:请求立即应用新网口配置 |
|
||||
| bit5 | `SYS_EVT_CFG_SAVE` | 命令位 | UI:网口配置保存请求(defaultTask 消费并写盘) |
|
||||
| bit6 | `SYS_EVT_CONSOLE_TX` | 命令位 | 控制台单写者:生产者入环形缓冲后置位 |
|
||||
|
||||
> ⚠️ **铁律**:状态位(bit0~3)表达**持久状态**,任何消费者都**不许消费**——必须
|
||||
> `osFlagsWaitAny|osFlagsNoClear`。命令位(bit4~6)表达"请做一件事",必须**恰好被消费一次**(消费型等待)。
|
||||
> 历史事故:就绪位被先到的等待者消费,导致 `ftpTask` 的 `WaitAll(bit0|bit1)` 永不成立、21 端口从未监听(静默)。
|
||||
|
||||
### 3.4 启动时序
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant M as main
|
||||
participant A as app_main_init
|
||||
participant K as osKernelStart
|
||||
participant D as defaultTask
|
||||
participant N as netTask
|
||||
participant F as ftpTask
|
||||
participant U as uiTask
|
||||
participant T as timeSyncTask
|
||||
|
||||
M->>M: HAL_Init + CubeMX 外设初始化<br/>(SPI1/SPI2/I2C1/UART4/USART1/DMA/GPIO/TIM7)
|
||||
M->>A: app_main_init()
|
||||
Note over A: 时间子系统优先,使后续日志带时间戳
|
||||
A->>A: sd2506_init() → sys_clock_init()(墙钟基准)
|
||||
A->>A: rs485_init() → gd5f2gq5ue_init()(BBT 扫描)
|
||||
A->>A: tpafe5160_init() → SD2506 诊断 → start_conv_irq()
|
||||
A-->>M: "App init OK"
|
||||
M->>K: osKernelStart()
|
||||
K->>D: 调度
|
||||
D->>D: f_mount(无卷则 f_mkfs FAT32)→ 卷健康探针/自愈 → net_cfg_load()
|
||||
D-->>N: set SYS_EVT_STORAGE_READY
|
||||
N->>N: wait STORAGE_READY(Any|NoClear)→ net_init(ip,mask,gw,mac)<br/>→ PHY 强制 100M 全双工 → 等链路 ≤3s
|
||||
N-->>F: set SYS_EVT_NET_READY
|
||||
F->>F: wait NET_READY|STORAGE_READY(All|NoClear)→ lftpd_start("/", 21)
|
||||
U->>U: wait NET_READY(Any|NoClear)→ ui_port_init → ui_menu_init → ui_net_sink_start(7003)
|
||||
T->>T: wait NET_READY(Any|NoClear)→ TCP listen :8888
|
||||
```
|
||||
|
||||
### 3.5 线程间通信
|
||||
|
||||
| 机制 | 对象 | 用途 |
|
||||
|---|---|---|
|
||||
| Event Flags | `sys_evtHandle` | 启动就绪屏障 + 命令位(§3.3) |
|
||||
| Message Queue | `netMsgQueue`(深度 8,`net_msg_t`) | 所有 CH395F 操作经队列**串行化**到 netTask 执行,保证 SPI 单线程访问 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 硬件规格
|
||||
|
||||
### 4.1 主控与内存
|
||||
|
||||
| 项 | 值 | 说明 |
|
||||
|---|---|---|
|
||||
| MCU | STM32F407ZGTx | Cortex-M4(FPU),LQFP144 |
|
||||
| 主频 | 168 MHz | HSE 8 MHz → PLL M=4 / N=168 / P=2 |
|
||||
| Flash | 1 MB(0x08000000) | 片内 |
|
||||
| SRAM | 192 KB(128 KB 主 SRAM1+SRAM2 + 64 KB CCM) | 链接器映射 128 KB 主 SRAM;CCM 用于 FreeRTOS 堆(任务栈) |
|
||||
| RTOS | FreeRTOS V10.3.1(CMSIS-RTOS2) | HAL 时基 TIM7,tick = 1 ms;NVIC 4 位抢占,外设中断优先级 ≥5 |
|
||||
| 工具链 | Keil MDK-ARM v5(ARMCC v5) | 工程锁 `uAC6=0`,**不支持 armclang** |
|
||||
| CubeMX | 6.17.0 + STM32Cube FW_F4 V1.28.3 | 与 `.ioc` 记录一致,再生成须用此组合 |
|
||||
|
||||
### 4.2 外设与引脚分配
|
||||
|
||||
> **权威来源**:V0.1 网表分析报告 + `Inc/main.h`(代码已迁移至 V0.1)。下表为 **V0.1 硬件**的引脚。
|
||||
|
||||
| 外设 | 接口 | 引脚 | 说明 |
|
||||
|---|---|---|---|
|
||||
| **CH395F 以太网** | SPI2 | PB12 CS / PB13 SCK / PB14 SDO / PB15 SDI | 10/100M 以太网控制器;PHY 强制 100M 全双工;**SPI 分频系数必须为 8**(PCB 设计约束) |
|
||||
| **GD5F2GQ5UE NAND** | SPI1 | PE0 CS / PB3 SCK / PB4 MISO / PB5 MOSI / PB8 WP / PE1 HOLD | 256 MB SPI NAND(2 Gbit) |
|
||||
| **TPAFE5160 ADC** | 并行 16 位 | PG0~PG15 数据 / **PC6 FRSTDATA** / **PC7 BUSY**(EXTI) / **PC8 RD** / **PC9 CONVST** / **PA8 OS2** / **PA11 OS1** / **PA12 OS0** | 高精度多通道 ADC |
|
||||
| **SD2506 RTC** | I2C1 | PB6 SCL / PB7 SDA | 提供墙钟基准与日志时间戳 |
|
||||
| **USART1(调试串口)** | UART | PA9 TX / PA10 RX | 115200 8N1;printf 日志 + `@test` 采集通道 |
|
||||
| **UART4(RS-485)** | UART | PC10 TX / PC11 RX / **PA15 DE** | 半双工通信 |
|
||||
| **状态 LED ×6** | GPIO | PC5 / PB0 / PB1 / PB2 / PF11 / PF12 | **低电平点亮** |
|
||||
| SWD | — | PA13 SWDIO / PA14 SWCLK | V0.1 已修复 V0.0 的 SWCLK 引脚缺陷 |
|
||||
| 调试口 | — | CN2(XH-3A,1=SWDIO/2=SWCLK/3=GND) | V0.1 由 H2 排针改为 XH 端子 |
|
||||
|
||||
> ⚠️ **V0.0 / V0.1 差异**:V0.1 相比 V0.0 做了**接口裁剪(删 8080 LCD 与 8 键)+ U17 大面积引脚重排 +
|
||||
> ADC 前端通道置换(17 路中 13 路变化)+ 调试口改型**。固件 BSP 与 ADC 通道映射表**必须按 V0.1 重映射**;
|
||||
> 详见 `docs/硬件平台/V0.1_网表详细分析报告.md`。
|
||||
>
|
||||
> ⚠️ **文档遗留**:根 `README.md` 的"外设接口"表与 `docs/环境与部署/项目部署环境要求.md` §3.2 仍为
|
||||
> **V0.0 口径**(TPAFE 控制组、RS-485 实例、LED 序号),与 V0.1 不符——**本文以 V0.1 为准**。
|
||||
|
||||
### 4.3 存储器件
|
||||
|
||||
| 器件 | 容量 | 组织 | 软件栈 |
|
||||
|---|---|---|---|
|
||||
| GD5F2GQ5UE | 2 Gbit(256 MB) | 2048 块 × 64 页 × 2048 B | FatFS(FAT32)→ dhara FTL(磨损均衡 / 坏块管理 / GC)→ NAND 驱动 |
|
||||
| SD2506 | — | I2C1 | RTC(时间/温度/电池诊断) |
|
||||
|
||||
- **BBT 持久化**:坏块表存于保留块池(顶部 4 块),不交给 dhara 管理。
|
||||
- **单写者纪律**:`defaultTask` 拥有存储;`netTask` 只读 RAM 配置副本,不触卷。
|
||||
- **FatFs 约束**:`FF_USE_LFN=0`(严格 8.3 文件名);`FF_FS_REENTRANT=1` + `ffsystem.c` 互斥钩子(超时 1 s);`FF_FS_NORTC=0`(`get_fattime` 直引用墙钟)。
|
||||
|
||||
### 4.4 硬件版本与兼容性
|
||||
|
||||
| 版本 | 状态 | 说明 |
|
||||
|---|---|---|
|
||||
| V0.0 | 历史 | 含 8080 LCD、8 按键;存在 2 处设计缺陷(SWCLK 引脚错误致 SWD 不通、ADC17 落在非 ADC 引脚) |
|
||||
| **V0.1** | **当前** | 架构与 V0.0 一致;裁剪 LCD/按键、U17 引脚重排、修复上述 2 处缺陷;固件已迁移 |
|
||||
| V0.2 | 规划关注 | 新增关注项:VCAP 电容值未标注、PC13/14/15 子板 LED 3 mA 限流、SPI1 无法双落点 |
|
||||
|
||||
### 4.5 平台约束
|
||||
|
||||
| 约束 | 内容 |
|
||||
|---|---|
|
||||
| **CubeMX 生成文件** | `Inc/`、`Src/` 中带 `USER CODE BEGIN/END` 标记;自定义代码**只能**写标记区内 |
|
||||
| **生成区外的定制** | 仅限 `Src/iwdg.c` 延后启动、4 个 Fault Handler 实体(`scripts/check_cubemx_survival.py` 审计兜底) |
|
||||
| **`osKernelStart` 前** | 禁止任何 FreeRTOS / CMSIS-RTOS API 调用 |
|
||||
| **BOM / 编码** | 部分源文件带 BOM(`Drivers/BSP/UI/*`、`App/task/ui_task.c`、`App/cfg/cfg_file.c`、`Lib/lv_conf.h`),被工具改写丢 BOM 会导致 ARMCC 按 CP936 解码、中文字面量编译失败 |
|
||||
| **SDIO** | V0.1 主板 SDIO 固定引脚组被 TPAFE/UART 全部占用 → **无 SDIO 能力**(当前设计不受影响,FatFs 卷在 SPI NAND 上) |
|
||||
| **新源文件** | 必须双端注册(Keil `.uvprojx` + `simulator/CMakeLists.txt`),否则不参与编译 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 功能需求
|
||||
|
||||
> 每项功能给出:**需求描述 → 实现要点 → 验收判据**。状态标注:✅ 已实现并验收 / ⚠️ 已实现待专项 / ⬜ 待实现。
|
||||
|
||||
### 5.1 网络通信子系统(FR-NET)✅
|
||||
|
||||
**FR-NET-1 以太网组网**
|
||||
- 需求:上电后按配置的 IP/掩码/网关/MAC 完成以太网初始化,PHY 强制 100M 全双工,等链路稳定后置就绪位。
|
||||
- 实现:`netTask` 等 `STORAGE_READY` → 读 RAM 配置副本 → `net_init(ip,mask,gw,mac)` → 等链路 ≤3 s → 置 `NET_READY`。
|
||||
- 判据:串口出现 `Network Init` / `net init: OK` / `PHY: 100M FULL`;PC 能 ping 通设备 IP。
|
||||
|
||||
**FR-NET-2 网络抽象层(BSD Socket API)**
|
||||
- 需求:为上层提供 `socket/bind/listen/accept/recv/send/close` 与 `select/poll` 多路复用;所有 CH395F 操作串行化。
|
||||
- 实现:`net_socket.c`(BSD API)→ `netMsgQueue`(深度 8)→ `netTask` 串行执行;`net_select.c` 提供 I/O 多路复用。
|
||||
- 判据:三个 TCP 服务(FTP / 对时 / 远程显示)均经同一 API 工作;单连接模型下连接断开自动回到 LISTEN。
|
||||
|
||||
**FR-NET-3 单连接模型与自愈**
|
||||
- 需求:CH395F 配置为多 Socket + TCP Server 单连接(`set_fun_para(0x09)`),Socket 0 复用监听与数据通道;网络重建后服务自动重连。
|
||||
- 实现:三个 TCP 服务**串行**占用连接,断开自动重听;代次号(`net_get_generation()`)驱动服务自愈。
|
||||
- 判据:FTP 旧会话异常断开后约 30 s 恢复监听;网络重建(改 IP)后服务自动重建监听。
|
||||
|
||||
> 网络层是全项目**最成熟子系统**(pending 机制 + 四份 Trap 记录 + 量化基线 + 探针族)。
|
||||
|
||||
### 5.2 存储子系统(FR-STO)✅
|
||||
|
||||

|
||||
|
||||
**FR-STO-1 三层存储栈**
|
||||
- 需求:在 SPI NAND 上提供 FAT32 文件系统;具备磨损均衡、坏块管理、垃圾回收;上电无卷自动格式化。
|
||||
- 实现:FatFS(FAT32)→ dhara FTL → gd5f2gq5ue 驱动;`defaultTask` 挂载(无卷 `f_mkfs`)+ 卷健康探针/自愈。
|
||||
- 判据:FTP 可列目录/读写卷根文件;掉电后数据仍在。
|
||||
|
||||
**FR-STO-2 坏块管理与持久化 BBT**
|
||||
- 需求:坏块表持久化,重启后不丢失;不交给 dhara 管理。
|
||||
- 判据:全片擦除后容量恢复流程可用(见 `docs/测试说明/存储维护与容量恢复.md`)。
|
||||
|
||||
**FR-STO-3 卷并发一致性**
|
||||
- 需求:FTP 传输(ftpTask)与配置读写(defaultTask)并发访问卷时不得损坏。
|
||||
- 实现:`FF_FS_REENTRANT=1` + 逐次加锁/放锁(超时 1 s);三条一致性协议(写 tmp+rename / 沉降去抖 / 单写者)。
|
||||
- 判据:并发 FTP 下载 + UI 保存无卷损坏、无死锁。
|
||||
|
||||
### 5.3 时间子系统(FR-TIME)✅
|
||||
|
||||
**FR-TIME-1 墙钟维护**
|
||||
- 需求:以 SD2506 RTC 建立 Unix epoch 墙钟基准,运行期以 tick 推进(零 I2C 流量),提供字符串格式时间。
|
||||
- 实现:`sys_clock_init()` 读一次 RTC 建基准(无效时按默认值自动校时);base+delta 法;30 天惰性再基准化(防 49.7 天 tick 回绕);`sys_clock_get_str()` → `"YYYY-MM-DD HH:MM:SS"`。
|
||||
- 判据:日志时间戳真实正确;主机侧单测 100 断言点通过。
|
||||
|
||||
**FR-TIME-2 网络对时**
|
||||
- 需求:PC 主动通过 TCP :8888 推送时间到设备,设备写回 RTC。
|
||||
- 实现:`timeSyncTask` 等 `NET_READY` → TCP listen :8888 → 收 PC 推送 → 写 RTC;30 s 无包则掉线重建监听。
|
||||
- 判据:对时后设备墙钟更新、日志时间戳正确。
|
||||
|
||||
> **已知限制**:uint32 epoch → **2038 年**上限。
|
||||
|
||||
### 5.4 配置引擎(FR-CFG)✅
|
||||
|
||||

|
||||
|
||||
**FR-CFG-1 通用配置文件**
|
||||
- 需求:网络参数(IP/掩码/网关/MAC)持久化到 `/config.ini`(INI `[network]` 段);文件可经 FTP 下载/上传;格式纯文本、带注释、可编辑器编辑。
|
||||
- 实现:`cfg_file` 段键表引擎(段 RAM 副本复用模块静态结构体,键表 `const` 映射键→偏移);工厂模板首启自动生成。
|
||||
- 判据:文件缺失/损坏回退工厂默认并重建模板;FTP 上传后 2~5 s 自动生效。
|
||||
|
||||
**FR-CFG-2 外科手术式保存 + 原子写**
|
||||
- 需求:保存时保留用户注释/未知段/未知键(降级安全);写入原子(并发读者只见旧完整或新完整文件)。
|
||||
- 实现:受管键行替换,其余原样保留;临时文件 + `unlink` 目标 + `f_rename`;输出 >4096 B 拒绝保存。
|
||||
- 判据:设备保存后下载文件,用户注释与未来版本段落原样保留。
|
||||
|
||||
**FR-CFG-3 变更检测与立即应用**
|
||||
- 需求:FTP 上传配置后无需重启即生效;网络段变化触发网络重建。
|
||||
- 实现:`defaultTask` 每 2 s `f_stat` 比对 (size, mtime),连续 2 次稳定才重载(沉降去抖);`[network]` 段变化 → `SYS_EVT_NET_RECONFIG` → 网络重建(代次 +1,服务自愈)。
|
||||
- 判据:FTP 改 IP 后 2~5 s 生效(网络重建含等链路 ≤3 s)。
|
||||
|
||||
**FR-CFG-4 旧档迁移**
|
||||
- 需求:旧固件的 `/cfg/netcfg.bin`(NCFG 二进制)首启自动迁移为 INI 并删除旧文件。
|
||||
- 判据:迁移后日志 `cfg file: legacy NCFG migrated`,配置保留。
|
||||
|
||||
**FR-CFG-5 扩展性**
|
||||
- 需求:未来所有模块配置(ADC/RS-485/端口等)进同一文件、按段组织。
|
||||
- 实现:未来模块接入三步——① 定义段结构体(静态工厂默认)② 写键表 ③ `cfg_file_register()`。
|
||||
|
||||
### 5.5 运行 / 自检记录与日志(FR-LOG)✅
|
||||
|
||||
**FR-LOG-1 定长记录引擎**
|
||||
- 需求:运行记录与自检记录持久化到 NAND,FTP 可直下。
|
||||
- 实现:`sys_log` 定长 64 B 文本记录(一行一条);`/log/run.log`(1024 条 / 64 KB 上限)、`/log/selftest.log`(512 条 / 32 KB);`defaultTask` 唯一写者;ISO8601 时间戳 + epoch。
|
||||
- 判据:UI"运行记录/自检记录"页可显示;FTP 可下载。
|
||||
|
||||
**FR-LOG-2 控制台单写者日志**
|
||||
- 需求:多任务并发日志不得字符级交错;异常场景(HardFault)日志可控。
|
||||
- 实现:4 KB 环形缓冲 + `defaultTask` 唯一发送(行级原子);内核前/ISR/异常钩子有界直发回退。
|
||||
- 判据:日志无交错;崩溃时能输出归因日志。
|
||||
|
||||
**FR-LOG-3 上电/重启分类与待机显示**
|
||||
- 需求:区分上电与重启;空闲切待机屏。
|
||||
- 实现:`run.log` 末条 epoch 时间差推断;硬件复位原因(`RCC_CSR`)优先;`ui_standby` 空闲 60 s 切入。
|
||||
|
||||
### 5.6 UI 与远程显示(FR-UI)✅
|
||||
|
||||
**FR-UI-1 离屏渲染 + 远程推流**
|
||||
- 需求:MCU 无物理屏幕,UI 以 160×160 单色位图(1bpp,3200 B)经 TCP :7003 推送到远端客户端渲染;远端按键回注 UI。
|
||||
- 实现:LVGL 160×160 1bpp 离屏渲染到 `g_ui_fbuf`(3200 B)→ `ui_net_sink` 经 RemoDispBus 推流;远端按键经协议注入。
|
||||
- 判据:DTU-RemoteLCD 连 7003 出图(160×160 1bpp)+ 远端菜单导航可用。
|
||||
|
||||
**FR-UI-2 菜单与内容页**
|
||||
- 需求:42 节点层级菜单(最大 4 级)+ 内容页(装置信息/交流量/直流量等)。
|
||||
- 实现:三层拆分(数据层 `ui_menu_tab` 生成物 / 逻辑层 `ui_menu` 17 B 导航状态 / 显示层 `ui_menu_view` 级联框);内容页框架 + 页面插件描述符。
|
||||
- 判据:`UI menu init: OK`;菜单像素回归全 PASS。
|
||||
|
||||
**FR-UI-3 待机屏**
|
||||
- 需求:空闲超时(默认 60 s)自动切待机屏,仅确认键回菜单。
|
||||
- 判据:空闲后进入待机屏,按键返回菜单。
|
||||
|
||||
> 详见 §8 UI 规格。
|
||||
|
||||
### 5.7 看门狗与故障自恢复(FR-WD)✅
|
||||
|
||||

|
||||
|
||||
**FR-WD-1 IWDG + 任务心跳位图**
|
||||
- 需求:任务级死锁/饿死/断言死循环可自恢复(硬件复位),无需人工到场;不误杀正常长耗时窗口。
|
||||
- 实现:IWDG(LSI 独立时钟,PR=4 / RLR=1249 → 标称 **2498 ms**、最坏 **≈1701 ms**);任务心跳位图(各自置位,无锁单字)+ `defaultTask` 单一喂狗者(`task_wd_poll` 每 100 ms 抽样);连续 8 次(800 ms)未达标 → 停喂 → 约 2.5 s 后复位;必需位掩码 `0x37`。
|
||||
- 判据:V2 任务饿死 ≤2.5 s 复位;V4 关中断死循环每 ~4.9 s 稳定复位;V5 30 min 真实负载零复位。
|
||||
|
||||
**FR-WD-2 复位原因诊断**
|
||||
- 需求:复位后可区分上电 / 看门狗 / 软件 / 引脚 / 欠压。
|
||||
- 实现:`HAL_Init()` 后一次性读 `RCC_CSR` 锁存并清标志;优先级 POR > PIN > IWDG > WWDG > SFT > LPWR > BOR。
|
||||
- 判据:串口 `[APP] reset cause: <类型>`;`[WD] armed:` 自检标记。
|
||||
|
||||
**FR-WD-3 故障现场采集**
|
||||
- 需求:HardFault / MemManage / BusFault / UsageFault 触发时输出完整现场。
|
||||
- 实现:4 个 Fault Handler 采集(PC/LR/xPSR/R0-R3/CFSR/HFSR/BFAR/MMFAR)+ `fault_handler_enable()` 使能 SHCSR 后三者。
|
||||
- 判据:日志形如 `[ERR] MEMFAULT PC=... CFSR=... MMFAR=...`。
|
||||
|
||||
> **已知边界**:启动段(`app_main_init` + bring-up)无看门狗保护;`ftpTask` 首期不纳入监视(掩码剔除)。
|
||||
|
||||
### 5.8 LED 状态指示(FR-LED)✅
|
||||
|
||||
- 需求:6 路 LED(低电平点亮)随系统状态变化。
|
||||
- 实现:`defaultTask` 循环驱动(闪烁指示系统活跃)。
|
||||
- 判据:目检 6 路 LED 随系统状态变化。
|
||||
|
||||
### 5.9 ADC 采集(FR-ADC)⬜ 待实现
|
||||
|
||||
- **需求(待产品定义确认)**:周期采集 TPAFE5160 多通道模拟量并转发。
|
||||
- **现状**:`tpafe5160_init()` 与 `tpafe5160_start_conv_irq()` 在启动序列调用一次;**全仓库无周期性 CONVST 重触发**;`data_ready`/`get_buf` 无消费者(`adc_task.c` 为空桩,且未在 `freertos.c` 创建)。
|
||||
- **后果**:上电后仅采集 1 个样本,此后数据永久陈旧。
|
||||
- **待确认(阻塞项 B0)**:① 采集是否持续 ② 采样率/通道 ③ 转发目标 ④ `APP_ADC_ENABLE` 语义。
|
||||
- **实现约束**(见 §9):周期 CONVST 重触发 + `adc_task` 消费;**先修原子快照 API**(否则接入即撕裂);栈预算核算;V0.1 通道映射表重写(13/17 路变化,第 17 路用 `ADC_CHANNEL_12`)。
|
||||
|
||||
### 5.10 RS-485 采集(FR-RS485)⬜ 待实现
|
||||
|
||||
- **需求(待产品定义确认)**:半双工 RS-485 收发、协议帧解析、转发。
|
||||
- **现状**:`rs485_init()` 已调用;`rs485_task.c` 为空桩,未在 `freertos.c` 创建;`App/protocol/` 预留(仅 README + `.gitkeep`)。
|
||||
- **实现约束**:双缓冲 + 序号(防包撕裂)+ DE 收尾(超时路径等 TC)+ 协议状态机;解析必须与硬件 I/O 分离(`App/protocol/` 正为此预留)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 接口规范
|
||||
|
||||
### 6.1 网络服务端口
|
||||
|
||||
| 服务 | 协议 / 端口 | 用途 | 核对方法 |
|
||||
|---|---|---|---|
|
||||
| FTP | TCP **21** | 文件上传/下载(根目录 `/`,NAND 存储) | 任意 FTP 客户端列目录/读写 |
|
||||
| 墙钟对时 | TCP **8888** | PC 主动推送时间到设备 | 对时后核对设备时间 / 日志时间戳 |
|
||||
| 远程显示(RemoDispBus) | TCP **7003** | 远端看图(160×160 1bpp)+ 远端导航按键 | DTU-RemoteLCD 或任意 TCP 客户端连 7003 收帧 |
|
||||
|
||||
> **现场组网要求**:设备与客户端**同网段**(默认 .100/24、网关 .1);跨网段先改 IP 再上线。
|
||||
|
||||
### 6.2 RemoDispBus 协议
|
||||
|
||||

|
||||
|
||||
| 项目 | 内容 |
|
||||
|---|---|
|
||||
| 传输 | TCP,端口 **7003**;单连接(`backlog=1`) |
|
||||
| 帧格式 | `[TAG(1)][CMD(1)][LEN_H(1)][LEN_LO(1)][DATA(n)][CRC(1)]` |
|
||||
| 方向标识 | TAG `0xAA` = 客户端→服务端,`0xBB` = 服务端→客户端 |
|
||||
| 校验 | CRC = 数据段逐字节**异或**(低 8 位,不含 TAG/CMD/LEN) |
|
||||
| 字节序 | 多字节字段**大端**(网络字节序) |
|
||||
| 最短帧 | 5 字节(LEN=0) |
|
||||
| 接收方式 | 逐字节有限状态机(TAG 定界 + 长度定长 + CRC 校验,自动重同步) |
|
||||
|
||||
**命令集**:
|
||||
|
||||
| CMD | 名称 | 请求数据段 | 应答数据段 |
|
||||
|---|---|---|---|
|
||||
| 0 | KEEPLIVE | 无 | 无(原样回显) |
|
||||
| 1 | INIT | 无 | `[宽u16][高u16][帧字节数u32]`(**8 B**) |
|
||||
| 2 | KEY | `[按键码u8]` | 无(确认) |
|
||||
| 3 | LCDMEM | `[起始偏移u32]` | `[偏移u32][1bpp位图 3200B]`(3204 B) |
|
||||
|
||||
**按键码**:`UP=0x02` / `DOWN=0x40` / `LEFT=0x10` / `RIGHT=0x08` / `ENTER=0x20` / `ESC=0x01`。
|
||||
|
||||
**位图格式**:1bpp 单色,**MSB 优先**(bit7 = 该字节第一个像素);像素 (x,y) → `byte_i=(y*W+x)/8`、`bit_i=7-(x%8)`;位值 `1`=白、`0`=黑;160×160 → 3200 B。
|
||||
|
||||
**关键常量**:`UI_NET_SINK_PORT=7003`、`RM_MAX_RX_PAYLOAD=256`、`RM_RX_BUF=64`、帧重组缓冲 261 B。
|
||||
|
||||
> 详见 `docs/UI设计/RemoDispBus协议与接收设计说明.md`。MCU 与模拟器**共用同一份** `ui_net_sink.c`。
|
||||
|
||||
### 6.3 对时协议
|
||||
|
||||
- **载体**:TCP :8888,PC 主动推送,设备接收并写 RTC。
|
||||
- **行为**:`timeSyncTask` 监听 → 收包 → 写回 RTC;30 s 无包则掉线重建监听(约 4 s)。
|
||||
- **待补充**:推送报文的具体帧格式(当前实现细节见 `App/sync/time_sync.c` 与 `test/host/time_sync_server.py`)。
|
||||
|
||||
### 6.4 FTP 服务
|
||||
|
||||
- **实现**:lftpd(轻量 FTP 服务器),root = `/`(FatFS 卷根),端口 21,**单客户端**。
|
||||
- **支持命令**:登录 / TYPE I / PASV / STOR / RETR / LIST / DELE / QUIT。
|
||||
- **启动门**:`ftpTask` 必须等 `NET_READY` **且** `STORAGE_READY`(两位 `NoClear`)才 `lftpd_start`。
|
||||
- **注意**:同一时刻只服务 1 个会话,旧会话异常断开后约 30 s 恢复监听;测试脚本须内置连接重试,**不要用裸 TCP 工具探测 21 端口**。
|
||||
- **实测**:128 KB 上传下载逐字节一致(约 49/60 KB/s)。
|
||||
|
||||
### 6.5 配置文件格式
|
||||
|
||||
**位置**:MCU `/config.ini`(卷根);模拟器 `sim_config.ini`(工作目录)。
|
||||
|
||||
**语法**:`key=value`(key `[a-z0-9_]+` 大小写敏感);`[section]`;`;`/`#` 注释行;UTF-8(容忍 BOM);CRLF(设备写出)/ LF 均接受;行长 >127 字符该行无效;文件 >4096 B 视为损坏。
|
||||
|
||||
**出厂模板**(首启自动生成):
|
||||
|
||||
```ini
|
||||
; DTU 通用配置文件
|
||||
[network]
|
||||
; IP 地址
|
||||
ip=192.168.1.100
|
||||
; 子网掩码
|
||||
mask=255.255.255.0
|
||||
; 默认网关
|
||||
gateway=192.168.1.1
|
||||
; MAC 地址 (全零 = 使用芯片内置 MAC)
|
||||
mac=00:00:00:00:00:00
|
||||
```
|
||||
|
||||
**值类型**:`IP4`(`a.b.c.d`)、`MAC`(`aa:bb:cc:dd:ee:ff`)、`UINT`(十进制,兼容 `0x`)、`STR`(≤31 字符)。
|
||||
|
||||
**工厂默认**:IP `192.168.1.100` / 掩码 `255.255.255.0` / 网关 `192.168.1.1` / MAC 全零(= 芯片内置)。
|
||||
|
||||
> MAC 全零是"使用芯片内置 MAC"的**哨兵**,不是"MAC 为 0"。恢复出厂:FTP `DELE /config.ini` → 下次上电重新生成模板。
|
||||
|
||||
### 6.6 调试串口
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 端口 | USART1(PA9 TX / PA10 RX),115200 8N1 |
|
||||
| 用途 | printf 日志 + `@test` 采集通道 |
|
||||
| 配置源 | `.opencode/serial_config.json`(单一配置源) |
|
||||
| 工具 | 仓库内置 Python 串口助手(`tools/serial_tool/`,常驻 daemon + CLI) |
|
||||
|
||||
**启动标记(`@test` 判据)**:
|
||||
- Required:`App init OK` / `Network Init` / `net init: OK` / `PHY: 100M FULL`
|
||||
- Forbidden:`FAIL` / `ERROR` / `HardFault` / `[ERR]`
|
||||
|
||||
### 6.7 对外 API 一览
|
||||
|
||||
| 模块 | 关键 API | 说明 |
|
||||
|---|---|---|
|
||||
| `net_socket` | `socket/bind/listen/accept/recv/send/close` + `select/poll` | BSD Socket 抽象 |
|
||||
| `net_cfg` | `net_cfg_load/save/get/set/get_mac/set_active_mac/fmt_ipv4/set_apply_cb/request_apply` | 网络配置(签名与语义稳定) |
|
||||
| `cfg_file` | `cfg_file_register/load/save/poll/section_data` | 配置引擎核心(双端共享) |
|
||||
| `sys_clock` | `sys_clock_init/get/get_str/get_time` | 墙钟时间服务 |
|
||||
| `sys_log` | `syslog_post`(RUN / SELFTEST) | 定长记录引擎 |
|
||||
| `ui_net_sink` | `ui_net_sink_start(port)` / `ui_net_sink_poll()` | 远程显示服务端 |
|
||||
| `ui_content_page` | `ui_content_page_open/close/invalidate/is_open` | 内容页框架 |
|
||||
| `task_watchdog` | `task_wd_beat/poll/start` + 观测接口 | 看门狗判定状态机 |
|
||||
| `sys_events` | `sys_evtHandle` + 7 个事件位 | 启动屏障 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 非功能需求
|
||||
|
||||
### 7.1 可靠性
|
||||
|
||||
| 需求 | 要求 | 落地 |
|
||||
|---|---|---|
|
||||
| **自恢复** | 任务死锁/饿死/断言死循环 → 硬件复位 | IWDG + 心跳位图(§5.7) |
|
||||
| **掉电不丢配置** | 配置原子写 + 旧档迁移 | tmp+rename + NCFG→INI 迁移 |
|
||||
| **错误可追溯** | 错误码分级/透传/留痕,不吞不猜 | 错误码通道四要素(分类/透传/分级/留痕) |
|
||||
| **存储自愈** | 卷损坏可探针/自愈;丢弃可观测 | 卷健康探针 + 丢弃计数 + TX 僵尸通道自愈 |
|
||||
| **不误杀** | 正常长耗时窗口不触发复位 | 启动段不喂狗 + 心跳切片 + 白名单 |
|
||||
|
||||
> **错误码通道四要素**(CH395F 范式,后续任何驱动/子系统建立错误通道时应沿用):
|
||||
> ① 分类(超时/真故障/参数错)② 透传(逐层上报,禁 `(void)ret`)③ 分级(可恢复重试/不可恢复上报)
|
||||
> ④ 留痕(不可恢复写 syslog selftest,可恢复计数并 UI/日志可见)。
|
||||
> **纪律**:自愈逻辑严禁把"名字/参数类错误码"归入"卷损坏触发集"。
|
||||
|
||||
### 7.2 性能指标
|
||||
|
||||
| 指标 | 基线值 | 来源 |
|
||||
|---|---|---|
|
||||
| M3 压力档帧周期 | med 60.1 / p95 66.4 / max 69.3 ms(零尖峰) | `docs/测试说明/链路延迟测试说明.md` |
|
||||
| 队列响应性(挂起客户端) | 92.5 ms(pending 一期) | `test/host/e02_probe.py` |
|
||||
| FTP 传输速率 | 约 49 / 60 KB/s(上传/下载) | 128 KB 实测 |
|
||||
| 网络重建生效 | 2~5 s(含等链路 ≤3 s) | 配置设计 |
|
||||
| UI 刷新 | 10 ms 循环 | `ui_task_func` |
|
||||
| IWDG 停喂到复位 | ≤2.5 s | IWDG 设计 |
|
||||
|
||||
### 7.3 内存与资源预算
|
||||
|
||||
> **权威来源**:`.map` 受管快照 + V5 30 min 运行时水位(2026-10-04)。详见
|
||||
> `docs/内存管理/RAM使用分析与优化方案.md`。
|
||||
|
||||
**静态区(产品构建)**:
|
||||
|
||||
| 区域 | 用量 | 容量 | 占比 |
|
||||
|---|---|---|---|
|
||||
| Flash ER_IROM1 | 266,632 B | 1024 KB | 25.4% |
|
||||
| ROM 合计 | 267,372 B | — | — |
|
||||
| RW_IRAM1 | 84,960 B | 131,072 B | 64.8% |
|
||||
| RW_CCM | 49,184 B | 65,280 B | 75.3% |
|
||||
|
||||
**运行时(V5 30 min 真实负载)**:
|
||||
|
||||
| 项 | 值 | 判定 |
|
||||
|---|---|---|
|
||||
| 实测堆 | free=8,664 / min_ever=4,728 B | — |
|
||||
| `defaultTask` 栈峰值 | 3664 / 4096 B(余量 432 B ≈ **10%**) | ⚠️ **低于 30% 判据,需处理** |
|
||||
| `netTask` 栈峰值 | 1228 / 4096 B(余量 70%) | ✅ |
|
||||
| `ftpTask` 栈峰值 | 2516 / 4096 B(余量 38%) | ✅ |
|
||||
| `uiTask` 栈峰值 | 4060 / 16384 B(余量 75%) | ✅ |
|
||||
| `timeSyncTask` 栈峰值 | 792 / 2048 B(余量 61%) | ✅ |
|
||||
| `testTask` 栈峰值(产品态空转) | 496 / 8192 B(余量 93%) | ✅ |
|
||||
|
||||
> **定栈规则**:改栈或加大栈内局部变量前后**必须**重跑 `scripts/stack_report.py`
|
||||
> (Keil 静态调用图 × 串口 `[STACK]` 水位,判定取两者更坏者)。
|
||||
> **LVGL 内存池** 40 KB(静态占用);**FreeRTOS 堆** 48 KB(CCM)。
|
||||
|
||||
### 7.4 可维护性(测试与门禁)
|
||||
|
||||
**测试分层**:
|
||||
|
||||
| 层 | 内容 | 运行位置 |
|
||||
|---|---|---|
|
||||
| L0 | 静态门禁(pre-commit 18 钩子) | 本地 / CI |
|
||||
| L0.5 | 主机侧单元测试(MSVC 离线编译真实源码) | 本地 / CI |
|
||||
| L1 / L2 | 板端套件 / 模拟器回归 | 本地(需硬件 / 模拟器) |
|
||||
| L3 | 真机台架(`@test` 闭环 + 探针) | 本地(需真机 + ST-LINK) |
|
||||
|
||||
**构建 / 测试命令**:
|
||||
|
||||
```powershell
|
||||
# 构建(@build):0 错 0 警
|
||||
& "MDK-ARM\build.bat" # 退出码 0=PASS / 1=构建失败 / 2=环境错误
|
||||
# 自动化测试(@test):串口采集 → 烧录 → 日志校验
|
||||
& '.venv\Scripts\python.exe' test/host/run_boot_test.py # 0=PASS / 1=FAIL / 2=采集或烧录错误 / 3=用法错误
|
||||
# 全库门禁
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
**pre-commit 18 钩子**:trailing-whitespace、end-of-file-fixer、check-added-large-files、
|
||||
check-merge-conflicts、check-yaml、cppcheck、test-cppcheck、no-mojibake、coding-standard、
|
||||
doc-links、task-table、mem-numbers、cubemx-survival、watchdog-unit-test、sys-clock-unit-test、
|
||||
cfg-file-unit-test、test-suite-switch、gitlint。
|
||||
|
||||
**受管事实源(禁止手改,由脚本生成)**:
|
||||
- 任务表(`README.md` / `AGENTS.md`)← `scripts/gen_task_table.py`
|
||||
- 内存/Flash 快照 ← `scripts/check_mem_numbers.py`
|
||||
- 菜单表 ← `tools/menu_gen/gen_menu.py`
|
||||
- 中文字体 ← `tools/font_gen/make_font.py`
|
||||
|
||||
### 7.5 可移植性(双端)
|
||||
|
||||
| 项 | MCU | 模拟器 |
|
||||
|---|---|---|
|
||||
| 构建 | Keil MDK-ARM v5(ARMCC) | CMake + SDL2 + MSVC |
|
||||
| 共用源码 | `Drivers/BSP/UI/*`、`Drivers/BSP/NETCFG/net_cfg.c`、`App/cfg/cfg_file.c` | 同左 |
|
||||
| 平台后端 | `*_mcu.c`(CH395F/FatFS) | `*_sim.c`(Winsock/宿主文件) |
|
||||
| 验证 | `@build` 0/0 → `@test` 串口闭环 | `check_menu_rows.py` + `check_content_pages.py`(像素黄金参考) |
|
||||
|
||||
> **新源文件必须双端注册**(Keil `.uvprojx` + `simulator/CMakeLists.txt`),否则不参与编译。
|
||||
|
||||
### 7.6 安全与权限
|
||||
|
||||
| 项 | 现状 |
|
||||
|---|---|
|
||||
| FTP 鉴权 | **无**(维持现状,非本期目标) |
|
||||
| UI 菜单权限 | 受保护叶子(行尾 `#P`)先经密码页;密码**仅编译期写入**(查看 `000` / 修改 `123`),不落 Flash、无运行期设置页 |
|
||||
| 远程显示 | 无鉴权,单连接;现场同网段部署 |
|
||||
|
||||
---
|
||||
|
||||
## 8. UI 规格
|
||||
|
||||
### 8.1 屏幕与渲染
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 屏幕尺寸 | 160 × 160 px |
|
||||
| 色深 | 1bpp 单色(MSB 优先),帧缓冲 3200 B |
|
||||
| 渲染 | LVGL 离屏渲染到 `g_ui_fbuf`;MCU 无物理屏,经 TCP 7003 推流 |
|
||||
| 内存池 | `LV_MEM_SIZE` = 40 KB |
|
||||
| 主题 | dark mono(单色深色) |
|
||||
| 刷新 | `uiTask` 10 ms 循环 |
|
||||
| 绘制缓冲 | I1 draw buffer 需 +8 B palette 头 |
|
||||
|
||||
### 8.2 菜单树(42 节点)
|
||||
|
||||

|
||||
|
||||
**规模**:菜单节点 **9** 个(含根)+ 叶子节点 **33** 个 = **42** 节点;最大深度 **4 级(L0~L3)**。
|
||||
|
||||
**根页(主界面)7 个一级条目**:装置信息 / 实时数据 / 参数定值 / 三遥设置 / 装置维护 / 通讯参数 / 记录查询。
|
||||
|
||||
**完整层级树**:
|
||||
|
||||
```text
|
||||
主界面 (L0)
|
||||
├─ 装置信息 [叶子]
|
||||
├─ 实时数据 ▶ [菜单]
|
||||
│ ├─ 交流量 ├─ 直流量 └─ 遥信量
|
||||
├─ 参数定值 ▶
|
||||
│ ├─ 整定 ▶(参数 / 定值 / 控制字 / 软压板)
|
||||
│ └─ 查看 ▶(参数 / 定值 / 控制字 / 软压板)
|
||||
├─ 三遥设置 ▶(遥测死区 / 遥测系数 / 遥信类型 / 遥信防抖 / 双点遥信)
|
||||
├─ 装置维护 ▶(时钟设置 / 强制复归 / 手动录波 / 清除记录)
|
||||
├─ 通讯参数 ▶(通讯设置 / 网口设置 / SNTP设置)
|
||||
└─ 记录查询 ▶(SOE记录 / 事故记录 / 操作记录 / 保护告警 / 保护启动 /
|
||||
遥控记录 / 自检记录 / 运行记录 / 运行报告)
|
||||
```
|
||||
|
||||
**三层代码架构**:数据层 `ui_menu_tab`(生成物,`g_menu_tab[42]` 扁平父子索引表,≈0.7 KB Flash)
|
||||
+ 逻辑层 `ui_menu`(唯一 **17 B** 导航状态)+ 显示层 `ui_menu_view`(持全部 LVGL 对象,零导航状态)。
|
||||
|
||||
**导航模型**:树形逐级进入——`ENTER`/`→` 进入子页,`ESC`/`←` 返回上一级;页面 = 对表的一次
|
||||
`parent == 节点` 过滤(**现算不落地**)。
|
||||
|
||||
**显示模型**:横向级联子框——每级一个框,子框左缘 = 父框右缘(共享 1px 边框列);子框顶边对齐父框
|
||||
"选中行"行顶,溢出时整框上移使底边对齐选中行行底;选中行整行反色(白带黑字),菜单行带 `▶`。
|
||||
|
||||
**改菜单流程**:编辑 `ui_menu_tree.txt`(缩进即层级)→ 重跑 `tools/menu_gen/gen_menu.py` → 导航/渲染代码**零改动**。
|
||||
|
||||
### 8.3 内容页
|
||||
|
||||
| 页 | 节点 | 类型 | 规格 |
|
||||
|---|---|---|---|
|
||||
| 装置信息 | node 1 | 静态键值行 | 6 行不分页;副标题"馈线自动化终端" |
|
||||
| 交流量 | node 3 | 数据列表 | 24 行 / 每页 8(3 页) |
|
||||
| 直流量 | node 4 | 数据列表 | 3 行单页 |
|
||||
| 用户密钥 | 受保护叶子 | 表单/操作页 | 3 个 14×14 数字框 + 反显光标 |
|
||||
|
||||
- 内容页为**独立全屏屏**,由框架一次性自绘(**零 LVGL 子对象**),`ESC` 返回菜单屏。
|
||||
- 菜单导航状态**不压层**,返回即原样还原;同一时刻至多一个内容页打开。
|
||||
- 节点→页映射在逻辑层 `menu_content_page_for(node)`;其余叶子暂无内容页(进空白终点框)。
|
||||
|
||||
### 8.4 密码与权限
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 查看密码 | `000`(授只读权限) |
|
||||
| 修改密码 | `123`(授修改权限) |
|
||||
| 存储 | `ui_pwd_def.h` **编译期**写入,不落 Flash |
|
||||
| 流程 | 受保护叶子先 arm → 开密码页 → 确认一致后回调 → **先关页再续做进入动作**(携授予权限) |
|
||||
|
||||
### 8.5 中文字体
|
||||
|
||||
- 字体 `ui_font_cn_12.c`:宋体 12px 1bpp **子集**(当前 122 唯一字 / 217 字形)。
|
||||
- 生成流程:`tools/font_gen/extract_cn.py`(扫 UI 源码 → `ui_cn_chars.txt`)→ `tools/font_gen/make_font.py`。
|
||||
- **约束**:任何 UI 文案新增汉字后必须走此流程,否则显示为空白方块。
|
||||
|
||||
---
|
||||
|
||||
## 9. 待实现项与路线图
|
||||
|
||||
### 9.1 功能缺口(当前最大产品空洞)
|
||||
|
||||
| 缺口 | 现状 | 影响 |
|
||||
|---|---|---|
|
||||
| **ADC 采集链路** | `adc_task.c` 空桩;无周期 CONVST 重触发;`data_ready`/`get_buf` 无消费者 | 上电后仅采 1 个样本 |
|
||||
| **RS-485 采集链路** | `rs485_task.c` 空桩;`App/protocol/` 仅 README | 无 RS-485 数据收发 |
|
||||
| **DTU 核心转发职责** | 未定义 | 采集到数据后无处转发 |
|
||||
|
||||
> **根因不是"缺陷难修",而是"功能没接"**——B1/B2 的规模完全取决于 B0 产品定义。
|
||||
|
||||
### 9.2 阶段路线图
|
||||
|
||||
```text
|
||||
【阶段 B 功能】 B0 产品定义确认 ─┬─ B3 E-59 门禁固化(并行)
|
||||
(当前最高优先) └─ E-58 原子快照 → B1 ADC → B2 RS485
|
||||
↓
|
||||
【阶段 C 结构】 C1 pending 二期 ─ C3 日志管线 ─ C4 栈(S-1) ─ C5 收口 ─ C6 USART1 TX-only
|
||||
↓
|
||||
【阶段 D 常态】 D2 N-3 L5 基线重锁 / D5 N-16 负向台架 / D6 N-17 探针窗口
|
||||
```
|
||||
|
||||
| 阶段 | 关键任务 | 前置 |
|
||||
|---|---|---|
|
||||
| **B0** | 产品定义确认(阻塞项):采集是否持续 / 采样率通道 / 转发目标 / `APP_*_ENABLE` 语义 | — |
|
||||
| **B1** | ADC 采集链路实现(周期 CONVST + `adc_task` 消费;**先修原子快照 API**) | B0 + E-59 门禁 |
|
||||
| **B2** | RS-485 采集链路实现(双缓冲 + 序号 + DE 收尾 + 协议状态机) | B0 + E-59 门禁 |
|
||||
| **B3** | E-59 门禁固化入 `AGENTS.md`(接消费者前先修缺陷 + 栈预算) | — |
|
||||
| **C1** | pending 二期(ACCEPT + SEND pending 化) | — |
|
||||
| **C4** | `defaultTask` 栈余量(**当前 10%,需尽快处理**):4096→4608 或 GC 链局部削减 | — |
|
||||
| **C6** | USART1 TX-only 结构根治(灭 ORE 僵尸机制) | 单开一轮 |
|
||||
|
||||
### 9.3 未接线开关说明
|
||||
|
||||
| 开关 | 位置 | 现状 |
|
||||
|---|---|---|
|
||||
| `APP_NET_ENABLE` / `APP_ADC_ENABLE` / `APP_RS485_ENABLE` | `App/app/app_cfg.h` | **未接线占位,不门控任何代码**——三宏全库零消费点,各模块一律编译进产品;是否/如何接线取决于 B0 产品定义。**不要把它们当开关用** |
|
||||
| `TEST_SUITE_*` | `test/board/test_config.h` | 测试套件**互斥**,一次构建只开一个;全注释 = 正常产品固件 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 验收判据
|
||||
|
||||
### 10.1 构建与静态门禁
|
||||
|
||||
| 项 | 判据 |
|
||||
|---|---|
|
||||
| 构建 | `@build` → `BUILD_OK: 0 errors, 0 warnings`(退出码 0) |
|
||||
| 静态门禁 | `pre-commit run --all-files` 全部通过(18 钩子) |
|
||||
| 主机侧单测 | 看门狗 39 用例 / 系统时钟 100 断言 / 配置文件 149 断言 全 PASS |
|
||||
| 双端构建 | Keil 与 CMake 均 0 错 0 警 |
|
||||
| UI 回归 | `check_menu_rows.py` + `check_content_pages.py` PASS |
|
||||
|
||||
### 10.2 上电自检(`@test`)
|
||||
|
||||
| 项 | 判据 |
|
||||
|---|---|
|
||||
| Required 标记 | `App init OK` / `Network Init` / `net init: OK` / `PHY: 100M FULL` |
|
||||
| Forbidden 标记 | 无 `FAIL` / `ERROR` / `HardFault` / `[ERR]` |
|
||||
| 自检记录 | `selftest: no fault record` |
|
||||
| 退出码 | `@test` → 0(PASS) |
|
||||
|
||||
### 10.3 现场验收清单
|
||||
|
||||
| # | 项目 | 方法 | 通过标准 |
|
||||
|---|---|---|---|
|
||||
| 1 | 上电自启动 | 断电上电 + 串口采集 | `@test` PASS,无 Forbidden 标记 |
|
||||
| 2 | 网络连通 | PC ping 设备 IP | 通(PHY 100M FULL) |
|
||||
| 3 | 远程显示 | DTU-RemoteLCD 连 7003 | 出图(160×160 1bpp)+ 远端菜单导航可用 |
|
||||
| 4 | FTP | FTP 客户端连 :21 | 列目录 / 读写 `/` 下文件 |
|
||||
| 5 | UI 功能 | 远端操作 | 菜单 7 项导航、内容页、密码(查看 `000` / 修改 `123`)、网口设置保存后立即生效 |
|
||||
| 6 | 对时 | PC 推送 8888 | 设备墙钟更新、日志时间戳正确 |
|
||||
| 7 | 掉电保持 | 写文件 / 改网口配置 → 重启 | 数据仍在(`/config.ini` 按新值生效) |
|
||||
| 8 | LED 状态 | 目检 | 6 路 LED 随系统状态变化(低电平点亮) |
|
||||
|
||||
### 10.4 台架验收(已闭环)
|
||||
|
||||
| 用例 | 内容 | 结论 |
|
||||
|---|---|---|
|
||||
| V2 | 任务饿死 → IWDG 复位 | ✅ 800 ms 声明 stall,≤2.5 s 复位(`reset cause: IWDG`) |
|
||||
| V4 | 关中断死循环 → IWDG 复位 | ✅ 每 ~4.9 s 稳定复位(IWDG 独立于中断) |
|
||||
| V5 | 30 min 真实负载长跑 | ✅ 120/120 FTP PASS,零 IWDG 复位 |
|
||||
| P0-1 | 配置引擎堆分配改造(真机) | ✅ `[CFG] load: OK`(经 FreeRTOS 堆);FTP 改 IP 复位即生效 |
|
||||
| 存储/网络套件 | 16/16 PASS | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 11. 相关文档
|
||||
|
||||
| 主题 | 文档 |
|
||||
|---|---|
|
||||
| 文档索引 | [`docs/README.md`](../../docs/README.md) |
|
||||
| 项目全景架构 | [`docs/架构设计/项目架构总览.md`](../../docs/架构设计/项目架构总览.md) |
|
||||
| 存储架构 | [`docs/架构设计/STM32F4-Base存储架构说明.md`](../../docs/架构设计/STM32F4-Base存储架构说明.md) |
|
||||
| 启动顺序 / 就绪屏障 | [`docs/架构设计/项目启动顺序管理.md`](../../docs/架构设计/项目启动顺序管理.md) |
|
||||
| 配置引擎 | [`docs/子系统设计/配置文件设计说明.md`](../../docs/子系统设计/配置文件设计说明.md) |
|
||||
| 网络配置 | [`docs/子系统设计/网络配置说明.md`](../../docs/子系统设计/网络配置说明.md) |
|
||||
| 墙钟时间 | [`docs/子系统设计/系统墙钟时间维护说明.md`](../../docs/子系统设计/系统墙钟时间维护说明.md) |
|
||||
| 运行/自检记录 | [`docs/子系统设计/运行与自检记录设计说明.md`](../../docs/子系统设计/运行与自检记录设计说明.md) |
|
||||
| 控制台单写者日志 | [`docs/子系统设计/控制台单写者日志设计说明.md`](../../docs/子系统设计/控制台单写者日志设计说明.md) |
|
||||
| 看门狗 | [`docs/子系统设计/看门狗设计说明.md`](../../docs/子系统设计/看门狗设计说明.md) |
|
||||
| BSD Socket API | [`docs/网络/BSD_Socket_API_使用指南.md`](../../docs/网络/BSD_Socket_API_使用指南.md) |
|
||||
| Net 层阻塞模型 | [`docs/网络/Net层阻塞模型架构设计.md`](../../docs/网络/Net层阻塞模型架构设计.md) |
|
||||
| UI 架构 | [`docs/UI设计/UI_设计架构.md`](../../docs/UI设计/UI_设计架构.md) |
|
||||
| 菜单页面 | [`docs/UI设计/菜单页面设计.md`](../../docs/UI设计/菜单页面设计.md) |
|
||||
| 内容页 | [`docs/UI设计/内容页架构.md`](../../docs/UI设计/内容页架构.md) |
|
||||
| 远程显示协议 | [`docs/UI设计/RemoDispBus协议与接收设计说明.md`](../../docs/UI设计/RemoDispBus协议与接收设计说明.md) |
|
||||
| 部署环境 | [`docs/环境与部署/项目部署环境要求.md`](../../docs/环境与部署/项目部署环境要求.md) |
|
||||
| 硬件网表 | [`docs/硬件平台/V0.1_网表详细分析报告.md`](../../docs/硬件平台/V0.1_网表详细分析报告.md) |
|
||||
| 待办登记簿 | [`docs/待处理内容.md`](../../docs/待处理内容.md) |
|
||||
| 体系层评审报告 | [`docs/问题记录/项目审查与优化建议报告.md`](../../docs/问题记录/项目审查与优化建议报告.md) |
|
||||
| 错误码审计 | [`docs/问题记录/错误码传播审计.md`](../../docs/问题记录/错误码传播审计.md) |
|
||||
| 实机测试指南 | [`docs/测试说明/实机测试实施指南.md`](../../docs/测试说明/实机测试实施指南.md) |
|
||||
| 测试标准流程 | [`docs/测试说明/测试开发标准流程.md`](../../docs/测试说明/测试开发标准流程.md) |
|
||||
| RAM 预算与优化 | [`docs/内存管理/RAM使用分析与优化方案.md`](../../docs/内存管理/RAM使用分析与优化方案.md) |
|
||||
| AI 开发规范 | `AGENTS.md`(仓库根) |
|
||||
| 开发者入门 | `README.md`(仓库根) |
|
||||
|
||||
---
|
||||
|
||||
## 12. 变更记录
|
||||
|
||||
| 日期 | 变更 | 说明 |
|
||||
|---|---|---|
|
||||
| 2026-10-05 | 初版 | 基于项目全量内容(架构 / 子系统 / UI / 测试 / 硬件网表 / 待办)编写完整产品需求设计文档:产品定位、六层架构与任务模型、V0.1 硬件规格、10 类功能需求(含 2 项待实现)、接口规范、非功能需求、UI 规格、待实现项与路线图、验收判据 |
|
||||
Reference in New Issue
Block a user