Files
STM32F4-Base/docs/环境与部署/项目部署环境要求.md
wandering1 7efa58d9a1
CI / 静态门禁 (pre-commit) (push) Failing after 25s
CI / 主机侧单测 (MSVC) (push) Successful in 48s
network: 台架 IP 迁到 192.168.31.100,并把重复写死的值收进单一真源
分两段(用户裁定 2026-11-02):先做地址迁移,再把同类字面量收敛成
单一真源,以后再改地址只动一处。

一、IP 迁移 192.168.1.100 → 192.168.31.100(gw 同步 → .31.1)
- 工厂默认:Drivers/BSP/NETCFG/net_cfg.c 的 NET_CFG_DEF_IP/_GW
- 注释/文档示例、主机与板级测试、台架 py 脚本、两份 sim_config.ini
- 字节序教学点同步换算 hex:0x6401A8C0 → 0x641FA8C0(内存
  C0 A8 1F 64),旧版示例引文与历史 Trap 记录按冻结纪律不动
- UI 黄金基准:网口设置 4 态 + shot_info 共 5 张 .bin 由
  check_content_pages.py --update 重刷(渲染值 IP 变了,属预期变更)
- 保留判定:客户点表引用(IEC104/继电保护规划)、芯片手册摘录、
  日期冻结的变更记录行、已退役台架档案 MDK-ARM/retracted_bench_*

二、单一真源收口(A+B+C+D,用户批准全做)
- 新建 test/host/bench_defaults.py:台架 py 默认值唯一定义点
  (DEVICE_IP/DEVICE_GW/PC_IP/NET_BCAST),22 个脚本改为引用;
  MDK-ARM 两探针与 scripts/board_ui_nav.py 经 sys.path shim 引入
- test/board/net_test_task.h 新增 TEST_PC_PEER_IP,板测三处
  PHASE*_REMOTE_IP 改引该宏(保留 -D 覆盖);Phase1 断言改
  memcmp 数组比较,数组各只出现一次
- simulator/tests/check_content_pages.py 从 net_cfg.c 正则解析
  NET_CFG_DEF_* 推导期望值(解析失败即报错、不静默兜底),
  脚本内台架 IP 字面量清零
- 装饰性注释去具体值(net_cfg.h/net_socket.h/net_socket.c/
  net_socket_sim.c);字节序教学 hex 对刻意保留为唯一写值点
- 刻意不动:主机单测夹具 IP(逐文件钉住的任意值是正确测试
  实践)、文档正文 IP(那是文档内容本身)

顺带:scripts/gen_task_table.py 规范串清掉「,B5」——编号清退提交
72b4b094 改了受管区没重跑生成器,task-table 门禁因此一直红

验证:产品 @build 0/0;CH395F 套件开关构建 0/0 后还原产品态;
6 套主机单测 rc=0;content_pages(含宏推导路径)/菜单 8 态/
推流位比对全 PASS;bom-drift 99 无漂移;doc-links/coding-standard/
cppcheck 绿;py_compile 23 文件 + --help 冒烟(含 shim 绝对路径)
2026-11-02 14:46:42 +08:00

653 lines
51 KiB
Markdown
Raw Permalink 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.
# 项目部署环境要求
> 版本:v1.0 日期:2026-09-13
> 适用工程:STM32F4-Base(STM32F407ZGTx + CH395F 以太网 / LVGL UI / FreeRTOS)
> 用途:新机器搭建、环境交接、现场部署时的**一站式环境核对清单**——开发机软件环境、
> 目标板硬件与资源预算、网络/服务现场部署、远端客户端环境、验收步骤与常见环境问题。
> 文中所有版本/参数/数值均取自仓库内配置或本机实测(`AGENTS.md`、`MDK-ARM/*.bat`、
> `simulator/README.md`、`docs/内存管理/`、`docs/子系统设计/网络配置说明.md`、`docs/测试说明/` 等),
> 换机器时以仓库文件为准逐项核对。
---
## 一、环境总览
本项目涉及三类环境,部署前按 §二~§五 逐一核对:
```mermaid
flowchart LR
subgraph DEV["① 开发机(Windows PC)"]
K[Keil MDK-ARM v5<br/>MCU 编译/烧录]
X[STM32CubeMX 6.17.0<br/>外设配置/代码再生成]
S[CMake + VS2019/2026<br/>LVGL PC 模拟器]
P[Python .venv<br/>字体/回归脚本]
T[Python 串口助手 serial_tool<br/>串口调试/自动测试]
U[MSVC (VS2022 生成工具)<br/>主机侧单元测试 cl.exe]
G[Graphviz<br/>引用关系图渲染(可选)]
end
subgraph TGT["② 目标板(DTU 硬件)"]
M[STM32F407ZGTx @168MHz<br/>1MB Flash / 192KB SRAM]
H[CH395F / GD5F2GQ5UE<br/>TPAFE5160 / RS-485 / LED×6]
end
subgraph RMT["③ 远端客户端(PC/浏览器)"]
C[DTU-RemoteLCD<br/>或任意 TCP 客户端]
end
DEV -- "USB:下载器(ST-Link 等)" --> TGT
DEV -- "USB 串口 USART1<br/>COMx @115200 调试日志" --> TGT
TGT -- "以太网(CH395F)<br/>FTP:21 / 对时:8888 / 显示:7003" --> RMT
```
| 环境 | 角色 | 必需性 |
|---|---|---|
| ① 开发机 | MCU 编译/烧录、UI 模拟器、脚本工具链 | 开发/测试必需 |
| ② 目标板 | 运行固件的 DTU 硬件 | 上机必需 |
| ③ 远端客户端 | 远程看图/按键、对时推送、FTP 文件操作 | 现场使用必需 |
---
## 二、开发机环境(Windows)
### 2.1 操作系统与基础
| 项 | 要求 | 说明 |
|---|---|---|
| 系统 | Windows 10/11 x64 | 全部工具链均为 Windows 形态(Keil / VS / SDL / COM 口);本机实测 Win11 |
| 终端 | PowerShell 5.1+ | 构建/测试脚本均为 `.bat` / `.ps1` |
| 版本控制 | git | 提交受 pre-commit 钩子门禁(§2.7) |
| 磁盘 | ≥10 GB 空闲 | Keil 工程 + VS 模拟器 `build/` + 工具链 |
### 2.1.1 本地工具路径环境变量(`DTU_*` 系列,新机器必配项见下表)
仓库脚本**不含本机绝对工具路径**:Keil / ST-LINK / pre-commit Python / MSVC / Windows SDK /
Graphviz / Cppcheck 的安装位置差异一律用 `DTU_*` 环境变量表达(完整契约与解析语义见
`docs/环境与部署/本地工具路径环境变量方案.md`)。新机器装完工具后按表配置:
| 变量 | 必需性 | 值的形态 | 使用方 |
|---|---|---|---|
| `DTU_KEIL_UV4` | **必需**(MCU 构建机) | UV4.exe 完整路径 | `keil_build.py`(`/keil-build`) |
| `DTU_STLINK_CLI` | **必需**(用 ST-LINK CLI 的机器;已在 PATH 可不设) | ST-LINK_CLI.exe 完整路径 | `stlink_flash.py`(烧录/复位/回读) |
| `DTU_PRECOMMIT_PYTHON` | 可选(pre-commit 不在 `.venv`/当前解释器时设;CI runner 建议必设) | 装有 pre-commit 的 python.exe 完整路径 | `scripts/ci_local.py`、CI 静态门禁 / 主机侧纯逻辑单测 |
| `DTU_CPPCHECK` | 可选(开发机入 PATH 即可;无 PATH 的 CI runner 建议设) | cppcheck.exe 完整路径 | pre-commit cppcheck 钩子、CI 静态门禁 |
| `DTU_MSVC_CL` | 可选(VS 标准位置时自动探测) | x64 `cl.exe` 完整路径 | 主机侧纯逻辑单测(本地与 CI) |
| `DTU_WINDOWS_KITS_ROOT` | 可选(SDK 标准位置时自动探测) | `Windows Kits\10` 根目录 | 主机侧单测 |
| `DTU_VSWHERE` | 可选(VS 标准位置时由 `%ProgramFiles(x86)%` 自动推导) | vswhere.exe 完整路径 | `simulator/build_sim.ps1` |
| `DTU_GRAPHVIZ_DOT` | 可选(PATH 可发现时不设) | dot.exe 完整路径 | `tools/refgraph` 渲染 |
```powershell
# 用户级设置(无需管理员;★ 设完必须重开终端/IDE 才生效)
[Environment]::SetEnvironmentVariable('DTU_KEIL_UV4', 'D:\Tools\Keil\UV4\UV4.exe', 'User') # 示例路径
[Environment]::SetEnvironmentVariable('DTU_STLINK_CLI', 'D:\Tools\STLink\ST-LINK_CLI.exe', 'User') # 示例路径
# 其余可选项按实际安装位置补充;验证:$env:DTU_KEIL_UV4 后 Test-Path / 跑对应命令
```
> 统一解析语义:变量**显式设置但无效 → 立即报错**(指出变量名与收到的路径),不静默回退到别的安装;
> 未设置 → 按工具走 PATH / 标准布局自动发现(可选工具允许降级,如 Graphviz 缺失只跳渲染)。
> CI runner 以 **SYSTEM 服务**运行,用户级变量对其不可见——runner 用**机器级**变量注入(见
> `docs/CI/远程CI完整指南.md` §4.1.3)。
### 2.2 MCU 构建工具链(必需)
| 项 | 要求 | 说明 |
|---|---|---|
| Keil MDK-ARM | **v5.x**(须含 ARMCC v5 编译器) | 工程锁定 `uAC6=0`(仅 ARMCC v5,**不支持 armclang**);仅支持此工具链,无其他工具链 |
| 安装路径 | **任意目录** | `keil_build.py` / `stlink_flash.py` 经 `DTU_*` 环境变量解析工具路径(§2.1.1);新机器装完后设置 `DTU_KEIL_UV4` / `DTU_STLINK_CLI` 即可,**无需修改仓库脚本** |
| 设备支持 | STM32F407ZGTx + CMSIS Flash 算法 | 工程引用 `STM32F4xx_1024.FLM`(1MB 片内 Flash,0x08000000),由 CMSIS STM32F4 设备包提供 |
| STM32CubeMX | **6.17.0**(工程 `STM32F407-Demo.ioc` 记录的版本) | 修改外设/引脚/时钟配置并再生成 CubeMX 文件;固件包须 **STM32Cube FW_F4 V1.28.3** |
| 命令行构建 | `& '.venv\Scripts\python.exe' .dsh\skills\keil-build\scripts\keil_build.py`(即 `/keil-build`) | 退出码 0 = 0 错 0 警;失败看 `MDK-ARM/build_log.txt` |
| 命令行烧录 | `& '.venv\Scripts\python.exe' .dsh\skills\stlink-flash\scripts\stlink_flash.py flash`(即 `@download`) | 烧后 `-Rst -Run`;判据 `Programming Complete` + 回读 `No difference found` |
> ⚠ **版本一致性关键**:.ioc 记录 `MxCube.Version=6.17.0` + `FirmwarePackage=STM32Cube FW_F4 V1.28.3`,
> 再生成代码必须用此组合——用更新版本的 CubeMX 会把仓库内 HAL 驱动升级、产生大量无关 diff(见 §六 速查)。
> 自定义代码只写 `USER CODE BEGIN/END` 区域内(再生成时保留,`KeepUserCode=true`),**勿手改生成文件的非 USER CODE 区域**。
**Keil 初始化配置(机器侧项,非项目自带)**:
| 项 | 配置方法 | 说明 |
|---|---|---|
| License | 首次启动 UV4 自动生成 **90 天评估 license**;长期使用需购买正式 license | license 绑定机器、不在仓库;`Options for Target → License` 查看/输入 |
| Device Pack | **Pack Installer** 安装 `Keil::STM32F4xx_DFP`(pack 源 https://www.keil.com/pack/ ) | 工程引用的 **Flash 算法 `STM32F4xx_1024.FLM` 就来自此 pack**(.uvoptx 的 `$$Device:STM32F407ZGTx$` 变量解析到 pack 目录 `<Keil安装目录>\PACK\Keil\STM32F4xx_DFP\<ver>\CMSIS\Flash\`,如 `C:\Keil_v5\...`);**pack 缺失则下载失败**。`Keil::CMSIS` pack **不需要**:核心头文件由仓库 `Drivers/CMSIS/` 提供,`.uvprojx` 只引用 DFP pack(2026-10-02 本机实测:未装 CMSIS pack 构建 0/0 通过;且 keil.com 的 CMSIS pack 直链(5.7.0~6.1.0)均已下架 404,无从安装) |
| 下载器驱动 | 工程已配 **UL2CM3** 调试驱动 + Flash 算法参数(.uvoptx 自带,调试时钟 10 MHz) | 物理下载器(ST-Link 等)需装 USB 驱动(见第 8 步);现场换其他下载器在 Keil `Options for Target → Debug → Settings` 切换 |
> **项目自带、新机器无需重配**(随仓库同步):编译器与目标选项(`.uvprojx`:ARMCC v5 / 设备 STM32F407ZGTx / Cortex-M4+FPU)、
> 调试与下载参数(`.uvoptx`)、Run-Time Environment(`MDK-ARM/RTE/`)、启动文件 `startup_stm32f407xx.s`、构建/下载 bat、
> **RAM/Flash 链接布局(见下)**。
**RAM / Flash 链接布局(项目自带,自动同步,新机器无需在 Keil 里重设)**:
- 链接器使用**手动 scatter 文件** `MDK-ARM/STM32F407-Demo/STM32F407-Demo.sct`(在仓库,`.uvprojx` 已启用 `useFile=1`):
- `ER_IROM1` 0x08000000,1 MB(代码 + 只读数据)
- `RW_IRAM1` 0x20000000,**128 KB**(SRAM1 112K + SRAM2 16K 连续,**DMA 可达区**:存储/网络/串口 DMA
缓冲只能放这里;克隆芯片可能无 SRAM3,换料必须重测)
- `RW_CCM` 0x10000000,**64 KB 减 256 B 尾**(2026-10-11 起启用,承载 FreeRTOS 堆与 `.noinit` 崩溃现场;
**CCM 不可被 DMA 寻址**——规则 R2/R3 见 `docs/内存管理/内存内容分配策略.md` §4,并有编译期窗口断言 +
启动期自检 + 运行时守卫三层强制)
- Keil `Options for Target → Target` 页显示的片上内存来自 `.uvprojx` 的 `<Cpu>` 行(IRAM 112 KB / IRAM2 16 KB / IROM 1 MB,同样在仓库)+ Device Pack(**GUI 那几格不含 CCM 段,别据此判断"CCM 没用"**)
- ⚠ 新机器**不要在 GUI 里重填 RAM 区**,也**勿改 Target 页**(会回写共享的 `.uvprojx` 影响他人);确需调整内存布局(如日后启用 SRAM3/CCM)时修改 `.sct` 并提交
### 2.3 PC 侧编译环境(模拟器 + 主机侧单元测试,必需)
> ⚠ 本节涵盖**两类都要 MSVC 的 PC 侧构建**:① LVGL 模拟器(C++,产物 `lvgl_sim.exe`);
> ② 主机侧单元测试(C,批量离线编译**真实生产源码**,见 §2.10 与
> `docs/测试说明/单元测试/看门狗单元测试说明.md`)。两者共用同一套 VS 安装,**无需装两次**。
| 项 | 要求 | 说明 |
|---|---|---|
| CMake | ≥ 3.15 | 本机实测 4.3.0-rc1;**仅模拟器需要**,单元测试不用 CMake |
| 编译器 | **VS2019 / 2022 / 2026 任一**(C++ x64 工作负载) | `build_sim.ps1` 按本机 VS 大版本自动选生成器(16=2019 / 17=2022 / 18=2026)、`-A x64`;CMakeLists 已加 `/utf-8` 消中文注释告警 |
| **MSVC C 工具链** | **同上(`cl.exe`)** | **主机侧单元测试的必需项**:`test/host/<模块>/run_unit_test.py` 用 `cl.exe` 离线编译真实源码。**只要装了 VS 就有**(`VC\Tools\MSVC\<ver>\bin\Hostx64\x64\cl.exe`),不额外装东西 |
| Windows SDK | 10.0.19041 及以上 | CMake 配置与 `cl.exe` 编译(`stdio.h` 等)都从这里取;随 VS 工作负载勾选安装 |
| SDL2 | 2.32.10(预编译,无需系统安装) | **不在仓库**(`simulator/SDL2/` 目录 gitignore,fresh clone/换机须本地下载一次);缺失时的下载/解压/校验步骤见**第 3 步**。**仅模拟器需要** |
| 产物 | `simulator/build/Debug/lvgl_sim.exe` | `build/` 为生成物(gitignore),可整体删除重建 |
```powershell
& "simulator\build_sim.bat" # 一键构建(自动探测 VS 版本;首次自动配置,改 CMakeLists.txt 后需重跑)
.\simulator\build\Debug\lvgl_sim.exe # 运行(纯键盘导航 ↑↓←→ / Enter / Esc)
# 主机侧单元测试(示例:看门狗判定状态机;纯逻辑、零硬件、秒级)
& '.venv\Scripts\python.exe' test/host/watchdog/run_unit_test.py # 退出码 0=PASS / 1=FAIL / 2=环境错误
```
> 模拟器与 MCU **共用 UI 源码**(`Drivers/BSP/UI/`),无硬件业务(网络推流除外,Winsock 版)。
> 详见 `simulator/README.md`、`docs/UI设计/LVGL模拟器部署与使用说明.md`。
### 2.4 Python 环境(脚本工具链)
| 项 | 要求 | 说明 |
|---|---|---|
| 统一入口 | **仓库 `.venv\Scripts\python.exe`** | 一切依赖第三方库的脚本(字体生成、截图转 PNG、RemoDispBus 回归)都用它 |
| 解释器版本 | Python ≥ 3.10(任意发行版) | 种子解释器仅用于建 venv 一次;本机为 3.12.4 |
| 依赖 | `fonttools==4.51.0`、`pillow==10.3.0`、`pyserial==3.5`、`pre-commit==4.6.2` | 清单 = 仓库根 `requirements.txt`(**必须保持纯 ASCII**:Windows 下 pip 按 GBK 代码页解码,中文注释会 UnicodeDecodeError);`pre-commit` 入 `.venv` 后,重建 venv 即可直接跑静态门禁(`scripts/ci_local.py` 自动选用) |
| 入库情况 | `.venv/` 已 gitignore | **换机/首次必须重建** |
```powershell
# 重建(<种子python> 换成本机任一 python ≥3.10)
& <种子python> -m venv .venv
& '.venv\Scripts\python.exe' -m pip install -r requirements.txt
```
> ⚠ PATH 里默认 `python` 可能是 msys64 的(无第三方库)——**禁止**用它跑字体生成 / Pillow 脚本;
> 纯标准库脚本(UI 回归测试、`extract_cn.py`)任意 python3 均可。
### 2.5 中文字体生成依赖
| 项 | 要求 | 说明 |
|---|---|---|
| Node.js + npm | 任意近期版本 | 一次性:`npm i -g lv_font_conv`(字体位图转换) |
| fontTools | 仓库 `.venv`(§2.4) | `make_font.py` 依赖 |
```powershell
python tools/font_gen/extract_cn.py # 任意 python3:扫 UI 源码 → ui_cn_chars.txt
& '.venv\Scripts\python.exe' tools/font_gen/make_font.py # 宋体 12px 1bpp + 字符集 → ui_font_cn_12.c
```
> 任何 UI 文案新增汉字后必须走此流程(缺字 = 屏幕空白块),详见 `docs/UI设计/UI_中文字体生成与配置.md`。
### 2.6 串口调试 / 自动化测试工具
| 项 | 要求 | 说明 |
|---|---|---|
| Python 串口助手 | `.dsh/skills/serial-assistant/scripts/serial_tool.py`(仓库内置,.venv + pyserial) | 常驻 daemon + 薄 CLI + 全量日志文件;无需单独安装,`pip install -r requirements.txt` 即就绪 |
| 调试串口 | USART1(PA9 TX / PA10 RX),115200 8N1 | **端口单一配置源 `.serialtest/config.json`**(本机 COM6);换端口只改这个文件 |
| 一键测试 | `.dsh/skills/serial-boot-test/scripts/run_boot_test.py`(即 `/serial-boot-test`,`& '.venv\Scripts\python.exe' .dsh/skills/serial-boot-test/scripts/run_boot_test.py`) | 开串口 + 清日志 → 烧录 → wait-idle(静默 8s/超时 30s)→ 提取 → 标记校验;默认端口取 `.serialtest/config.json` / 115200,退出码 0=PASS / 1=FAIL / 2=采集或烧录错误 / 3=用法错误 |
> 采集 = 端口常开 + daemon 全量日志(`.dsh/skills/serial-assistant/scripts/state/serial.log`),无采集窗口/first-byte/EOF 重试仪式。
> 命令契约与陷阱见 `docs/测试说明/测试工具/串口助手设计说明.md`、`docs/测试说明/流程与规范/自动化测试流程.md`。
### 2.7 代码审查钩子(pre-commit)
| 项 | 要求 | 说明 |
|---|---|---|
| pre-commit | 已安装并 `pre-commit install` | 提交门禁(`pre-commit` 阶段 48 根 + commit-msg 阶段 `gitlint`,一次提交实跑 49 根) |
| cppcheck | 在 PATH 中 | 钩子直接调 `cppcheck --enable=warning,performance,portability,style`(`language: system`)。⚠ `cppcheck` / `test-cppcheck` / `test-coverage` 三根带 `stages: [manual]`:`git commit` 不跑,由远端 CI 的「手动阶段门禁」步与 `scripts/ci_local.py` 的 manual 段跑(CI runner 缺 cppcheck 则该步失败) |
| python | 在 PATH 中 | 本地钩子调 `scripts/check_mojibake.py`(U+FFFD 乱码)、`scripts/check_coding_standard.py`(规范 V1.0,纯标准库) |
| **MSVC `cl.exe`** | **装了 VS 即有(§2.3)** | **`watchdog-unit-test` 钩子必需**:改 `App/util/task_watchdog.*` 或 `test/host/watchdog/**` 时触发,用 `cl.exe` 离线编译真实源码跑单测。**未装 VS 时该钩子报环境错误(退出码 2)→ 拦截提交** |
| gitlint | 随 pre-commit 自动拉取 | commit message 格式(宽松规则,兼容中文标题) |
> 检查范围仅项目自有代码;`Lib/`、`Middlewares/`、`Drivers/BSP/UI`、`lftpd`、`dhara`、`test/` 等被排除。
> 全库扫描:`pre-commit run --all-files`(提交期 47 根);三根 manual 钩子逐根复跑:
> `& '.venv\Scripts\python.exe' -m pre_commit run --all-files --hook-stage manual <hook-id>`(一次只能一个 id)。
> 详见 `docs/代码规范/pre-commit使用说明.md`、`docs/代码规范/cppcheck使用说明.md`。
>
> ⚠ **新增主机侧纯逻辑单测钩子(2026-10-01)后,"装了 VS"从"仅模拟器需要"升级为"提交门禁需要"**:
> 只要装了 VS(§2.3)就自动具备,无需额外安装;但**完全未装 VS 的机器在改动看门狗相关文件时会被钩子拦截**。
### 2.8 引用关系图渲染(Graphviz,可选)
| 项 | 要求 | 说明 |
|---|---|---|
| Graphviz | `winget install Graphviz.Graphviz`(本机实测 16.1.0) | `tools/refgraph` 引用关系图生成器的渲染引擎;`dot` 从 **PATH** 查找(winget 安装自动入 PATH);非标准安装目录用 `DTU_GRAPHVIZ_DOT` 指向 `dot.exe`(§2.1.1) |
| 必需性 | **可选** | 未装时工具自动跳过渲染(仍产出 `.dot`/`.json`,装好后重跑即出图);不影响编译/测试/审查门禁 |
| 产物 | `docs/images/引用关系图.*` | 文件级 + 模块级 `.svg`/`.dot`/`.json`(随工具提交入库);PNG 仅本地预览(`docs/images/*.png` 已 gitignore) |
```powershell
winget install Graphviz.Graphviz
& 'tools\refgraph\gen_refgraph.bat' # → docs/images/引用关系图.*(.dot/.svg/.png/.json)+ 生成报告
```
> 图例、语义(文本层引用/未解析归外部)、更新流程与已知限制见 `docs/架构设计/引用关系图说明.md`。
> Keil 工程包含路径解析自 `MDK-ARM/*.uvprojx`(自动跟随);模拟器包含路径变化需同步脚本 `SIM_INCLUDE_DIRS`。
### 2.9 开发机一次性搭建(分步安装命令)
以下命令在 PowerShell 中直接执行(新机器从零搭建,全程约 1~2 小时),逐步对照文末清单打勾。
**第 1 步:git**
```powershell
winget install Git.Git
```
> 手动下载:https://git-scm.com/download/win (Git for Windows)
**第 2 步:Keil MDK-ARM v5 + STM32CubeMX**(GUI 安装,无命令行方式)
- 下载页:<https://www.keil.com/arm/mdk.htm>(MDK-ARM v5.x;90 天评估 license 可先开发;必须含 **ARMCC v5** 编译器——工程锁 `uAC6=0`,armclang 不行)
- **安装目录任意**(装完设置 `DTU_KEIL_UV4` = UV4.exe 完整路径,§2.1.1;默认安装位置即可)
- 装完打开 **Pack Installer** → 安装 `Keil::STM32F4xx_DFP`(提供 STM32F407ZGTx 设备 + `STM32F4xx_1024.FLM` Flash 算法;pack 源 https://www.keil.com/pack/ ,Pack Installer 自动拉取)——**必装,否则烧录失败**(FLM 从 pack 目录解析,不在仓库)。`Keil::CMSIS` pack 不需要:核心头文件由仓库 `Drivers/CMSIS/` 提供(`.uvprojx` 只引用 DFP pack;CMSIS pack 已被 keil.com 下架,2026-10-02 实测各版本直链均 404)
- **License**:首次启动 UV4 自动生成 90 天评估 license(长期使用需购买正式 license;license 绑定机器、不在仓库)
- **STM32CubeMX 6.17.0**:下载页 https://www.st.com/en/tools/stm32cubemx.html (直链 https://www.st.com/resource/en/software_stm32cubemx/stm32cubemx_setup.exe )
- 用途:打开仓库 `STM32F407-Demo.ioc` → 改外设/引脚/时钟 → 生成代码(仅重写 CubeMX 区域,**USER CODE 区域保留**)
- 固件包须 **STM32Cube FW_F4 V1.28.3**(与仓库 HAL 驱动一致;若未随附,在 CubeMX `帮助 → 管理` 下载对应包)
- ⚠ 更新版本的 CubeMX 会升级 HAL 驱动、产生大量无关 diff,**勿随意用最新版**
**第 3 步:VS(2019/2022/2026 任一)+ CMake**(模拟器工具链 **+ 主机侧单元测试编译器 MSVC**)
```powershell
winget install Kitware.CMake # ≥3.15(仅模拟器用;单元测试不用 CMake)
```
- VS 版本不固定:构建入口 `simulator\build_sim.bat` 自动探测本机 VS 大版本选生成器(16=2019 / 17=2022 / 18=2026),装任一即可
- **这一个 VS 同时提供两样东西**:① 模拟器的 C++ 工具链 + CMake 生成器;② **主机侧单元测试的 `cl.exe`**(§2.3 / §2.10)——装一次即可,**不需要为单测另装编译器**
- 新装选 VS2019 的注意:Community 已下架主站,从**存档页**下载:<https://visualstudio.microsoft.com/zh-hans/vs/archives/>(直链:<https://aka.ms/vs/16/release/vs_community.exe>);装 VS2022/VS2026 走主站下载
- 工作负载勾选 **“使用 C++ 的桌面开发”**;单个组件勾对应 **Windows 10/11 SDK**(**`cl.exe` 编 `stdio.h` 等标准头也依赖此处安装的 SDK**)
- **SDL2 无需系统安装**(用预编译 SDK),但**不在仓库**——`simulator/SDL2/` 被 gitignore,`git clone` 后本地没有;目录不存在时按下面步骤补一次
**补 SDL2 SDK(仅当 `simulator/SDL2/` 缺失)**
```powershell
# 1) 下载官方 2.32.10 VC 预编译包(GitHub Releases,约 7 MB)
New-Item -ItemType Directory -Force simulator\SDL2 | Out-Null
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri "https://github.com/libsdl-org/SDL/releases/download/release-2.32.10/SDL2-devel-2.32.10-VC.zip" `
-OutFile simulator\SDL2\SDL2-devel-2.32.10-VC.zip -UseBasicParsing
# 2) 解压到 simulator/SDL2/;顶层目录名须为 SDL2-2.32.10
# (若解压出 SDL2-devel-2.32.10/,改名为 SDL2-2.32.10/)
Expand-Archive simulator\SDL2\SDL2-devel-2.32.10-VC.zip -DestinationPath simulator\SDL2 -Force
# 3) 头文件复制到 include/SDL2/ 子目录(必做:LVGL SDL 驱动写死 #include "SDL2/SDL.h")
$inc = "simulator\SDL2\SDL2-2.32.10\include"
New-Item -ItemType Directory -Path "$inc\SDL2" -Force | Out-Null
Copy-Item "$inc\*.h" "$inc\SDL2\"
# 4) 校验 5 个必备文件(全 True = 就绪),然后删 zip
foreach ($f in @("include\SDL.h", "include\SDL2\SDL.h", "lib\x64\SDL2.lib",
"lib\x64\SDL2main.lib", "lib\x64\SDL2.dll")) {
"{0} : {1}" -f $f, (Test-Path "simulator\SDL2\SDL2-2.32.10\$f")
}
Remove-Item simulator\SDL2\SDL2-devel-2.32.10-VC.zip
```
目标目录结构:
```
simulator/SDL2/SDL2-2.32.10/
├── include/ ← SDL.h 及各头文件
│ └── SDL2/ ← 头文件副本(第 3 步;缺它编译报 C1083: cannot open include file "SDL2/SDL.h")
└── lib/x64/ ← SDL2.lib / SDL2main.lib / SDL2.dll(构建与运行均从此取)
```
> 内网机器连不上 GitHub:在任一台有网的机器下载 zip(release 页:<https://github.com/libsdl-org/SDL/releases/tag/release-2.32.10>)拷过去,再走上面第 2~4 步。
**第 4 步:Python**(`.venv` 脚本工具链)
```powershell
winget install Python.Python.3.12 # 或任一 ≥3.10;手动:https://www.python.org/downloads/windows/
# 仓库根目录建 venv(种子解释器用刚装的 python 即可)
python -m venv .venv
& '.venv\Scripts\python.exe' -m pip install -r requirements.txt
```
> `python` 不可用时改用完整路径 `& "$env:LOCALAPPDATA\Programs\Python\Python312\python.exe" -m venv .venv`。
> `requirements.txt` 必须保持**纯 ASCII**;之后一切依赖第三方库的脚本只用 `.venv\Scripts\python.exe`。
**第 5 步:Node.js + 字体工具**
```powershell
winget install OpenJS.NodeJS.LTS # 手动:https://nodejs.org/ (选 LTS)
npm i -g lv_font_conv # 手动:https://www.npmjs.com/package/lv_font_conv
```
**第 6 步:pre-commit + cppcheck**(提交门禁)
```powershell
winget install astral-sh.uv
uv tool install pre-commit
winget install cppcheck # 2.21.0(安装位置任意;入 PATH 或用 DTU_CPPCHECK 指向)
# ★ 重开终端(PATH 才生效),然后:
pre-commit install
pre-commit run --all-files # 首次全库基线扫描(提交期 47 根)
# manual 阶段三根(cppcheck / test-cppcheck / test-coverage,提交期不跑)逐根跑,一次一个 id:
& '.venv\Scripts\python.exe' -m pre_commit run --all-files --hook-stage manual cppcheck
```
> 手动下载:uv → https://astral.sh/uv/ (一行安装 `powershell -c "irm https://astral.sh/uv/install.ps1 | iex"`)· pre-commit → https://pre-commit.com/ · cppcheck 2.21.0 → https://github.com/CppQA/cppcheck/releases (2.21.0 tag 的 Windows x64 zip,解压至任意目录并加入 PATH,或用 `DTU_CPPCHECK` 指向 `cppcheck.exe`)
**第 7 步:Python 串口助手**(串口调试 / 自动测试,仓库内置)
无需单独安装:`.dsh/skills/serial-assistant/` 随仓库提供,依赖 `pyserial`(已入 `requirements.txt`,第 4 步建 `.venv` 时一并安装)。建成后验证:
```powershell
& '.venv\Scripts\python.exe' .dsh\skills\serial-assistant\scripts\serial_tool.py selftest # → SELFTEST PASS
& '.venv\Scripts\python.exe' .dsh\skills\serial-assistant\scripts\serial_tool.py ports # 枚举 COM 口
```
**第 8 步:下载器驱动**(ST-Link)
- ST 官网下载 **STM32CubeProgrammer** 运行一次(自动安装 ST-Link USB 驱动):https://www.st.com/en/development-tools/stm32cubeprog.html
- 仅需要 ST-Link V2 驱动时:https://www.st.com/en/development-tools/stm321025.html (`ST-LinkV2-USB-Driver` 包)
- Keil `Options for Target → Debug` 确认驱动与实物一致(工程已配 UL2CM3 框架)
**第 9 步:串口配置**
```powershell
& '.venv\Scripts\python.exe' .dsh\skills\serial-assistant\scripts\serial_tool.py ports # 查 COM 号
```
把查到的端口写入 `.serialtest\config.json` 的 `portName`(唯一配置源,换口只改这里)。
**第 10 步:冒烟验证**(全过 = 环境就绪;前置:§2.1.1 的 `DTU_*` 变量已设置——未设时构建脚本会明确报出缺哪个变量及设置方法)
```powershell
& '.venv\Scripts\python.exe' .dsh\skills\keil-build\scripts\keil_build.py # → BUILD_OK: 0 errors, 0 warnings
& "simulator\build_sim.bat" # 模拟器一键构建(自动探测 VS 版本),0 警告
.\simulator\build\Debug\lvgl_sim.exe # 出 160×160 单色菜单画面
& '.venv\Scripts\python.exe' simulator\tests\check_menu_rows.py # PASS
& '.venv\Scripts\python.exe' simulator\tests\check_content_pages.py # PASS(基准 ref/*.bin 已入库,无需先生成)
& '.venv\Scripts\python.exe' .dsh\skills\serial-assistant\scripts\serial_tool.py selftest # → SELFTEST PASS
& '.venv\Scripts\python.exe' test\host\watchdog\run_unit_test.py # 主机侧单测 → 39/39 PASSED(退出码 0)
pre-commit run --all-files # 提交期 47 根(manual 三根另跑:--hook-stage manual <id>,或直接 ci_local.py)
```
**搭建清单汇总**(随步骤逐项打勾):
- [ ] Windows 10/11 x64 + PowerShell 5.1+
- [ ] Keil MDK-ARM v5.x 已装(任意目录,`DTU_KEIL_UV4` 已设 UV4.exe 完整路径,§2.1.1)+ STM32F4 DFP 包(CMSIS pack 不需要,见 §2.2)
- [ ] STM32CubeMX 6.17.0 已装(与 .ioc 版本一致;含/可装 STM32Cube FW_F4 V1.28.3 固件包)
- [ ] VS2019 / 2022 / 2026 任一(C++ x64 工作负载)+ Windows 10/11 SDK + CMake ≥3.15(模拟器构建脚本自动适配 VS 版本;**同一 VS 提供主机侧单测所需的 `cl.exe`**,见 §2.3 / §2.10)
- [ ] `git clone` 仓库 → `pre-commit install`;cppcheck 入 PATH
- [ ] 建 `.venv` 并 `pip install -r requirements.txt`
- [ ] `npm i -g lv_font_conv`
- [ ] 写好 `.serialtest/config.json`(本机 COM 口),`serial_tool selftest` PASS
- [ ] 下载器(ST-Link 等)USB 驱动已装,Keil `Options for Target → Debug` 驱动一致
- [ ] 第 10 步冒烟验证全部通过(含 `test/host/watchdog/run_unit_test.py` → PASSED)
- [ ] (可选)Graphviz 已装(引用关系图渲染:`winget install Graphviz.Graphviz`,见 §2.8)
### 2.10 手动下载来源速查
§2.9 中需下载组件的官方下载地址汇总(正文的 winget / 命令行方式优先;网络受限时按本表手动下载):
| 组件 | 官方下载页 | 版本 / 说明 |
|---|---|---|
| Git for Windows | https://git-scm.com/download/win | 最新稳定版 |
| Keil MDK-ARM | https://www.keil.com/arm/mdk.htm | v5.x,须含 ARMCC v5;安装目录任意(`DTU_KEIL_UV4` 设 UV4.exe 完整路径) |
| STM32F4xx DFP | https://www.keil.com/pack/ | 在 Keil Pack Installer 内装 `Keil::STM32F4xx_DFP`(CMSIS pack 不需要/已下架,见 §2.2) |
| STM32CubeMX | https://www.st.com/en/tools/stm32cubemx.html | 6.17.0(与 .ioc 一致);直链 https://www.st.com/resource/en/software_stm32cubemx/stm32cubemx_setup.exe |
| STM32Cube FW_F4(固件包) | https://www.st.com/en/embedded-software/stm32cube-f4.html | V1.28.3(与仓库 HAL 驱动一致) |
| Visual Studio 2019 | https://visualstudio.microsoft.com/zh-hans/vs/archives/ | 直链:https://aka.ms/vs/16/release/vs_community.exe |
| Visual Studio 2022 / 2026 | https://visualstudio.microsoft.com/zh-hans/downloads/ | 任一版本均可(模拟器构建 + 主机侧单测 `cl.exe`,二者共用) |
| CMake | https://cmake.org/download/ | ≥ 3.15 |
| Python | https://www.python.org/downloads/windows/ | ≥ 3.10,推荐 3.12 |
| Node.js | https://nodejs.org/ | LTS |
| lv_font_conv | https://www.npmjs.com/package/lv_font_conv | 一般 `npm i -g lv_font_conv` |
| uv | https://astral.sh/uv/ | `powershell -c "irm https://astral.sh/uv/install.ps1 \| iex"` |
| pre-commit | https://pre-commit.com/ | 一般 `uv tool install pre-commit` |
| cppcheck | https://github.com/CppQA/cppcheck/releases | 2.21.0 的 Windows x64 zip(`cppcheck-2.21.0-windows-x64.zip` 形式),解压入 PATH |
| STM32CubeProgrammer | https://www.st.com/en/development-tools/stm32cubeprog.html | 含 ST-Link USB 驱动 |
| ST-Link V2 驱动 | https://www.st.com/en/development-tools/stm321025.html | `ST-LinkV2-USB-Driver` 包 |
| SDL2(仅仓库预编译库缺失时) | https://github.com/libsdl-org/SDL/releases | 2.32.10,一般不需要 |
| Graphviz | https://graphviz.org/download/ | 一般 `winget install Graphviz.Graphviz`;未装时引用关系图工具跳过渲染(§2.8),不阻塞其他工具链 |
> 获取渠道优先级:① `winget`(自动校验、免手动)→ ② 上表官方页 → ③ 网络受限时自行选可信镜像;
> Keil / ST 官网访问受限时可走代理。
### 2.11 CI runner 环境(Gitea Actions,2026-10-01 起)
CI 跑 **静态门禁 + 主机侧纯逻辑单测**(**不含板端测试套件 / 主机侧回归 / 人工目检**——需真机 + ST-LINK,只在本地)。
workflow 见 `.gitea/workflows/ci.yml`;覆盖边界与判定细节见 [`../测试说明/流程与规范/测试开发标准流程.md`](../测试说明/流程与规范/测试开发标准流程.md) §9。
| 项 | 要求 | 说明 |
|---|---|---|
| Gitea 版本 | ≥ 1.21(实测远程 **1.25.4**) | workflow 置于 `.gitea/workflows/`,兼容 GitHub Actions 语法 |
| Actions 开关 | 实例 `[actions] ENABLED = true` | site admin 配置;未开启则 push 不触发任何 job |
| runner OS | **Windows**(`runs-on: windows`) | labels 须含 `windows`;与开发机同平台,避免脚本语法分叉 |
| runner 软件 | Python 3.x、cppcheck、pre-commit、**MSVC**(VS C++ 工具链 + Windows SDK) | 前三个缺 → `static-gates` **硬失败**(`::error::`);MSVC 缺 → `host-unit-tests` **降级跳过并告警**(不硬失败,但等于主机侧纯逻辑单测裸奔)。runner 以 SYSTEM 服务运行,**用户级 PATH/变量不可见**:自动发现失败时用**机器级** `DTU_PRECOMMIT_PYTHON` / `DTU_CPPCHECK` / `DTU_MSVC_CL` 注入(见 `docs/CI/远程CI完整指南.md` §4.1.3) |
| Keil | **不需要** | 刻意不跑 `/keil-build`(需授权);`.map` 缺失时 `mem-numbers` 钩子自动跳过 |
| `mem-numbers` | 有 `.map` 就跑,无则 `SKIP` | Keil 构建产物 `.map` 已 gitignore;自建带 Keil 的 runner 会照常跑该钩子 |
**runner 就绪前的过渡**:CI 只是"多一道网",**不能替代本地门禁**。提交前仍须在本地跑:
```powershell
& '.venv\Scripts\python.exe' scripts/ci_local.py # 与 CI 同一套判定(静态门禁 + 主机侧纯逻辑单测)
```
### 2.12 跨机验证(第二台机器 / 换机验收清单)
验收判据(对应 `本地工具路径环境变量方案.md` 的最终验收):新电脑只按 §2.1.1 配置本机
`DTU_*` 变量,clone 仓库后**不修改任何 `.bat/.py/.ps1/.yml` 中的本机路径**即可运行开发命令。
工具安装清单同 §2.9 第 1~8 步(**刻意指定与旧机不同的安装目录**,才能真正验证跨路径);
按下表顺序执行,任一步不达预期即停下排查。
**第 1 步:配置变量 + sanity check**
```powershell
# 用户级(无需管理员);值填本机实际安装路径
[Environment]::SetEnvironmentVariable('DTU_KEIL_UV4', '<本机 UV4.exe 完整路径>', 'User')
[Environment]::SetEnvironmentVariable('DTU_STLINK_CLI', '<本机 ST-LINK_CLI.exe 完整路径>', 'User')
# ★ 关闭并重开终端(旧终端持有设置前的环境快照——最常见的"假失败"来源)
# 重开后验证:
Test-Path $env:DTU_KEIL_UV4 # True
Test-Path $env:DTU_STLINK_CLI # True
```
**第 2 步:验证链**(每步有明确期望;①②③④ 全过 = 该机器验证通过)
| # | 命令 | 期望 | 失败诊断 |
|---|---|---|---|
| ① | `& <任一 python> -m venv .venv` + `& '.venv\Scripts\python.exe' -m pip install -r requirements.txt` | 安装完成且含 pre-commit | pip 报 GBK 解码错 = `requirements.txt` 被污染(该文件必须纯 ASCII,不该发生) |
| ② | `& '.venv\Scripts\python.exe' .dsh\skills\keil-build\scripts\keil_build.py` | `BUILD_OK: 0 errors, 0 warnings`,exit 0 | 报错行**直接指出变量名**(如 `BUILD_ENV_ERROR: $DTU_KEIL_UV4 is set but not a file: ...`)——照报错修值;新机器首次启动 UV4 需 license(90 天评估),缺 Device Pack 则下载失败(构建不受影响) |
| ③ | `& '.venv\Scripts\python.exe' scripts/ci_local.py` | 静态门禁全钩子 Passed + 主机侧纯逻辑单测断言全部通过(当前 278 条),exit 0 | "找不到 MSVC" = VS 未装或装到非标准位置(设 `DTU_MSVC_CL` 可验证覆盖通道) |
| ④ | `& 'tools\refgraph\gen_refgraph.bat'` → `git status` | 重生成后 `docs/images/` **无 diff**(图内容只依赖源码,与本机工具链无关) | 出现 diff = 异常,需查 |
| ⑤ | `& "simulator\build_sim.bat"` | 自动探测 VS → 生成器匹配 → 构建成功(2026-10-02 起模拟器构建可用:配置引擎重构的文件迁移已同步进 `simulator/CMakeLists.txt`) | 报 `Cannot find source file` / `C1083` = CMakeLists 与源码目录再次失步(查文件迁移记录),与 `DTU_*` 变量无关;"未探测到 VS" 见 §2.3 |
| ⑥ | (有 ST-LINK 硬件才执行)`& '.venv\Scripts\python.exe' .dsh\skills\stlink-flash\scripts\stlink_flash.py list` | 列出探针 SN | 只跑 `list`,**不烧录不复位**;无硬件跳过不扣分 |
**第 3 步:反向测试**(验证"显式值无效 = 硬报错、不静默回退"语义,约 1 分钟)
```powershell
$env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级值
& '.venv\Scripts\python.exe' .dsh\skills\keil-build\scripts\keil_build.py
# 期望:BUILD_ENV_ERROR: $DTU_KEIL_UV4 is set but not a file: D:\NotExist\UV4.exe,exit 2
# 关键判定:没有回退去猜别的 Keil 安装,而是明确报错
# 测完重开终端即恢复(用户级值未动)
```
**通过判定**:①②③④ 全过 = 该机器验证通过(⑤ 的既有 CMake 问题、⑥ 无硬件跳过均不扣分)。
两台不同安装路径的机器都通过 = 环境变量方案的跨机验收闭环(方案阶段 C 出口标准)。
---
## 三、目标板环境(DTU 硬件)
### 3.1 主芯片
| 项 | 值 | 说明 |
|---|---|---|
| MCU | STM32F407ZGTx | Cortex-M4,**单精度** FPU(VFPv4-SP,**无硬件双精度**,`double` 走软件模拟;无 TrustZone),LQFP144 |
| 主频 | 168 MHz | HSE 8 MHz → PLL M=4 / N=168 / P=2(`Inc/stm32f4xx_hal_conf.h`) |
| Flash | 1 MB(0x08000000) | 片内 |
| SRAM | 192 KB(128 KB 主 + 64 KB CCM) | **两块都在用**:主 SRAM1 128 KB(DMA 可达)+ CCM(FreeRTOS 堆);SRAM3 仍未映射 → §3.3 |
| RTOS | FreeRTOS V10.3.1(CMSIS-RTOS V2) | HAL 时基 TIM7,tick = 1 ms;NVIC 4 位抢占,外设中断优先级 ≥5 |
### 3.2 外设硬件要求(引脚级)
> **口径 = V0.1 硬件**:引脚以 `Inc/main.h`(CubeMX 生成)与
> [`docs/硬件平台/V0.1_网表详细分析报告.md`](../硬件平台/V0.1_网表详细分析报告.md) §4.1 为准。
> V0.0 与本表的差异集中在三处:TPAFE 控制组 7 线(`PD1/PD3/PD4/PD7` + `PF13/14/15` → `PC6/PC8/PC9/PC7` + `PA12/11/8`)、
> RS-485 所在串口实例(UART5 → **UART4**)、LED1/LED2 驱动脚(`PC4/PC5` → `PC5/PB0`)。
| 外设 | 接口 | 引脚 | 备注 |
|---|---|---|---|
| CH395F 以太网 | SPI2 | PB12 CS / PB13 SCK / PB14 SDO / PB15 SDI | PHY 强制 100M 全双工;SPI 分频系数必须为 8(PCB 设计约束,速度受限) |
| GD5F2GQ5UE NAND(2 Gbit) | SPI1 | PE0 CS / PB3 SCK / PB4 MISO / PB5 MOSI / PB8 WP / PE1 HOLD | FatFS(FAT32)+ dhara FTL;上电无卷自动 `f_mkfs` |
| TPAFE5160 ADC | 并行 16 位 | PG0~PG15 数据 / **PC6 FRSTDATA** / **PC7 BUSY(EXTI9_5)** / **PC8 RD** / **PC9 CONVST** / **PA8 OS2 · PA11 OS1 · PA12 OS0** | **编译期常驻**(无裁剪开关;原 `APP_ADC_ENABLE` 未接线占位宏已于 2026-10-22 删除) |
| USART1(调试串口) | UART | PA9 TX / PA10 RX | 115200 8N1;printf 日志 + `/serial-boot-test` 采集通道 |
| UART4(RS-485) | UART | **PC10 TX / PC11 RX / PA15 DE** | 半双工 115200;`app_main.c` 以 `rs485_init(&g_rs485, &huart4, ST_DIR4_GPIO_Port, ST_DIR4_Pin)` 绑定;**编译期常驻**(无裁剪开关;原 `APP_RS485_ENABLE` 占位宏已删) |
| 状态 LED ×6 | GPIO | **PC5 / PB0 / PB1 / PB2 / PF11 / PF12**(LED1~LED6) | **低电平点亮**;网名↔实板丝印为 `LED(n+4)` 倒序(V0.1 网表关注点 V3),固件 LED 序表须按丝印对齐 |
### 3.3 资源预算(部署红线)
实测(**2026-10-22 `/keil-build` 快照**)。实时权威值恒以 `docs/内存管理/RAM预算台账.md` 与
`docs/内存管理/RAM使用分析与优化方案.md` §2.1 受管快照为准,本节只是部署视角的摘要:
| 资源 | 已用 | 总量 | 利用率 | 余量 | 红线说明 |
|---|---|---|---|---|---|
| Flash(`ER_IROM1` = Code + RO) | 232,536 B(227.09 KB) | 1 MB | 22.2% | ≈804 KB | **充裕**:产品需求无 OTA / 双镜像预算,Flash 不是卡点;死代码裁剪簇已收口 → `docs/内存管理/RAM使用分析与优化方案.md` §2.6.4 |
| 主 SRAM1(静态区;FreeRTOS 堆已迁 CCM) | 75,264 B(73.5 KB) | 128 KB | 57.4% | 55,808 B | 已不紧张——2026-10-11 堆迁 CCM 与 2026-10-15 `LV_MEM_SIZE` 40→16 KB 两步的结果 |
| CCM(`RW_CCM` 段) | 57,376 B(56.0 KB) | 65,280 B | **87.9%** | **7,904 B** | **当前真正的红线**:加任务 / 抬栈 / 加堆会先在这里撞墙;`mem-budget` 钩子在 92% 拦提交 |
- LVGL 内存池 16 KB(静态占用,2026-10-15 由 40 KB 收缩);FreeRTOS 堆 56 KB(CCM)
- **任务栈配置不在本文重复**:唯一事实源是 `Src/freertos.c`(`.ioc` 的 `FREERTOS.Tasks01`),
受管表只有两份——根 `README.md` 与 `AGENTS.md` 里由 `scripts/gen_task_table.py --write` 生成的
`TASK_TABLE` 块,由 `task-table` 钩子校验;每任务的静态最坏链、实测峰值与余量台账在
`docs/内存管理/RAM使用分析与优化方案.md` §2.3(配置与实测峰值)与 §4.0.6(静态最坏链与判定)。
- ⚠ **不要再在本文抄一份任务表**:`task-table` 钩子的校验面只有上面那两份受管块,抄出来的副本
没有门禁、改栈后必然漂(2026-10-22 删除本文历史副本时,它已缺 `adcTask` / `iec104Task` /
`protectTask` 三个任务,`defaultTask`/`timeSyncTask` 两值也停在旧数)。
> 挖潜方向:**SRAM3 64 KB 仍未映射**;CCM 64 KB **已启用**(2026-10-11 起承载 FreeRTOS 堆,见上表
> `RW_CCM` 行),配额与台账 → `docs/内存管理/RAM预算台账.md`。
> 部署侧含义:**新增需要额外 RAM 的固件定制前必须先过内存预算**——余量集中在 SRAM1,CCM 只剩
> 7,904 B,加任务 / 抬栈 / 加堆会先在 CCM 撞墙。
### 3.4 下载与调试
| 项 | 说明 |
|---|---|
| 下载方式 | `& '.venv\Scripts\python.exe' .dsh\skills\stlink-flash\scripts\stlink_flash.py flash`(ST-LINK_CLI:烧写 + Reset & Run) |
| 下载器 | 工程已配 `UL2CM3` 调试驱动 + `STM32F4xx_1024` Flash 算法;**物理下载器按现场选择**(本机为 ST-Link——不占 COM 口,可与串口调试并存);新机器在 Keil `Options for Target → Debug → Settings` 选择与硬件一致的驱动 |
| 调试日志 | USART1 115200;抓开机日志必须**先武装采集再复位**(`.dsh/skills/serial-boot-test/scripts/run_boot_test.py --flash-cmd` 已保证顺序) |
### 3.5 功能配置开关
| 开关 | 位置 | 当前值 | 说明 |
|---|---|---|---|
| 功能裁剪开关 | — | 无 | **当前没有任何可裁剪的编译开关**(2026-10-22):原 `APP_NET_ENABLE` / `APP_ADC_ENABLE` / `APP_RS485_ENABLE` 三个宏全库零消费点,已于 2026-10-22 删除,`App/app/app_cfg.h` 只留决策占位说明。要不要真实门控取决于产品定义(开放问题见 `docs/任务规划/登记簿.md` §9);在此之前各模块一律编译进产品 |
| `TEST_SUITE_*` | `test/board/test_config.h` | 全注释(产品构建) | 测试套件**互斥**:一次构建只开一个(CH395F / 存储 / GD5F / RTC);全注释 = 正常产品固件 |
---
## 四、网络与现场部署
### 4.1 网络参数
| 参数 | 工厂默认 | 修改方式 |
|---|---|---|
| IP | **192.168.31.100**(静态,无 DHCP) | 屏幕 `通讯参数 → 网口设置`(修改密码 `123`)保存后**立即生效**(网络重建约 1~3 s);或预置 `/config.ini`(INI;旧版 `/cfg/netcfg.bin` **不再读取**——存在则忽略、不迁移,配置回落工厂默认,2026-10-10 起) |
| 子网掩码 | 255.255.255.0(/24) | 同上 |
| 默认网关 | 192.168.31.1 | 同上 |
| MAC | 全零 = 芯片内置 MAC | 同上(全零是"使用芯片内置 MAC"的哨兵,不是"MAC 为 0") |
| PHY | 强制 100M 全双工 | 固件固定,不可配 |
- 配置持久化:NAND 上通用配置文件 `/config.ini`(INI `[network]` 段;缺失/损坏回退工厂默认并重建模板,不带崩网络)
- 立即生效机制:保存 → netTask 重建网络 → 代次号递增 → 三个 TCP 服务自动重建监听(**既有连接会断开**,属预期)
### 4.2 服务端口(现场连通性核对)
| 服务 | 协议/端口 | 用途 | 核对方法 |
|---|---|---|---|
| 远程显示(RemoDispBus) | TCP **7003** | 远端看图(160×160 1bpp,3200 B/帧,客户端 LCDMEM 拉取)+ 远端导航按键 | DTU-RemoteLCD 或任意 TCP 客户端连 7003 收帧 |
| 墙钟对时 | TCP **8888** | PC 主动推送时间到设备 | 对时推送后核对设备时间 / 日志时间戳 |
| FTP | TCP **21** | 文件上传/下载(根目录 `/`,NAND 存储) | 任意 FTP 客户端列目录/读写 |
> 现场组网要求:设备与客户端**同网段**(默认 .100/24、网关 .1);跨网段部署先按 §4.1 改 IP 再上线。
### 4.3 存储与运行时
- 文件系统:FatFS(FAT32)挂 NAND;**上电无卷自动格式化**(`f_mkfs`);格式化会清除卷上全部文件(含网口配置 `/config.ini`)
- RTC:SD2506 芯片(驱动 `Drivers/BSP/SD2506/`)提供墙钟基准与日志时间戳;首次使用建议先经 8888 对时
- 启动时序:`app_main_init`(存储 → 时钟 → RS485 → NAND → ADC → 启动转换)→ 就绪屏障(STORAGE / NET / FTP / TIMESYNC 事件)→ 六任务运行;详见 `docs/架构设计/项目启动顺序管理.md`、`docs/架构设计/项目架构总览.md`
### 4.4 现场验收清单
| # | 项目 | 方法 | 通过标准 |
|---|---|---|---|
| 1 | 上电自启动 | 断电上电 + 串口采集 | `/serial-boot-test` PASS:Required `App init OK;Network Init;net init: OK;PHY: 100M FULL`,无 `FAIL/ERROR/HardFault` |
| 2 | 网络连通 | PC ping 192.168.31.100 | 通(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 随系统状态变化(低电平点亮) |
---
## 五、远端客户端环境
| 项 | 要求 | 说明 |
|---|---|---|
| 操作系统 | 任意(Windows / Linux / macOS,有浏览器或 Python 即可) | 与设备同网段 |
| 远程显示客户端 | **DTU-RemoteLCD**(独立项目:Flask + WebSocket 参考实现)或任意符合 RemoDispBus 协议的 TCP 客户端 | 连设备 **TCP 7003**;协议见 `docs/UI设计/RemoDispBus协议与接收设计说明.md` |
| 对时工具 | 任意可 TCP 推送的工具/脚本 | 向设备 **8888** 推送 |
| FTP 客户端 | 任意(资源管理器 / FileZilla 等) | 设备端 lftpd,端口 21 |
| 浏览器 | Chrome / Edge | 查看参考客户端 Web 页;开发期浏览文档 SVG 图 |
> 客户端侧**无强制版本依赖**——协议是纯 TCP 字节流(`[TAG][CMD][LEN][DATA][CRC]` 帧),
> 任何语言均可实现;单连接模型(同一时刻一个客户端)。
---
## 六、常见环境问题速查
| 现象 | 原因 | 处理 |
|---|---|---|
| `keil_build.py` 报 `DTU_KEIL_UV4` 未设/无效 | `DTU_KEIL_UV4` 未设置或指向错误路径(**设完变量须重开终端**) | 设置/修正 `DTU_KEIL_UV4` 为 UV4.exe 完整路径(§2.1.1),重开终端重试 |
| `stlink_flash.py` 报 `ST-LINK_CLI.exe not found` / `ENV_ERROR: DTU_STLINK_CLI` | `DTU_STLINK_CLI` 未设且不在 PATH,或显式值无效 | 设置 `DTU_STLINK_CLI` 为 ST-LINK_CLI.exe 完整路径,或把其目录加入 PATH;显式值无效时**不会**回退,须修值 |
| Keil 编译报编译器不识别 | 新装 MDK 只有 armclang | 工程锁 `uAC6=0`,必须用带 **ARMCC v5** 的 MDK v5.x |
| CubeMX 再生成后出现大量 diff / 新告警 | 用了比工程记录更新的 CubeMX / 固件包版本 | 用 git 还原生成文件,按 **.ioc 记录的 CubeMX 6.17.0 + STM32Cube FW_F4 V1.28.3** 重新生成 |
| CMake 配置失败:找不到生成器 | 本机 VS 大版本与生成器不匹配 | 统一走 `simulator\build_sim.bat`(自动探测 VS 版本选生成器);手动 cmake 时 `-G` 号须与本机 VS 一致(16=2019 / 17=2022 / 18=2026) |
| 模拟器构建报 `SDL2/SDL.h` 找不到 | `simulator/SDL2/` SDK 缺失(不入库)或头文件副本没做 | 按第 3 步"补 SDL2 SDK"完整走一遍(下载 → 解压 → 头文件复制到 `include/SDL2/` → 5 文件校验) |
| **`run_unit_test.py` 退出码 2 / 报"找不到 MSVC cl.exe"** | 本机未装 VS(C++ 工作负载) | 按 §2.3 装 VS2019/2022/2026(勾"使用 C++ 的桌面开发"),装完即有 `cl.exe`;**提交看门狗相关改动时该钩子会拦截,必须装** |
| **`run_unit_test.py` 编译报 `C1083: 无法打开包括文件 "stdio.h"`** | VS 未勾选 Windows SDK,或 `cl.exe` 路径异常 | 在 VS Installer 里补勾 **Windows 10/11 SDK**;脚本已按本机 VS/SDK 目录自动拼 `INCLUDE`/`LIB`,无需手动 `vcvars64.bat`(其内部 `reg.exe` 在受限机器上会被安全策略拦截) |
| `.venv` 不存在 / 脚本 ModuleNotFound | venv 未建(不入库) | 按 §2.4 重建 + `pip install -r requirements.txt` |
| pip 装依赖报 UnicodeDecodeError | `requirements.txt` 含中文注释 | 保持该文件**纯 ASCII**(pip 按 GBK 代码页解码) |
| 字体生成 / 转 PNG 报缺模块 | 误用 PATH 里的 msys64 python | 一律用 `.venv\Scripts\python.exe` |
| 内容页回归 FAIL「缺黄金参考」 | `ref/*.bin` 已入库 → 缺失 = 检出不完整(被手工删过 / 不完整的 worktree 副本),**不是**"首次运行" | `git checkout -- simulator/tests/ref/` 取回基准;**不要**用 `--update` 就地造基准(那等于把当前渲染固化成基准) |
| 串口采集不到 / 端口占用 | COM 号变化 / 上一进程未释放 | 改 `.serialtest/config.json`;`serial_tool.py ports` 查实际端口,`open` 占用 ≤1s 报 `port busy` |
| 烧录失败 | 下载器未选 / USB 驱动缺失 | Keil `Options for Target → Debug` 选对驱动;安装下载器 USB 驱动 |
| 下载报 Flash 算法 / FLM 文件找不到 | 未安装 `Keil::STM32F4xx_DFP` pack(FLM 来自 pack 目录,不在仓库) | Pack Installer 安装该 pack 后重新下载 |
| UV4 启动弹 license 窗口 / 无法编译 | 90 天评估 license 过期或未激活 | `Options for Target → License` 查看/输入;长期使用购买正式 license |
| 提交被钩子拦截 | cppcheck / 规范 / 乱码 / gitlint 任一失败 | 按 pre-commit 输出逐项修复;**禁止** `--no-verify` 跳过门禁 |
| 改代码后"没生效" | 新 `.c` 漏双端注册 / 模拟器缓存 | 走 `new-source-file` 双端注册流程;`cmake --build` 增量或删 `simulator/build/` 重建 |
---
## 七、相关文档
| 主题 | 文档 |
|---|---|
| 项目全景架构 | `docs/架构设计/项目架构总览.md` |
| 启动顺序 / 就绪屏障 | `docs/架构设计/项目启动顺序管理.md` |
| 内存预算详析 / 优化方案 / 栈观测 | `docs/内存管理/RAM使用分析与优化方案.md`(主文档)· `docs/内存管理/内存内容分配策略.md`(区域与 DMA 规则) |
| 网口配置 / 生效链路 | `docs/子系统设计/网络配置说明.md` |
| 远程显示协议 | `docs/UI设计/RemoDispBus协议与接收设计说明.md` |
| LVGL 模拟器部署 | `docs/UI设计/LVGL模拟器部署与使用说明.md`、`simulator/README.md` |
| 串口调试 / 自动化测试 | `docs/测试说明/测试工具/串口助手使用指南.md`、`docs/测试说明/测试工具/串口助手设计说明.md`、`docs/测试说明/流程与规范/自动化测试流程.md` |
| **测试分层 / 主机侧纯逻辑单测** | `docs/测试说明/流程与规范/测试开发标准流程.md`(分层与门禁)· `docs/测试说明/单元测试/看门狗单元测试说明.md`(主机侧纯逻辑单测范式:MSVC 离线编译 + 平台桩) |
| **CI(Gitea Actions)** | `docs/CI/README.md`(**远程 CI 唯一入口**:服务端 / Runner 部署与保活 / workflow / 排障,**仅本机一台 runner,日常开发不必读**)· `docs/测试说明/流程与规范/测试开发标准流程.md` §9(覆盖边界) |
| pre-commit / cppcheck | `docs/代码规范/pre-commit使用说明.md`、`docs/代码规范/cppcheck使用说明.md` |
| 引用关系图(文件引用) | `docs/架构设计/引用关系图说明.md`(生成工具 `tools/refgraph`;渲染依赖 Graphviz,§2.8) |
| 各模块测试指南 | `docs/测试说明/板级测试/CH395F_Test_Guide.md`、`GD5F2GQ5UE_Test_Guide.md`、`SD2506_Test_Guide.md`、`FTP_Test_Guide.md` |
| 已知硬件陷阱 | `docs/问题记录/CH395F_Trap_Records.md` 等 |