docs(架构): 全景/启动顺序/存储/引用图与 README 同步任务面与 NET 内部模块

- 项目架构总览 v1.1:§1.1 去重复⑥行、硬件行 UART4/TIM3/ADC1;§2.1
  任务表 6→9 行且栈值按 freertos.c 校准;§3 补采集算法链与 TIM3 节拍;
  §5 补 net_events/net_listener/net_pending 与 iec104_serv,单客户端
  恢复窗更正为实测 p50 208ms;§7 目录树、§9 索引、§10 变更记录同步
- 项目启动顺序管理:任务表 5→10 行;启动轨迹表 8→14 行(fw build、
  ADC input layer、phasor/freq/protection、SD2506 明细、TIM3 启动)
- 存储架构说明:§1 初始化顺序块重写(gd5f 归位 app_main_init 内、
  rs485Task 未创建、补 TIM3 与 L1~L3 链)
- 引用关系图说明 §7 统计与产物重跑刷新;就绪屏障 SVG 补 iec104Task
  消费者后重生成(1400x912)
- README:外设引脚纠错(RS485=UART4/PC10/PC11/PA15、TPAFE 控制脚
  PC8/PC9/PC7)、启动流程补 sys_clock/adc_input/TIM3、任务表重生成
  (9 任务)、目录树与 NET 小节同步、ftp_speed_test→regression/
  integrity、文档表补四条专项索引
- 工具:gen_task_table.py 补 iec104Task/protectTask 职责;
  gen_barrier_svg.py 补 iec104Task 消费者与 bit0 计数
This commit is contained in:
2026-10-14 19:07:48 +08:00
parent 4f8e298394
commit cea2b51efb
14 changed files with 2979 additions and 2653 deletions
+40 -18
View File
@@ -14,10 +14,10 @@
|------|------|------|------|
| CH395F 以太网 | SPI2 | PB12 CS, PB13 SCK, PB14 MISO, PB15 MOSI | 10/100M 以太网控制器 |
| GD5F2GQ5UE NAND | SPI1 | PE0 CS, PB3 SCK, PB4 MISO, PB5 MOSI, PB8 WP, PE1 HOLD | 256MB SPI NAND Flash |
| TPAFE5160 ADC | 并行16位 | PG0-PG15 数据, PD3 RD, PD4 CONVST, PD7 BUSY | 高精度 ADC |
| TPAFE5160 ADC | 并行16位 | PG0-PG15 数据, PC8 RD, PC9 CONVST, PC7 BUSY, PA8/PA11/PA12 OS0~2 | 高精度 ADC |
| USART1 | 串口 | PA9 TX, PA10 RX | 115200bps 调试串口 |
| 6x LED | GPIO | PC4, PC5, PB1, PB2, PF11, PF12 | 低电平点亮 |
| RS-485 | UART5 | PC12 TX, PD2 RX, PD0 DE | 半双工通信 |
| RS-485 | UART4 | PC10 TX, PC11 RX, PA15 DE | 半双工通信(B2 暂缓,见 `docs/任务规划/暂缓-RS485.md`) |
## 项目架构
@@ -25,7 +25,7 @@
flowchart TB
subgraph APP["应用层 (App/)"]
direction LR
A1["app/app_main.c"] ~~~ A2["task/net_task.c"] ~~~ A3["task/ui_task.c"] ~~~ A4["sync/time_sync.c"]
A1["app/app_main.c"] ~~~ A2["task/net_task.c"] ~~~ A3["task/ui_task.c"] ~~~ A4["sync/time_sync.c"] ~~~ A5["algo/(L1~L3)"]
end
subgraph BSP["驱动层 (Drivers/BSP/)"]
direction LR
@@ -51,16 +51,19 @@ flowchart TB
main.c
├─ HAL_Init()
├─ SystemClock_Config() // 168MHz 系统时钟
├─ MX_GPIO/DMA/UART/SPI/I2C_Init() // CubeMX 外设初始化
├─ app_main_init() // 应用层初始化(时间→RS485→NAND→ADC→诊断)
│ ├─ sd2506_init() + sys_clock_init() // 时间子系统优先
├─ MX_GPIO/DMA/UART/SPI/I2C/ADC/TIM/IWDG_Init() // CubeMX 外设初始化
├─ app_main_init() // 应用层初始化(时间→RS485→NAND→ADC→采集算法→诊断)
│ ├─ syslog_mcu_init() // 日志先进 RAM 暂存(内核前安全)
│ ├─ sd2506_init() + sys_clock_init() // 时间子系统优先(墙钟基准)
│ ├─ rs485_init()
│ ├─ gd5f2gq5ue_init()
│ ├─ gd5f2gq5ue_init() // 含 BBT 全片扫描
│ ├─ tpafe5160_init()
│ ├─ adc_input_init() // L1 采集层(语义映射 + STM32 ADC1 DMA)
│ ├─ phasor_init() / freq_init() / prot_set_init() + prot_elm_init() // L2/L3 内核前就绪
│ ├─ SD2506 诊断(ID/时间/温度/电池)
│ └─ tpafe5160_start_conv_irq() // 首次 ADC 转换
│ └─ HAL_TIM_Base_Start_IT(&htim3) // 启动 TIM3 1kHz 采样节拍
├─ osKernelInitialize()
├─ MX_FREERTOS_Init() // 创建任务和事件组
├─ MX_FREERTOS_Init() // 创建 9 任务 + 事件组 + 消息队列
└─ osKernelStart() // 启动调度器
```
@@ -70,17 +73,17 @@ main.c
| 任务 | 栈大小 | 优先级 | 职责 |
|------|--------|--------|------|
| defaultTask | 1280 words | Normal | FTL + FatFS 挂载、配置引擎属主、syslog 唯一写者 |
| netTask | 960 words | Normal | 网络初始化 + CH395F 轮询 |
| netTask | 960 words | Normal | 网络初始化 + CH395F 轮询(消费 NET_RECONFIG 按代次重建监听) |
| ftpTask | 1024 words | Normal | FTP 服务(等待网络+存储就绪) |
| testTask | 2048 words | BelowNormal | 硬件测试入口 |
| uiTask | 4096 words | BelowNormal | LVGL UI 界面 |
| timeSyncTask | 640 words | Normal | 墙钟时间同步 |
| adcTask | 640 words | AboveNormal | TPAFE5160 采样(TIM3 1kHz 事件驱动 + 原子快照 + STM32 ADC DMA) |
| iec104Task | 640 words | Normal | |
| protectTask | 512 words | Normal | |
| adcTask | 640 words | AboveNormal | TPAFE5160 采样(TIM3 1kHz 事件驱动 + 原子快照 + STM32 ADC DMA,纯消费者) |
| iec104Task | 640 words | Normal | IEC 60870-5-104 上行(:2404 监听,遥信/遥测/定值区) |
| protectTask | 512 words | Normal | 保护判据 20ms 节拍(L3 元件 + 采样故障闭锁,B5) |
<!-- TASK_TABLE:END -->
> 上表与 `Src/freertos.c` 的 `osThreadAttr_t` 一致(2026-09-25 校准);改动栈大小前先读
> 上表与 `Src/freertos.c` 的 `osThreadAttr_t` 一致(2026-10-14 校准,9 任务);改动栈大小前先读
> `docs/内存管理/RAM使用分析与优化方案.md` 的定栈规则与 `docs/任务规划/基线与待确认.md` 的内存预算项。
### 任务启动顺序管理
@@ -111,15 +114,19 @@ STM32F4-Base/
│ └── gpio.h / dma.h / spi.h / i2c.h / usart.h
├── App/ # 应用层代码
│ ├── app/ # 应用入口与全局(app_main / app_cfg / sys_events)
│ ├── algo/ # 采集与算法层(L1 adc_input / L2 phasor+freq / L3 prot_set+prot_elm)
│ ├── cfg/ # 配置引擎(cfg_file 解析/持久化/迁移 + 存储后端)
│ ├── fs/ # 卷锁(vol_lock,syslog/cfg/lftpd 三条路径 try 语义)
│ ├── sync/ # 时间同步(time_sync 任务)
│ ├── log/ # 日志(sys_log 运行/自检记录、console_log 控制台单写者)
│ ├── task/ # FreeRTOS 任务实现
│ │ ├── default_task.c/h # 存储挂载 + 配置引擎属主 + syslog 写者
│ │ ├── net_task.c/h # 网络任务
│ │ ├── ui_task.c/h # UI 任务
│ │ ├── adc_task.c/h # ADC 任务
│ │ └── rs485_task.c/h # RS-485 任务
│ │ ├── adc_task.c/h # ADC 任务(L1/L2 纯消费者,TIM3 1kHz 唤醒)
│ │ ├── iec104_serv.c/h # IEC 60870-5-104 上行服务
│ │ ├── protect_task.c/h # 保护判据任务(L3 20ms 节拍)
│ │ └── rs485_task.c/h # RS-485 任务(已实现,未创建,B2 暂缓)
│ ├── util/ # 工具函数(crc / ringbuf / sys_clock)
│ └── protocol/ # 通信协议(预留)
├── Drivers/
@@ -131,6 +138,9 @@ STM32F4-Base/
│ │ ├── RS485/ # RS-485 通信驱动
│ │ ├── NET/ # BSD Socket API 网络抽象层
│ │ │ ├── net_socket.c/h # Socket API
│ │ │ ├── net_events.c/h # 芯片边沿事件处理 + 100ms 周期对账
│ │ │ ├── net_listener.c/h # 监听生命周期(请求登记 + 单一重建执行者)
│ │ │ ├── net_pending.c/h # 阻塞 recv/send 挂起请求表(SEND 二期已落地)
│ │ │ ├── net_select.c/h # select/poll 多路复用
│ │ │ └── lftpd/ # 轻量 FTP 服务器
│ │ ├── NETCFG/ # 网络配置(/config.ini [network] 段加载/保存)
@@ -159,7 +169,7 @@ STM32F4-Base/
│ │ └── net_latency_test.c/h # 链路时延探针
│ └── host/ # 主机端脚本(PC 侧;@test 入口已迁至 .dsh/skills/serial-boot-test/)
│ ├── ch395f_socket_test.py # Socket 通信测试
│ ├── ftp_test.py / ftp_up_dl_test.py / ftp_speed_test.py / ftp_capture.py / ftp_regression.py
│ ├── ftp_test.py / ftp_up_dl_test.py / ftp_regression.py / ftp_integrity_test.py / ftp_capture.py
│ ├── e02_probe.py # E-02 专项探针
│ ├── latency_peer.py # 链路时延 PC 对端
│ └── time_sync_server.py # 时间同步推送服务
@@ -265,9 +275,13 @@ UI 改动回归门禁(菜单像素回归 + 内容页黄金参考 + 池水位
### 网络层 (NET)
- BSD Socket API 抽象:`net_socket.h/c`
- 事件处理与周期对账:`net_events.c`(芯片边沿事件 + 100ms 对账,`net_poll()` 内分派)
- 监听生命周期单一所有者:`net_listener.c`(`net_listener_request` 只登记意图、`net_listener_tick` 唯一执行)
- 阻塞挂起请求表:`net_pending.c`(recv 一期 / SEND 二期已落地;调用方铁律 `sent < len`)
- select/poll I/O 多路复用:`net_select.h/c`
- 线程安全通过消息队列(`netMsgQueue`)实现
- 所有 CH395F 操作在 netTask 中串行处理
- 网口配置保存后经 `SYS_EVT_NET_RECONFIG` 按网络代次号重建监听(新 IP 免重启生效)
### 时间子系统
@@ -303,7 +317,8 @@ UI 改动回归门禁(菜单像素回归 + 内容页黄金参考 + 池水位
| `ch395f_socket_test.py` | Socket 通信测试 |
| `ftp_test.py` | FTP 服务器基础测试 |
| `ftp_up_dl_test.py` | FTP 上传/下载测试 |
| `ftp_speed_test.py` | FTP 传输速度测试 |
| `ftp_regression.py` | FTP 功能回归(会话流程全序列) |
| `ftp_integrity_test.py` | FTP 传输完整性压测(多轮 SHA-256 校验) |
| `ftp_capture.py` | FTP 流量抓取 |
| `time_sync_server.py` | 时间同步推送服务(PC → 板子) |
@@ -372,6 +387,9 @@ pre-commit run --all-files
| `Drivers/BSP/CH395F/ch395f.c` | 以太网控制器驱动 |
| `Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c` | NAND Flash 驱动 |
| `Drivers/BSP/NET/net_socket.c` | BSD Socket API |
| `Drivers/BSP/NET/net_events.c` | 芯片边沿事件处理 + 周期对账 |
| `Drivers/BSP/NET/net_listener.c` | 监听生命周期(单一重建所有者) |
| `App/algo/prot_elm.h` | L3 保护元件框架(判据消费入口) |
| `.dsh/skills/keil-build/scripts/keil_build.py` | 编译脚本(`@build`) |
| `.dsh/skills/serial-boot-test/scripts/run_boot_test.py` | 自动化测试脚本 |
@@ -396,6 +414,10 @@ pre-commit run --all-files
| `docs/子系统设计/系统墙钟时间维护说明.md` | RTC + 墙钟时间子系统 |
| `docs/子系统设计/网络配置说明.md` | 网口设置页配置(UI 可改的 IP/掩码/网关/MAC:持久化 + 立即生效 + 页面操作) |
| `docs/网络/BSD_Socket_API_使用指南.md` | BSD Socket API 使用指南(`net_socket` / `net_select`:线程安全 / 快速开始 / TCP / UDP / I/O 多路复用 / 事件回调 / API 参考 / 常见问题) |
| `docs/网络/Net层阻塞模型架构设计.md` | NET 阻塞模型(挂起请求表五路语义,recv 一期 / SEND 二期已落地) |
| `docs/网络/网络自愈架构设计.md` | 网络自愈架构(监听重建 / 沉降隔离 / 周期对账) |
| `docs/子系统设计/IEC104上行设计说明.md` | IEC 60870-5-104 上行(:2404 监听,B4) |
| `docs/子系统设计/ADC采样节拍设计说明.md` | TIM3 1kHz 采样节拍(两片转换器同源硬件驱动) |
| `docs/UI设计/UI_设计架构.md` | LVGL UI 系统架构(菜单 / 内容页 / 内存预算) |
| `docs/UI设计/菜单页面设计.md` | 菜单导航行为、数据流与内容页设计 |
| `docs/UI设计/UI_界面制作流程.md` | 参考图 → 设计规格 → LVGL 代码管线(P0~P4 门禁) |
+13 -8
View File
@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1400" height="802" viewBox="0 0 1400 802" font-family="Microsoft YaHei, Segoe UI, PingFang SC, sans-serif">
<rect x="0" y="0" width="1400" height="802" fill="#ffffff"/>
<svg xmlns="http://www.w3.org/2000/svg" width="1400" height="912" viewBox="0 0 1400 912" font-family="Microsoft YaHei, Segoe UI, PingFang SC, sans-serif">
<rect x="0" y="0" width="1400" height="912" fill="#ffffff"/>
<text x="40" y="42" font-size="20" font-weight="700" fill="#0f172a">就绪屏障(Readiness Barrier)· 启动依赖链</text>
<text x="40" y="68" font-size="13" fill="#64748b">CMSIS-RTOS2 Event Flags · 生产者置位声明「我好了」,消费者阻塞等待</text>
<rect x="40" y="96" width="16" height="16" rx="4" fill="#ffffff" stroke="#2563eb" stroke-width="2"/>
@@ -23,7 +23,7 @@
<rect x="428" y="337" width="30" height="30" rx="7" fill="#0d9488"/>
<text x="443" y="357" font-size="14" font-weight="700" fill="#ffffff" text-anchor="middle">0</text>
<text x="470" y="346" font-size="14" font-weight="700" fill="#0d9488">bit0 · NET_READY</text>
<text x="470" y="368" font-size="12" fill="#64748b">netTask 置位 · 4 个任务等待</text>
<text x="470" y="368" font-size="12" fill="#64748b">netTask 置位 · 5 个任务等待</text>
<rect x="414" y="420" width="392" height="84" rx="10" fill="#fffbeb" stroke="#d97706" stroke-opacity="0.6"/>
<rect x="428" y="447" width="30" height="30" rx="7" fill="#d97706"/>
<text x="443" y="467" font-size="14" font-weight="700" fill="#ffffff" text-anchor="middle">2</text>
@@ -65,8 +65,11 @@
<text x="926" y="564" font-size="15" font-weight="700" fill="#0f172a">timeSyncTask</text>
<text x="926" y="588" font-size="12" fill="#64748b">wait bit0 · Forever</text>
<rect x="910" y="640" width="450" height="84" rx="10" fill="#f5f3ff" stroke="#7c3aed" stroke-opacity="0.5"/>
<text x="926" y="674" font-size="15" font-weight="700" fill="#0f172a">testTask</text>
<text x="926" y="698" font-size="12" fill="#64748b">wait bit0 · NET 模式</text>
<text x="926" y="674" font-size="15" font-weight="700" fill="#0f172a">iec104Task</text>
<text x="926" y="698" font-size="12" fill="#64748b">wait bit0 · Forever</text>
<rect x="910" y="750" width="450" height="84" rx="10" fill="#f5f3ff" stroke="#7c3aed" stroke-opacity="0.5"/>
<text x="926" y="784" font-size="15" font-weight="700" fill="#0f172a">testTask</text>
<text x="926" y="808" font-size="12" fill="#64748b">wait bit0 · NET 模式</text>
<polyline points="820.0,242.0 910.0,242.0" fill="none" stroke="#16a34a" stroke-width="2.2" stroke-linejoin="round"/>
<path d="M 910.0 242.0 L 899.0 247.5 L 899.0 236.5 z" fill="#16a34a"/>
<text x="865" y="234.0" font-size="11.5" fill="#16a34a" text-anchor="middle">wait</text>
@@ -75,7 +78,7 @@
<text x="841" y="344.0" font-size="11.5" font-weight="700" fill="#0d9488">All</text>
<polyline points="820.0,352.0 862.0,352.0" fill="none" stroke="#0d9488" stroke-width="2.2" stroke-linejoin="round"/>
<path d="M 862.0 352.0 L 851.0 357.5 L 851.0 346.5 z" fill="#0d9488"/>
<polyline points="862.0,352.0 862.0,682.0" fill="none" stroke="#0d9488" stroke-width="2.2" stroke-linejoin="round"/>
<polyline points="862.0,352.0 862.0,792.0" fill="none" stroke="#0d9488" stroke-width="2.2" stroke-linejoin="round"/>
<polyline points="862.0,352.0 910.0,352.0" fill="none" stroke="#0d9488" stroke-width="2.2" stroke-linejoin="round"/>
<path d="M 910.0 352.0 L 899.0 357.5 L 899.0 346.5 z" fill="#0d9488"/>
<polyline points="862.0,462.0 910.0,462.0" fill="none" stroke="#0d9488" stroke-width="2.2" stroke-linejoin="round"/>
@@ -84,6 +87,8 @@
<path d="M 910.0 572.0 L 899.0 577.5 L 899.0 566.5 z" fill="#0d9488"/>
<polyline points="862.0,682.0 910.0,682.0" fill="none" stroke="#0d9488" stroke-width="2.2" stroke-linejoin="round"/>
<path d="M 910.0 682.0 L 899.0 687.5 L 899.0 676.5 z" fill="#0d9488"/>
<text transform="rotate(-90 850.0 517.0)" x="850.0" y="517.0" font-size="11.5" fill="#0d9488" text-anchor="middle">wait bit0</text>
<text x="40" y="784" font-size="12" fill="#94a3b8">生产者与消费者互不知晓,只经事件组解耦;新增子系统 = 新 bit + 各自 wait/set,不改已有任务。详见 docs/项目启动顺序管理.md</text>
<polyline points="862.0,792.0 910.0,792.0" fill="none" stroke="#0d9488" stroke-width="2.2" stroke-linejoin="round"/>
<path d="M 910.0 792.0 L 899.0 797.5 L 899.0 786.5 z" fill="#0d9488"/>
<text transform="rotate(-90 850.0 572.0)" x="850.0" y="572.0" font-size="11.5" fill="#0d9488" text-anchor="middle">wait bit0</text>
<text x="40" y="894" font-size="12" fill="#94a3b8">生产者与消费者互不知晓,只经事件组解耦;新增子系统 = 新 bit + 各自 wait/set,不改已有任务。详见 docs/架构设计/项目启动顺序管理.md</text>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

+19
View File
@@ -75,6 +75,8 @@ digraph refgraph_full {
"Drivers/BSP/NET/lftpd/lftpd.h" [fillcolor="#f3f4f6", color="#9ca3af"];
"Drivers/BSP/NET/lftpd/lftpd_auth.c" [fillcolor="#f3f4f6", color="#9ca3af"];
"Drivers/BSP/NET/net_config.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/NET/net_events.c" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/NET/net_events.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/NET/net_listener.c" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/NET/net_listener.h" [fillcolor="#dbeafe", color="#1d4ed8"];
"Drivers/BSP/NET/net_pending.c" [fillcolor="#dbeafe", color="#1d4ed8"];
@@ -495,8 +497,23 @@ digraph refgraph_full {
"Drivers/BSP/GD5F2GQ5UE/nand_ftl.c" -> "Lib/dhara/nand.h" [color="#94a3b8", penwidth=0.7];
"Drivers/BSP/GD5F2GQ5UE/nand_ftl.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Drivers/BSP/GD5F2GQ5UE/nand_ftl.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Drivers/BSP/NET/net_events.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "Drivers/BSP/NET/net_events.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "Drivers/BSP/NET/net_listener.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "Drivers/BSP/NET/net_pending.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "Drivers/BSP/NET/net_socket.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h" [color="#94a3b8", penwidth=0.7];
"Drivers/BSP/NET/net_events.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7];
"Drivers/BSP/NET/net_events.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [color="#94a3b8", penwidth=0.7];
"Drivers/BSP/NET/net_events.c" -> "test/board/net_latency_test.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "test/board/test_config.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_events.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Drivers/BSP/NET/net_events.h" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_listener.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_listener.c" -> "Drivers/BSP/NET/net_listener.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_listener.c" -> "Drivers/BSP/NET/net_pending.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_listener.c" -> "Drivers/BSP/NET/net_socket.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_listener.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_listener.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0];
@@ -517,6 +534,7 @@ digraph refgraph_full {
"Drivers/BSP/NET/net_pending.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7];
"Drivers/BSP/NET/net_pending.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [color="#94a3b8", penwidth=0.7];
"Drivers/BSP/NET/net_pending.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed];
"Drivers/BSP/NET/net_pending.h" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_pending.h" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_pending.h" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7];
"Drivers/BSP/NET/net_pending.h" -> "Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [color="#94a3b8", penwidth=0.7];
@@ -532,6 +550,7 @@ digraph refgraph_full {
"Drivers/BSP/NET/net_select.h" -> "Drivers/BSP/NET/net_config.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_select.h" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/NET/net_events.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/NET/net_listener.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/NET/net_pending.h" [color="#2563eb", penwidth=1.0];
"Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/NET/net_socket.h" [color="#2563eb", penwidth=1.0];
+125 -5
View File
@@ -333,6 +333,14 @@
"path": "Drivers/BSP/NET/net_config.h",
"class": "fp"
},
{
"path": "Drivers/BSP/NET/net_events.c",
"class": "fp"
},
{
"path": "Drivers/BSP/NET/net_events.h",
"class": "fp"
},
{
"path": "Drivers/BSP/NET/net_listener.c",
"class": "fp"
@@ -7549,6 +7557,96 @@
"kind": "fp-ext",
"include": "stdint.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "外部/系统头文件",
"kind": "fp-ext",
"include": "string.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "外部/系统头文件",
"kind": "fp-ext",
"include": "stdbool.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h",
"kind": "fp-tp",
"include": "FreeRTOS.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Middlewares/Third_Party/FreeRTOS/Source/include/task.h",
"kind": "fp-tp",
"include": "task.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h",
"kind": "fp-tp",
"include": "cmsis_os.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Drivers/BSP/NET/net_socket.h",
"kind": "fp-fp",
"include": "net_socket.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Drivers/BSP/NET/net_events.h",
"kind": "fp-fp",
"include": "net_events.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Drivers/BSP/NET/net_listener.h",
"kind": "fp-fp",
"include": "net_listener.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Drivers/BSP/NET/net_pending.h",
"kind": "fp-fp",
"include": "net_pending.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Drivers/BSP/CH395F/ch395f.h",
"kind": "fp-fp",
"include": "ch395f.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "test/board/test_config.h",
"kind": "fp-fp",
"include": "test_config.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "test/board/net_latency_test.h",
"kind": "fp-fp",
"include": "net_latency_test.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Inc/main.h",
"kind": "fp-fp",
"include": "main.h"
},
{
"from": "Drivers/BSP/NET/net_events.c",
"to": "Drivers/BSP/dbg_log.h",
"kind": "fp-fp",
"include": "dbg_log.h"
},
{
"from": "Drivers/BSP/NET/net_events.h",
"to": "Drivers/BSP/NET/net_types.h",
"kind": "fp-fp",
"include": "net_types.h"
},
{
"from": "Drivers/BSP/NET/net_listener.c",
"to": "外部/系统头文件",
@@ -7591,6 +7689,12 @@
"kind": "fp-fp",
"include": "net_listener.h"
},
{
"from": "Drivers/BSP/NET/net_listener.c",
"to": "Drivers/BSP/NET/net_pending.h",
"kind": "fp-fp",
"include": "net_pending.h"
},
{
"from": "Drivers/BSP/NET/net_listener.c",
"to": "Drivers/BSP/CH395F/ch395f.h",
@@ -7711,6 +7815,12 @@
"kind": "fp-fp",
"include": "net_types.h"
},
{
"from": "Drivers/BSP/NET/net_pending.h",
"to": "Drivers/BSP/CH395F/ch395f.h",
"kind": "fp-fp",
"include": "ch395f.h"
},
{
"from": "Drivers/BSP/NET/net_select.c",
"to": "外部/系统头文件",
@@ -7825,6 +7935,12 @@
"kind": "fp-fp",
"include": "net_listener.h"
},
{
"from": "Drivers/BSP/NET/net_socket.c",
"to": "Drivers/BSP/NET/net_events.h",
"kind": "fp-fp",
"include": "net_events.h"
},
{
"from": "Drivers/BSP/NET/net_socket.c",
"to": "Drivers/BSP/NET/net_pending.h",
@@ -41857,6 +41973,10 @@
"Drivers/BSP/NET/lftpd/private/lftpd_io.h": [
"stdint.h"
],
"Drivers/BSP/NET/net_events.c": [
"stdbool.h",
"string.h"
],
"Drivers/BSP/NET/net_listener.c": [
"stdbool.h",
"string.h"
@@ -43605,11 +43725,11 @@
]
},
"stats": {
"files_indexed": 1493,
"includes_parsed": 5954,
"resolved": 4805,
"unresolved": 1149,
"nodes_fp": 213,
"files_indexed": 1495,
"includes_parsed": 5972,
"resolved": 4821,
"unresolved": 1151,
"nodes_fp": 215,
"nodes_tp": 1266,
"ext_names": 351
},
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 512 KiB

After

Width:  |  Height:  |  Size: 522 KiB

+6 -6
View File
@@ -82,12 +82,12 @@ digraph refgraph_module {
"BSP/GD5F2GQ5UE" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×1"];
"BSP/GD5F2GQ5UE" -> "dhara" [color="#2563eb", penwidth=1.2, label="×2"];
"BSP/GD5F2GQ5UE" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"];
"BSP/NET" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×3"];
"BSP/NET" -> "BSP/CH395F" [color="#2563eb", penwidth=1.2, label="×4"];
"BSP/NET" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×15"];
"BSP/NET" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×4"];
"BSP/NET" -> "test" [color="#2563eb", penwidth=1.2, label="×4"];
"BSP/NET" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×6"];
"BSP/NET" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×4"];
"BSP/NET" -> "BSP/CH395F" [color="#2563eb", penwidth=1.2, label="×6"];
"BSP/NET" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×18"];
"BSP/NET" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×5"];
"BSP/NET" -> "test" [color="#2563eb", penwidth=1.2, label="×6"];
"BSP/NET" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×7"];
"BSP/NETCFG" -> "App" [color="#2563eb", penwidth=1.2, label="×2"];
"BSP/NETCFG" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×1"];
"BSP/NETCFG" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"];
+6 -6
View File
@@ -513,42 +513,42 @@
<title>BSP/NET&#45;&gt;BSP(公共)</title>
<path fill="none" stroke="#2563eb" stroke-width="1.2" d="M1366.53,-1486.55C1371.67,-1482.5 1376.67,-1477.93 1380.75,-1473 1392.66,-1458.6 1385.78,-1448.45 1398.75,-1435 1417.52,-1415.54 1429.05,-1420 1452.75,-1407 1500.15,-1380.99 1523.25,-1387.42 1558,-1346 1607.98,-1286.42 1639.96,-1044.77 1649.85,-959.76"/>
<polygon fill="#2563eb" stroke="#2563eb" stroke-width="1.2" points="1653.31,-960.31 1650.97,-949.97 1646.36,-959.51 1653.31,-960.31"/>
<text xml:space="preserve" text-anchor="middle" x="1514.38" y="-1402.27" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×3</text>
<text xml:space="preserve" text-anchor="middle" x="1514.38" y="-1402.27" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×4</text>
</g>
<!-- BSP/NET&#45;&gt;BSP/CH395F -->
<g id="edge56" class="edge">
<title>BSP/NET&#45;&gt;BSP/CH395F</title>
<path fill="none" stroke="#2563eb" stroke-width="1.2" d="M1368.34,-1486.5C1373.07,-1482.56 1377.45,-1478.04 1380.75,-1473 1400.78,-1442.42 1375.3,-1420.79 1398.75,-1392.75 1415.45,-1372.77 1430.53,-1383.59 1452.75,-1370 1464.34,-1362.91 1476.01,-1353.7 1485.97,-1345.06"/>
<polygon fill="#2563eb" stroke="#2563eb" stroke-width="1.2" points="1488.11,-1347.85 1493.24,-1338.57 1483.45,-1342.62 1488.11,-1347.85"/>
<text xml:space="preserve" text-anchor="middle" x="1425.75" y="-1397.5" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×4</text>
<text xml:space="preserve" text-anchor="middle" x="1425.75" y="-1397.5" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×6</text>
</g>
<!-- BSP/NET&#45;&gt;FreeRTOS -->
<g id="edge57" class="edge">
<title>BSP/NET&#45;&gt;FreeRTOS</title>
<path fill="none" stroke="#2563eb" stroke-width="1.2" d="M1349.64,-1523.41C1371.83,-1556.12 1418.69,-1626.84 1452.75,-1689.75 1471.36,-1724.13 1489.77,-1765.26 1501.33,-1792.2"/>
<polygon fill="#2563eb" stroke="#2563eb" stroke-width="1.2" points="1498,-1793.31 1505.13,-1801.14 1504.44,-1790.57 1498,-1793.31"/>
<text xml:space="preserve" text-anchor="middle" x="1425.75" y="-1694.5" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×15</text>
<text xml:space="preserve" text-anchor="middle" x="1425.75" y="-1694.5" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×18</text>
</g>
<!-- BSP/NET&#45;&gt;Src/Inc (CubeMX) -->
<g id="edge58" class="edge">
<title>BSP/NET&#45;&gt;Src/Inc (CubeMX)</title>
<path fill="none" stroke="#2563eb" stroke-width="1.2" d="M1329.66,-1523.2C1315.28,-1572.05 1276.62,-1702.66 1273.25,-1706 1264.72,-1714.47 870.58,-1827.86 858.75,-1830 813.65,-1838.17 762.2,-1841.67 722,-1843.13"/>
<polygon fill="#2563eb" stroke="#2563eb" stroke-width="1.2" points="722.14,-1839.63 712.26,-1843.45 722.37,-1846.62 722.14,-1839.63"/>
<text xml:space="preserve" text-anchor="middle" x="982" y="-1802.03" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×4</text>
<text xml:space="preserve" text-anchor="middle" x="982" y="-1802.03" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×5</text>
</g>
<!-- BSP/NET&#45;&gt;test -->
<g id="edge59" class="edge">
<title>BSP/NET&#45;&gt;test</title>
<path fill="none" stroke="#2563eb" stroke-width="1.2" d="M1312.76,-1523.36C1301.62,-1531.38 1287.5,-1539.88 1273.25,-1544 1205.85,-1563.5 1123.02,-1554.62 1075.71,-1546.64"/>
<polygon fill="#2563eb" stroke="#2563eb" stroke-width="1.2" points="1076.44,-1543.21 1065.99,-1544.91 1075.22,-1550.1 1076.44,-1543.21"/>
<text xml:space="preserve" text-anchor="middle" x="1174.5" y="-1560.5" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×4</text>
<text xml:space="preserve" text-anchor="middle" x="1174.5" y="-1560.5" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×6</text>
</g>
<!-- BSP/NET&#45;&gt;外部/系统头文件 -->
<g id="edge60" class="edge">
<title>BSP/NET&#45;&gt;外部/系统头文件</title>
<path fill="none" stroke="#94a3b8" stroke-width="0.7" d="M1369.51,-1508.86C1459.7,-1519.56 1714.78,-1549.82 1843.01,-1565.03"/>
<polygon fill="#94a3b8" stroke="#94a3b8" stroke-width="0.7" points="1842.5,-1568.5 1852.84,-1566.2 1843.32,-1561.55 1842.5,-1568.5"/>
<text xml:space="preserve" text-anchor="middle" x="1654.12" y="-1550.91" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×6</text>
<text xml:space="preserve" text-anchor="middle" x="1654.12" y="-1550.91" font-family="Microsoft YaHei" font-size="10.00" fill="#334155">×7</text>
</g>
<!-- BSP/NETCFG&#45;&gt;App -->
<g id="edge61" class="edge">

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

@@ -17,15 +17,24 @@
**初始化顺序:**
```
HAL_Init → SystemClock_Config → MX_GPIO_Init → MX_USART1_UART_Init
→ MX_SPI2_Init → MX_SPI1_Init
→ gd5f2gq5ue_init() // NAND 底层驱动 (含 BBT 扫描 + ECC 使能)
→ app_main_init() // 应用层初始化
→ osKernelStart() // FreeRTOS 启动
├─ defaultTask → f_mount() → 存储测试 + 业务
├─ netTask → 网络协议栈轮询
├─ adcTask → ADC 采集
└─ rs485Task → RS485 通信
HAL_Init → SystemClock_Config → MX_GPIO/DMA/USART1/SPI2/SPI1/I2C1/UART4/IWDG/ADC1/TIM3_Init
→ app_main_init() // 应用层初始化(全程内核前)
├─ syslog_mcu_init() // 日志先进 RAM 暂存(内核前安全空操作)
├─ sd2506_init() → sys_clock_init() // 时间子系统优先(墙钟基准)
├─ rs485_init()
├─ gd5f2gq5ue_init() // NAND 底层驱动(含 BBT 全片扫描 + ECC 使能)
├─ tpafe5160_init() → adc_input_init() // TPAFE + L1 采集层(语义映射 + ADC1 DMA)
├─ phasor_init() / freq_init() / prot_set_init() + prot_elm_init() // L2/L3 内核前就绪
├─ SD2506 诊断(ID/时间/温度/电池)
└─ HAL_TIM_Base_Start_IT(&htim3) // 启动 TIM3 1kHz 采样节拍
→ osKernelInitialize() → MX_FREERTOS_Init() → osKernelStart() // FreeRTOS 启动
├─ defaultTask → f_mount() → 卷健康探针/自愈 + 配置引擎 + syslog 落盘
├─ netTask → 网络协议栈轮询(等 STORAGE_READY)
├─ ftpTask → lftpd_start("/", 21)(等 NET_READY + STORAGE_READY)
├─ adcTask → TIM3 1kHz 唤醒,ADC 采集(纯消费者)
├─ iec104Task → IEC 60870-5-104 上行(:2404)
├─ protectTask → 保护判据 20ms 节拍
└─ rs485Task → 未创建(B2 暂缓,见 docs/任务规划/暂缓-RS485.md)
```
---
+1 -1
View File
@@ -35,7 +35,7 @@
## 二、既有工具(`tools/arch_diagram/`)
三个生成器共享同一套约定(§3.2),均为**纯标准库**拼 SVG:
以下生成器共享同一套约定(§3.2),均为**纯标准库**拼 SVG:
| 脚本 | 产物(入库) | 顶部数据区(改这里 → 重跑) |
|---|---|---|
+5 -5
View File
@@ -94,9 +94,9 @@
- 换机:`winget install Graphviz.Graphviz`(渲染依赖;缺失时工具自动跳过渲染,
仍产出 `.dot`)。
## 7. 当前数据(2026-09-16 首版)
## 7. 当前数据(2026-10-14 刷新)
索引 1396 个 `.c/.h`;解析 include 5588 条(解析成功 4539,外部/系统 1049,
353 种);第一方文件 126 个;去重边 4823 条。
被引用最多的第一方文件:`Drivers/BSP/dbg_log.h`(31)、`Inc/main.h`(20)、
`Drivers/BSP/NET/net_socket.h`(12)……(完整 Top10 见运行报告)。
索引 1495 个 `.c/.h`;解析 include 5972 条(解析成功 4821,外部/系统 1151,351 种);
第一方文件 215 个;节点 = 第一方 215 + 第三方 1266 + 外部聚合 1;去重边 5176 条。
被引用最多的第一方文件:`Drivers/BSP/dbg_log.h`(48)、`Inc/main.h`(33)、
`Drivers/BSP/NET/net_socket.h`(18)……(完整 Top10 见运行报告)。
+21 -10
View File
@@ -9,11 +9,16 @@
### 1.1 现有任务
| 任务 | 职责 | 当前启动依赖 |
|------|------|--------------|
| `defaultTask` | FTL + FatFS 存储挂载/测试(一次性) | 无(最先跑) |
| `netTask` | `net_init()` → `net_poll()` 周期轮询 | 无 |
| `defaultTask` | FTL + FatFs 存储 bring-up + 配置引擎属主 + syslog 唯一写者(一次性后转循环) | 无(最先跑) |
| `netTask` | `net_stack_bring_up()` → `net_poll()` 周期轮询 + `net_process_messages()` | 等 `SYS_EVT_STORAGE_READY`(配置已由 defaultTask 屏障前加载,本任务只读 RAM 副本) |
| `ftpTask` | `lftpd_start("/", 21, &ftp)` | 等 `SYS_EVT_NET_READY + SYS_EVT_STORAGE_READY`(`osFlagsWaitAll \| osFlagsNoClear`) |
| `start_test_task`(testTask) | 统一测试入口,按 `TEST_SUITE_*` 分发 | NET 模式下 `osEventFlagsWait(SYS_EVT_NET_READY, osFlagsWaitAny \| osFlagsNoClear, osWaitForever)` 阻塞等待 |
| `timeSyncTask` | 墙钟时间同步 | `osEventFlagsWait(SYS_EVT_NET_READY, … \| osFlagsNoClear)` 后开始同步 |
| `uiTask` | LVGL UI(`ui_port_init` → `ui_menu_init` → `ui_net_sink` :7003 → 10ms 刷新) | `osEventFlagsWait(SYS_EVT_NET_READY, osFlagsWaitAny \| osFlagsNoClear, osWaitForever)` |
| `iec104Task` | IEC 60870-5-104 上行(:2404 监听 + link 状态机,B4) | `osEventFlagsWait(SYS_EVT_NET_READY, … \| osFlagsNoClear)` |
| `adcTask` | TIM3 1kHz 采样节拍**纯消费者**(`adc_input_poll()`,L1/L2 取数,不做保护运算) | **无事件位依赖**:TIM3 ISR 内 `adc_tick_irq_notify()` 直接唤醒(TIM3 比调度器早 ≈100ms 启动,ISR 侧只能走该通知函数) |
| `protectTask` | 保护判据 20ms 节拍(`prot_elm_run()`,L3,B5) | 无(节拍自持,不依赖网络) |
| `rs485_task` | RS-485 通信(任务体已实现) | **未在 `freertos.c` 创建**(B2 暂缓,见 `docs/任务规划/暂缓-RS485.md`) |
### 1.2 改造前(已废弃)的依赖管理手段
> 以下为引入 Event Flags 之前的历史做法,仅作背景记录,当前代码已不再使用。
@@ -70,7 +75,7 @@ extern osEventFlagsId_t sys_evtHandle;
### 3.2 生产者 / 消费者矩阵
| 事件 bit | 生产者(置位处) | 消费者(等待处) |
|----------|------------------|------------------|
| `SYS_EVT_NET_READY` | `netTask`(`net_task_func` 中 `net_stack_bring_up()` 成功后置位) | `ftpTask`、`start_test_task`(NET 模式)、`timeSyncTask` |
| `SYS_EVT_NET_READY` | `netTask`(`net_task_func` 中 `net_stack_bring_up()` 成功后置位) | `ftpTask`、`start_test_task`(NET 模式)、`timeSyncTask`、`uiTask`、`iec104Task` |
| `SYS_EVT_STORAGE_READY` | `defaultTask`(卷挂载 + 网络配置加载完成后) | 依赖文件系统的任务/测试套件(netTask 组网、STORAGE/GD5F 等) |
| `SYS_EVT_FTP_READY` | `ftpTask`(`lftpd_start` 成功后) | 无(示例,预留给需要 FTP 就绪的后续功能) |
| `SYS_EVT_TIMESYNC_READY` | (预留,暂无生产者置位) | 可选:对时精度敏感的业务 |
@@ -223,13 +228,19 @@ if (sys_evtHandle != NULL) {
| # | 日志行 | 对应步骤 | 卡此步的含义 |
|---|---|---|---|
| 1 | `boot: syslog init OK` | `syslog_mcu_init()` | (纯 RAM,不会卡) |
| 2 | `reset cause: ... (CSR=...)` | 复位原因翻译 | (纯计算,不会卡) |
| 3 | `SD2506 init: OK/FAILED (ret=N)` | `sd2506_init()` | **I2C1 不通**(PB6/PB7、上拉、供电)——失败时其内部还会先打 `sd2506_init: ... FAIL` 指明具体寄存器与错误码 |
| 4 | `[CLK] sys_clock_init: ...` | `sys_clock_init()` | RTC 读/写异常(降级时会打 `RTC abnormal, fallback to default time`) |
| 5 | `RS485 init: OK (UART4, DE=PA15)` | `rs485_init()` | UART4 / DE 引脚配置 |
| 6 | `NAND init: OK/...` | `gd5f2gq5ue_init()` | **BBT 全片扫描**——启动段最耗时的一步,卡住多为此处(SPI2 与片选) |
| 7 | `ADC init: OK/TIMEOUT` | `tpafe5160_init()` | TPAFE5160 SPI 通信 |
| 8 | `App init OK` | 全部完成 | 此后问题属任务/调度层,不再是启动段 |
| 2 | `fw build: <日期 时间> <变体>` | 固件身份戳(构建变体串) | (纯打印,不会卡) |
| 3 | `reset cause: ... (CSR=...)` | 复位原因翻译 | (纯计算,不会卡) |
| 4 | `SD2506 init: OK/FAILED (ret=N)` | `sd2506_init()` | **I2C1 不通**(PB6/PB7、上拉、供电)——失败时其内部还会先打 `sd2506_init: ... FAIL` 指明具体寄存器与错误码 |
| 5 | `[CLK] sys_clock_init: ...` | `sys_clock_init()` | RTC 读/写异常(降级时会打 `RTC abnormal, fallback to default time`) |
| 6 | `RS485 init: OK (UART4, DE=PA15)` | `rs485_init()` | UART4 / DE 引脚配置 |
| 7 | `NAND init: OK/...` | `gd5f2gq5ue_init()` | **BBT 全片扫描**——启动段最耗时的一步,卡住多为此处(SPI2 与片选) |
| 8 | `ADC init: OK/TIMEOUT` | `tpafe5160_init()` | TPAFE5160 SPI 通信 |
| 9 | `ADC input layer init: OK` | `adc_input_init()`(L1 语义映射 + ADC1 DMA 武装) | 映射自检 FAILED / DMA arm FAILED(两条 `DBG_ERROR` 即此步;失败时无 OK 行) |
| 10 | `phasor layer init: OK (inst=N)` | `phasor_init()` | 纯 RAM(不会卡;实例数不符 = 相量层配置问题) |
| 11 | `freq layer init: OK` | `freq_init()` | 纯 RAM(不会卡) |
| 12 | `protection init: OK (set=N elm=N)` | `prot_set_init()` + `prot_elm_init()` | 纯 RAM(不会卡) |
| 13 | `SD2506 ID/time/temp/battery` 共 5 行 | SD2506 诊断 | I2C1(同第 4 步);缺行 = 诊断段卡死 |
| 14 | `App init OK` | 全部完成(其后启动 TIM3 1kHz 采样节拍 `HAL_TIM_Base_Start_IT(&htim3)`,见 AGENTS.md 铁律) | 此后问题属任务/调度层,不再是启动段 |
- **若一行日志都没有**:问题在 `fault_handler_enable()` 之前(`HAL_Init` / 时钟树 / `system_stm32f4xx.c`),或 USART1 本身未初始化(`MX_USART1_UART_Init` 在 `main.c` 的 CubeMX 初始化段)。
- **若卡在某步且无该步结果日志**:看该步**内部**是否还有更细的日志(如 `sd2506_init` 的 `ID read FAIL` / `charge reg read FAIL` 区分了 I2C 失败与寄存器校验失败)。
+51 -28
View File
@@ -1,6 +1,6 @@
# STM32F4-Base 项目架构总览
> 版本:v1.0 日期:2026-09-10
> 版本:v1.1 日期:2026-10-14
> 平台:STM32F407ZGTx @168MHz(HSE 8MHz → PLL M=4/N=168/P=2)+ FreeRTOS V10.3.1(CMSIS-RTOS2)
> 用途:一页看清项目的分层、任务、数据流与目录组织。细节以各模块专项文档为准(见 §9)。
@@ -23,26 +23,27 @@
|---|---|---|---|
| ① 业务层 | `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` |
| ③ 基础服务层 | `App/`、`Drivers/BSP/NET/lftpd/` | 应用侧服务与编排 | `app_main` `sys_events` `app_cfg` `task/*` `algo/*`(L1~L3) `lftpd` `time_sync` |
| ④ 中间件层 | `Drivers/BSP/NET/`、`Lib/`、`App/util/` | 通用库 / 协议栈 | `net_socket` `net_select` `net_events` `net_pending` `net_listener` `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 / UART5 / USART1 / DMA / GPIO / TIM7 |
| ⑥ 硬件 | — | STM32F407ZGTx @168MHz | SPI1 / SPI2 / I2C1 / UART5 / USART1 / DMA / GPIO / TIM7 |
| ⑦ 硬件 | — | STM32F407ZGTx @168MHz | SPI1 / SPI2 / I2C1 / UART4 / USART1 / ADC1 / TIM3 / DMA / GPIO |
### 1.2 关键跨层依赖(对应上图未画出的连线)
| 依赖 | 说明 |
|---|---|
| `ui_page_net_cfg` → `net_cfg` | 网口设置页显示/编辑 RAM 副本(不直接触 CH395F SPI) |
| `netTask` → `net_cfg` → `net_socket` | 上电只读 RAM 副本(defaultTask 已在屏障前 `net_cfg_load`)→ `net_init(ip,mask,gw,mac)` |
| `netTask` → `net_cfg` → `net_socket` | 上电只读 RAM 副本(defaultTask 已在屏障前 `net_cfg_load`)→ `net_init(ip,mask,gw,mac)`;配置保存后经 `SYS_EVT_NET_RECONFIG` 按**网络代次号**重建(新 IP 免重启生效) |
| `net_socket` → `net_events` / `net_listener` / `net_pending` | socket 宿主调三个内部模块:芯片边沿事件 + 100ms 周期对账 / 监听生命周期(重建请求登记 + 唯一执行)/ 阻塞 recv·send 挂起请求表 |
| `App/algo/*`(L1→L2→L3) → `adc_task` / `protect_task` | 采集与算法层为纯计算:adcTask 消费 L1/L2(TIM3 1kHz 节拍)、protectTask 消费 L3(20ms 判据节拍) |
| `lftpd` / `net_cfg` / 测试 → `FatFs` → `nand_ftl` → `gd5f2gq5ue` | 文件与配置落 NAND |
| `ui_net_sink` / `time_sync` → `net_socket` | 远程显示 :7003 / 对时 :8888 共用同一 TCP 栈 |
| `ui_menu` → `ui_content_page` → `ui_page_*` | 框架 + 页面插件(描述符解耦) |
| `time_sync` / `sys_clock` → `sd2506` | 墙钟基准与写回 RTC |
| `ui_port` / `ui_page_*` → `LVGL` | UI 全部绘制走 LVGL |
> `*` `adc_task.c` / `rs485_task.c` 任务体已实现,但**当前未在 `freertos.c` 创建**(预留/待接入)。
> `*` `rs485_task.c` 任务体已实现,但**当前未在 `freertos.c` 创建**(B2 暂缓,见 `docs/任务规划/暂缓-RS485.md`);`adc_task.c` 已于 2026-10-10 接入创建(`adcTask`)。
---
@@ -52,16 +53,19 @@
| 任务 | 栈 (字节) | 优先级 | 职责 | 入口 |
|---|---|---|---|---|
| `defaultTask` | 4096 | Normal | FatFS 挂载(无卷 `f_mkfs`)→ 卷健康探针/自愈 → `net_cfg_load`(配置引擎属主)→ 置 `STORAGE_READY`(= 存储+配置就绪)→ 日志落盘(唯一写者,`syslog_drain`)+ 配置保存执行/2s poll + LED 闪烁 + **栈水位观测**(`stack_probe_poll`:首次 5s 后报告,此后仅在出现更深峰值时打印) | `StartDefaultTask` |
| `netTask` | 4096 | Normal | 等存储(配置已由 defaultTask 就绪,本任务只读 RAM 副本)→ `net_stack_bring_up()`(不触碰配置文件引擎)→ 置 `NET_READY` → `net_poll` 轮询(CH395F 硬件层测试模式下入口自挂起) | `StartNetTask` |
| `ftpTask` | 4096 | Normal | 等网络**且**存储(`WaitAll`)→ `lftpd_start("/", 21)` → 单客户端会话循环(断开后重开监听) | `StartFtpTask` |
| `defaultTask` | 5120 | Normal | FatFS 挂载(无卷 `f_mkfs`)→ 卷健康探针/自愈 → `net_cfg_load`(配置引擎属主)→ 置 `STORAGE_READY`(= 存储+配置就绪)→ 日志落盘(唯一写者,`syslog_drain`)+ 配置保存执行/2s poll + LED 闪烁 + **栈水位观测**(`stack_probe_poll`:首次 5s 后报告,此后仅在出现更深峰值时打印) | `StartDefaultTask` |
| `netTask` | 3840 | Normal | 等存储(配置已由 defaultTask 就绪,本任务只读 RAM 副本)→ `net_stack_bring_up()`(不触碰配置文件引擎)→ 置 `NET_READY` → 循环 `net_poll` + `net_process_messages`;消费 `SYS_EVT_NET_RECONFIG` → 按网络代次号重建监听(CH395F 硬件层测试模式下入口自挂起) | `StartNetTask` |
| `ftpTask` | 4096 | Normal | 等网络**且**存储(`WaitAll`)→ `lftpd_start("/", 21)` → 单客户端会话循环(断开后经 `net_listener` 重建监听) | `StartFtpTask` |
| `testTask` | 8192 | BelowNormal | 测试套件入口(`test/board/test_config.h` 选择)。**产品构建不创建**:CubeMX 生成区无条件建后,`MX_FREERTOS_Init()` 在未选套件时(`!TEST_SUITE_SELECTED`)立即 `vTaskDelete` 回收其 8KB CCM 栈(P2-13,2026-10-04) | `start_test_task` |
| `uiTask` | 16384 | BelowNormal | 等网络 → `ui_port_init`/`ui_menu_init`/`ui_standby_init`(空闲 60s 切待机屏)/`ui_net_sink` → 10ms 刷新 | `ui_task_func` |
| `timeSyncTask` | 2048 | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC | `time_sync_task` |
| `timeSyncTask` | 2560 | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC | `time_sync_task` |
| `adcTask` | 2560 | AboveNormal | 纯消费者:`osThreadFlagsWait` 等 TIM3 1kHz 唤醒(ISR 内 `adc_tick_irq_notify` 置位)→ `adc_input_poll()`(TPAFE 原子快照 + STM32 ADC1 DMA 双缓冲)→ L1/L2 消费,不取数不做保护运算 | `adc_task_func` |
| `iec104Task` | 2560 | Normal | 等网络 → IEC 60870-5-104 上行(:2404 监听 + link 状态机,遥信/遥测/定值区,B4) | `iec104_serv_task` |
| `protectTask` | 2048 | Normal | 保护判据 20ms 节拍:`prot_elm_run()` + L5-4 采样故障闭锁 + L5-1 定值校验和巡检(B5);不依赖网络,纳入 IWDG `required_mask` | `protect_task` |
> `idle`(128 words)/ `timer`(256 words)由 FreeRTOS 内核创建。所有任务栈从 48KB heap_4 堆分配。
> **栈实测与预算**(2026-09-21,工具 `scripts/stack_report.py` = Keil 静态调用图 + 串口 `[STACK]` 水位;详见 `docs/内存管理/RAM使用分析与优化方案.md` §0.6):
> defaultTask 静态最坏 2776B/4096B(余量 32%)、ftpTask 实测 **1184B/4096B(余量 71%)**(lftpd 大局部缓冲静态化前为 3480B / 15%,见内存方案 §1.4)、uiTask 实测 3824B/16384B(缩栈空间大,内存方案 §1.3 目标 6KB)、netTask 588B、timeSyncTask 420B、testTask 348B(2026-09-21 实测;P2-13 后产品构建已不再创建该任务,仅测试构建保留)。
> `idle`(128 words)/ `timer`(256 words)由 FreeRTOS 内核创建。所有任务栈从 FreeRTOS `heap_4` 堆分配(**已迁 CCM**,2026-10-12 扩容至 56 KB,见 `docs/内存管理/RAM使用分析与优化方案.md` §1.2/§2.3)。
> **栈实测与预算**(2026-10-10~14,工具 `scripts/stack_report.py` = Keil 静态调用图 + 串口 `[STACK]` 水位;详见 `docs/内存管理/RAM使用分析与优化方案.md` §0.6/§2.3):
> defaultTask 实测峰值 **2152B/5120B(余 41%)**、静态最坏链 3016B;netTask 实测峰 **1116~1164B/3840B**(开机~FTP 传输期,2026-10-14)、静态链 1912B;ftpTask 实测 740B/4096B、静态 1216B;timeSyncTask 实测 616B/2560B、静态 1264B;uiTask 实测 4016B/16384B;adcTask 实测 952B/2560B、静态 1320B;iec104Task 静态 1456B(未上板);protectTask 静态 872B(未上板);testTask 静态 496B(仅测试构建)。
> ⚠ 改栈或加大栈内局部变量前后**必须**重跑该脚本——静态分析低估含递归/间接调用的链(优化前 ftpTask:静态 2528B vs 实测 3480B)。
### 2.2 就绪屏障(Event Flags,取代魔法延时)
@@ -106,16 +110,20 @@ sequenceDiagram
participant F as ftpTask
participant U as uiTask
participant T as timeSyncTask
participant I as iec104Task
participant P as protectTask
participant C as adcTask
M->>M: HAL_Init + CubeMX 外设初始化<br/>(SPI1/SPI2/I2C1/UART5/USART1/DMA/GPIO/TIM7)
M->>M: HAL_Init + CubeMX 外设初始化<br/>(SPI1/SPI2/I2C1/UART4/USART1/ADC1/TIM3/DMA/GPIO/IWDG)
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->>A: rs485_init() → gd5f2gq5ue_init()(BBT 扫描)→ tpafe5160_init()
A->>A: adc_input_init()(L1 语义映射 + ADC1 DMA)→ phasor_init() → freq_init()<br/>→ prot_set_init() + prot_elm_init()(L3 内核前封存)
A->>A: SD2506 诊断(ID/时间/温度/电池)→ HAL_TIM_Base_Start_IT(&htim3)(1kHz 节拍)
A-->>M: "App init OK"
M->>K: osKernelStart()
Note over K: MX_FREERTOS_Init 已创建 6 任务 + 事件组 + 队列
Note over K: MX_FREERTOS_Init 已创建 9 任务 + 事件组 + 队列<br/>(产品构建 testTask 创建即回收,实跑 8 任务)
K->>D: 调度
D->>D: f_mount(无卷则 f_mkfs FAT32)→ 卷健康探针/自愈 → net_cfg_load()(配置引擎属主)
@@ -125,12 +133,15 @@ sequenceDiagram
N->>N: wait STORAGE_READY(Any|NoClear,≤10s,超时回退工厂默认)
N->>N: 读 RAM 配置副本 → net_init(ip,mask,gw,mac)<br/>→ PHY 强制 100M 全双工 → 等链路 ≤3s → MAC 回写影子
N-->>F: set SYS_EVT_NET_READY
N->>N: 循环 net_poll() + net_process_messages() + osDelay(1)
N->>N: 循环 net_poll() + net_process_messages()<br/>(消费 NET_RECONFIG → 按代次号重建监听)
F->>F: wait NET_READY|STORAGE_READY(All|NoClear)→ lftpd_start("/", 21)<br/>→ 串口输出:waiting for connection...
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
Note over D,N,F,U,T: 就绪位一律 osFlagsNoClear(状态常驻、可被多任务重复读取);<br/>仅命令位 CFG_SAVE / NET_RECONFIG 用消费型等待
I->>I: wait NET_READY(Any|NoClear)→ IEC104 listen :2404
P->>P: 20ms 判据节拍 prot_elm_run()(保护判据,不依赖网络)
C->>C: wait TIM3 1kHz 唤醒(ISR adc_tick_irq_notify)→ adc_input_poll() 纯消费
Note over D,N,F,U,T,I: 就绪位一律 osFlagsNoClear(状态常驻、可被多任务重复读取);<br/>仅命令位 CFG_SAVE / NET_RECONFIG 用消费型等待
```
---
@@ -175,23 +186,28 @@ flowchart LR
flowchart TB
CHIP[("CH395F<br/>MAC+PHY · SPI2 + DMA")] --> DRV["ch395f.c<br/>寄存器/命令 + 中断集中读取"]
DRV --> NS["net_socket.c<br/>BSD Socket API(单连接模式)"]
NS --> EVT["net_events.c<br/>边沿事件处理 + 100ms 周期对账"]
NS --> LIS["net_listener.c<br/>监听生命周期(请求登记 + 唯一执行)"]
NS --> PND["net_pending.c<br/>阻塞 recv/send 挂起请求表"]
DRV --> NSEL["net_select.c<br/>select/poll 多路复用"]
NS --> Q["netMsgQueue<br/>(串行化到 netTask)"]
Q --> NT["netTask<br/>net_poll() + net_process_messages()"]
NS --> C1["lftpd<br/>FTP :21"]
NS --> C2["time_sync<br/>对时 :8888"]
NS --> C3["ui_net_sink<br/>RemoDispBus :7003"]
NS --> C4["iec104_serv<br/>104 上行 :2404"]
C3 -.->|"回送 1bpp 帧 + 接收远端按键"| CLIENT["DTU-RemoteLCD 客户端"]
NC["net_cfg<br/>IP/掩码/网关/MAC"] --> NS
style NT fill:#efe,stroke:#484
```
**单连接约束**:CH395F 配置为 8 Socket(索引寻址)+ TCP Server 单连接(`set_fun_para(0x08)`,bit3 SOCKET_CLOSE;bit0 保留必须为 0),Socket 0 复用监听与数据通道;FTP / 对时 / 远程显示三个 TCP 服务**串行**占用连接,连接断开后自动回到 LISTEN。
**单连接约束**:CH395F 配置为 8 Socket(索引寻址)+ TCP Server 单连接(`set_fun_para(0x08)`,bit3 SOCKET_CLOSE;bit0 保留必须为 0),Socket 0 复用监听与数据通道;FTP / 对时 / 远程显示 / IEC104 四个 TCP 服务**串行**占用连接,连接断开后自动回到 LISTEN。
> **FTP 启动门(2026-09-21 修复)**:`ftpTask` 必须等 `NET_READY` **且** `STORAGE_READY`(两位均 `NoClear`)才 `lftpd_start`——此前就绪位被其它等待者消费,FTP **静默不监听**(详见 §2.2 与 `docs/测试说明/FTP_Test_Guide.md` §8.6)。
> **单客户端实测注意**:同一时刻只服务 1 个会话,旧会话异常断开后约 30s 才恢复监听。测试脚本必须内置连接重试(`test/host/ftp_up_dl_test.py`、`test/host/ftp_speed_test.py` 已内置),且**不要用裸 TCP 工具探测 21 端口**(探测会占掉唯一会话,见 `docs/测试说明/FTP_Test_Guide.md` §8.7)。
> 2026-09-21 实测:登录/TYPE I/PASV/STOR/RETR/LIST/DELE/QUIT 全通,128KB 上传下载逐字节一致(约 49/60 KB/s,低于阶段 5 裸 socket 基线,待查)。
> **单客户端实测注意**:同一时刻只服务 1 个会话,旧会话异常断开后经 `net_listener` 重建监听(实测恢复窗 p50 **208 ms**,n=30;口径见 `docs/网络/网络自愈架构设计.md`)。测试脚本必须内置连接重试(`test/host/ftp_up_dl_test.py`、`test/host/ftp_regression.py` 已内置),且**不要用裸 TCP 工具探测 21 端口**(探测会占掉唯一会话,见 `docs/测试说明/FTP_Test_Guide.md` §8.7)。
> **阻塞模型(2026-10-14 SEND 二期落地)**:阻塞 recv/send 经 `net_pending` 挂起请求表续作,调用方铁律 `sent < len`(末块写完即返回、不得登记挂起);架构与五路语义见 `docs/网络/Net层阻塞模型架构设计.md`,监听重建/沉降隔离/周期对账见 `docs/网络/网络自愈架构设计.md`。
> 2026-10-14 实测:FTP 回归连续 19 次 11/11;`ftp_integrity_test` 20 轮 × 64 KB STOR/RETR SHA-256 20/20 一致,吞吐稳定 ≈80 KB/s。
---
@@ -249,14 +265,15 @@ flowchart TB
```
STM32F4-Base/
├── Src/ Inc/ CubeMX 生成:main.c / freertos.c / HAL 外设 / 中断 / 时基
│ ├── freertos.c 6 任务 + netMsgQueue + sys_evt 创建(CubeMX 接线 + 崩溃钩子;任务体在 App/task/)
│ ├── freertos.c 9 任务 + netMsgQueue + sys_evt 创建(CubeMX 接线 + 崩溃钩子;任务体在 App/task/)
│ └── main.c 入口 → app_main_init → osKernelStart
├── App/ 应用层(业务编排,非 CubeMX)
│ ├── app/ 启动编排与全局契约:app_main.c(时间子系统优先)、app_cfg.h、sys_events.h
│ ├── algo/ 采集与算法层(L1/L2):adc_input(语义通道映射 + STM32 ADC1 扫描)
│ ├── task/ default_task / net_task / ui_task / adc_task* / rs485_task*
│ ├── algo/ 采集与算法层 L1~L3:adc_input / phasor / freq / prot_set / prot_elm
│ ├── task/ default_task / net_task / ui_task / adc_task / iec104_serv / protect_task / rs485_task*(*未创建,B2 暂缓)
│ ├── log/ sys_log 记录引擎(定长 64B;MCU 后端落盘 /log/*.log)
│ ├── cfg/ 配置引擎:cfg_file(静态态单任务收敛于 defaultTask)、store(MCU=FreeRTOS 堆)
│ ├── fs/ 卷锁 vol_lock(syslog / cfg / lftpd 三条路径 try 语义)
│ ├── sync/ time_sync(TCP 对时服务)
│ ├── protocol/ 协议编解码(MODBUS 等)与帧解析
│ └── util/ sys_clock(墙钟)、task_watchdog(IWDG 判定状态机)
@@ -266,7 +283,7 @@ STM32F4-Base/
│ ├── TPAFE5160/ ADC
│ ├── SD2506/ RTC
│ ├── RS485/ 半双工串口
│ ├── NET/ net_socket / net_select / lftpd
│ ├── NET/ net_socket / net_select / net_events / net_listener / net_pending / lftpd
│ ├── NETCFG/ 网口配置(INI [network] 段)
│ ├── UI/ LVGL UI(与模拟器共用)
│ └── dbg_log.h/dbg_cfg.h 分级日志
@@ -310,11 +327,16 @@ flowchart LR
|---|---|
| 启动顺序 / 就绪屏障 | `docs/架构设计/项目启动顺序管理.md` |
| 存储架构(NAND/FTL/FatFs) | `docs/架构设计/STM32F4-Base存储架构说明.md` |
| NET 阻塞模型(挂起请求表五路语义) | `docs/网络/Net层阻塞模型架构设计.md` |
| 网络自愈(监听重建 / 沉降隔离 / 周期对账) | `docs/网络/网络自愈架构设计.md` |
| 采集与算法层 L1~L3 | `App/algo/README.md` |
| ADC 采样节拍(TIM3 1kHz 同源驱动) | `docs/子系统设计/ADC采样节拍设计说明.md` |
| IEC 60870-5-104 上行(:2404) | `docs/子系统设计/IEC104上行设计说明.md` |
| 墙钟时间维护 | `docs/子系统设计/系统墙钟时间维护说明.md` |
| 控制台单写者日志(USART1 调试流) | `docs/子系统设计/控制台单写者日志设计说明.md` |
| RAM 预算与优化 | `docs/内存管理/RAM使用分析与优化方案.md` |
| 栈/内存观测工具 | `scripts/stack_report.py`(Keil 静态调用图 × 串口 `[STACK]` 水位,判定取两者更坏者)· `scripts/ram_report.py`(.map 静态占用)—— 用法与基线见内存方案 §0.6 |
| FTP 功能与陷阱 | `docs/测试说明/FTP_Test_Guide.md` §8.6(启动门)/ §8.7(单客户端)· 脚本 `test/host/ftp_up_dl_test.py`、`test/host/ftp_speed_test.py` |
| FTP 功能与陷阱 | `docs/测试说明/FTP_Test_Guide.md` §8.6(启动门)/ §8.7(单客户端)· 脚本 `test/host/ftp_up_dl_test.py`、`test/host/ftp_regression.py`、`test/host/ftp_integrity_test.py` |
| UI 设计架构 / 内容页 / 菜单 | `docs/UI设计/UI_设计架构.md` · `内容页架构.md` · `菜单页面设计.md` |
| UI 自动化测试 | `docs/UI设计/UI_自动化测试流程.md` |
| 驱动已知陷阱 | `docs/问题记录/{CH395F,GD5F2GQ5UE,SD2506}_Trap_Records.md` |
@@ -345,3 +367,4 @@ flowchart LR
| 2026-09-24 → 09-25 | **控制台单写者日志**(09-24 实证驱动:多任务并发日志字符级交错 + HardFault 脏指针直达 UART):4KB 环形缓冲 + defaultTask 唯一发送(行级原子 + 指针可控)+ 内核前/ISR/异常钩子有界直发回退 + `fputc` 收敛到单写者路径;09-24 初版实施于 `Src/usart.c` USER CODE 区,09-25 迁出至 `App/log/console_log.{h,c}`(HAL 生成文件不含应用代码),`dbg_log.h` 改 `#include "console_log.h"`(调用点零改动),`Src/usart.c` 恢复纯 CubeMX 形态;`@build` 0/0 + `@test` PASS;详见 `docs/子系统设计/控制台单写者日志设计说明.md` |
| 2026-09-25 | **defaultTask 任务体文件拆分**:`Src/freertos.c` 的 `StartDefaultTask` 任务体(存储 bring-up / 配置引擎属主 / 控制台单写者 attach+drain / syslog 落盘 / LED / 栈水位探针 `stack_probe_poll`)整体迁至 `App/task/default_task.c`(`default_task_func()`,与其余任务文件同址);`freertos.c` 恢复"CubeMX 接线 + 崩溃钩子"形态(719→361 行),`@build` 0/0 复验;栈配置属性仍定义于 `freertos.c`(`stack_report` 数据源不变) |
| 2026-10-10 | **删除旧档 NCFG 迁移(栈整改)**:`Drivers/BSP/NETCFG/net_cfg_legacy.{c,h}` 整体移除、`cfg_store_legacy_path()` 撤销,`net_cfg_load` 不再调用 `net_cfg_legacy_migrate()`;旧档 `/cfg/netcfg.bin` 若存在则被忽略(不读、不删、不迁移),配置回落工厂默认。理由:该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏栈链 +600 B,本仓库无携带旧档的设备。同轮栈整改(未抬栈):defaultTask 静态最坏链 5312 → 2776 B / 实测峰值 3392 → 2152 B、timeSyncTask 1736 → 1024 B,6 任务全 PASS;代价静态 BSS +4,128 B |
| 2026-10-14 | **任务面与 NET 内部模块同步现状**:§1.1 补 ④ 中间件层 `net_events`/`net_pending`/`net_listener` 与 ③ 层 `algo/*`(L1~L3)、⑦ 硬件行去重(原两行重复编号且 UART5/TIM7 过期 → UART4/TIM3/ADC1);§1.2 增 NET 三内部模块与 algo→adcTask/protectTask 两条跨层依赖;§2.1 任务表 6 → 9 行(补 adcTask/iec104Task/protectTask,栈值按 `freertos.c` 校准:defaultTask 5120、netTask 3840、 timeSyncTask 2560、adcTask 2560、iec104Task 2560、protectTask 2048 B),栈实测更新至 2026-10-10~14 并注明堆已迁 CCM 扩容 56KB;§3 时序图补 adc_input/phasor/freq/prot_set/prot_elm 内核前初始化与 TIM3 节拍启动、新增 iec104Task/protectTask/adcTask 参与者;§5 网络栈图补三个 NET 内部模块与 iec104_serv 消费者,单客户端恢复窗更新为实测 p50 208 ms,登记 SEND pending 二期与 2026-10-14 FTP 实测;§7 目录树补 `algo/`/`fs/`、iec104_serv/protect_task、NET 三新文件;§9 补 Net 阻塞模型/网络自愈/algo/ADC 节拍/IEC104 五条专项文档索引 |
+5 -3
View File
@@ -64,18 +64,20 @@ TARGETS = [
# 文档中的展示顺序(与 README/AGENTS 既有一致;不在表内的任务按源码顺序追加)。
# 不用源码顺序:freertos.c 里 timeSyncTask 定义在最前,但文档按「主任务→辅助任务」排列。
DISPLAY_ORDER = ["defaultTask", "netTask", "ftpTask", "testTask", "uiTask",
"timeSyncTask", "adcTask"]
"timeSyncTask", "adcTask", "iec104Task", "protectTask"]
# 各任务在文档里的「职责」描述(README 需要,AGENTS 不需要)。
# 只影响展示文案,不参与一致性判定;未知任务回落为空。
ROLE = {
"defaultTask": "FTL + FatFS 挂载、配置引擎属主、syslog 唯一写者",
"netTask": "网络初始化 + CH395F 轮询",
"netTask": "网络初始化 + CH395F 轮询(消费 NET_RECONFIG 按代次重建监听)",
"ftpTask": "FTP 服务(等待网络+存储就绪)",
"testTask": "硬件测试入口",
"uiTask": "LVGL UI 界面",
"timeSyncTask": "墙钟时间同步",
"adcTask": "TPAFE5160 采样(TIM3 1kHz 事件驱动 + 原子快照 + STM32 ADC DMA)",
"adcTask": "TPAFE5160 采样(TIM3 1kHz 事件驱动 + 原子快照 + STM32 ADC DMA,纯消费者)",
"iec104Task": "IEC 60870-5-104 上行(:2404 监听,遥信/遥测/定值区)",
"protectTask": "保护判据 20ms 节拍(L3 元件 + 采样故障闭锁,B5)",
}
+4 -3
View File
@@ -56,7 +56,7 @@ BITS = [
dict(bit="bit1", flag="STORAGE_READY", color="#16a34a", bg="#f0fdf4",
note="defaultTask 置位(挂载+配置)· netTask / ftpTask 等待"),
dict(bit="bit0", flag="NET_READY", color="#0d9488", bg="#f0fdfa",
note="netTask 置位 · 4 个任务等待"),
note="netTask 置位 · 5 个任务等待"),
dict(bit="bit2", flag="FTP_READY", color="#d97706", bg="#fffbeb",
note="ftpTask 置位 · 预留消费者"),
dict(bit="bit3", flag="TIMESYNC_READY", color="#94a3b8", bg="#f8fafc",
@@ -76,7 +76,8 @@ CONSUMERS = [
dict(name="ftpTask", note="wait bit0 + bit1 · All", row=1),
dict(name="uiTask", note="wait bit0 · Forever", row=2),
dict(name="timeSyncTask", note="wait bit0 · Forever", row=3),
dict(name="testTask", note="wait bit0 · NET 模式", row=4),
dict(name="iec104Task", note="wait bit0 · Forever", row=4),
dict(name="testTask", note="wait bit0 · NET 模式", row=5),
]
FOOT = ("生产者与消费者互不知晓,只经事件组解耦;新增子系统 = 新 bit + 各自 wait/set,"
@@ -213,7 +214,7 @@ def build():
add('<text x="%d" y="%.1f" font-size="%s" font-weight="700" fill="%s">All</text>'
% (TAP_X + 9, c1 - 8, LABEL_FONT, col0))
# ---- wait 连线:bit0 → 总线 → 4 个消费者 ----
# ---- wait 连线:bit0 → 总线 → 各 bit0 消费者(ftpTask/ui/timeSync/iec104/testTask) ----
c_last = row_cy(len(CONSUMERS) - 1)
poly([(PANEL_X + PANEL_W, c1), (BUS_X, c1)], col0)
poly([(BUS_X, c1), (BUS_X, c_last)], col0, head=False)