Table of Contents
项目架构
一页看清: 分层、任务、启动顺序、线程间通信与数据流。细节以
docs/架构设计/项目架构总览.md、docs/架构设计/项目启动顺序管理.md和源码为准。本页基于 2026-11-01 的
master分支整理; 当前任务表以Src/freertos.c为准(9 个任务)。
1. 分层架构
图: 七层单向依赖 - 上层只依赖相邻下层.
设计原则: 上层只依赖相邻下层, 单向依赖; UI 层与基础服务层同级并列; 业务层(net_cfg)是顶层共享配置。
| 层 | 目录 | 职责 | 关键模块 |
|---|---|---|---|
| ① 业务层 | Drivers/BSP/NETCFG/ |
顶层共享配置, 被 UI 与基础服务共用 | net_cfg |
| ② UI 层 | Drivers/BSP/UI/ |
LVGL 界面, 与 PC 模拟器共用源码 | ui_menu / ui_content_page / ui_page_* / ui_net_sink |
| ③ 基础服务层 | App/、Drivers/BSP/NET/lftpd/ |
应用编排、任务、日志、对时、FTP | app_main / sys_events / task/* / lftpd / time_sync |
| ④ 中间件层 | Drivers/BSP/NET/、Lib/、App/util/ |
通用库与协议栈 | net_socket / net_select / FatFs / dhara FTL / 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 @168 MHz | SPI1/SPI2/I2C1/UART4/USART1/DMA/GPIO/TIM7/TIM3 |
关键跨层调用: UI 的网口设置页只读写
net_cfg的 RAM 副本, 不直接触 CH395F; FTP / 对时 / 远程显示 / 104 都经net_socket; 所有 CH395F 操作最终串行化到netTask。
2. 运行时任务(9 个)
图: 任务栈预算 - 栈从 CCM 的 FreeRTOS 堆分配.
任务由 Src/freertos.c 创建, 任务体在 App/task/、App/sync/ 与 App/algo/。栈单位为 words(x4 = 字节)。
| 任务 | 栈(words) | 优先级 | 职责 |
|---|---|---|---|
defaultTask |
1280 | Normal | FatFS 挂载/自愈、配置引擎属主、syslog 唯一写者、控制台唯一发送者、LED、栈水位、看门狗唯一喂狗者 |
netTask |
960 | Normal | 网络 bring-up、CH395F 轮询、socket 消息串行执行、网络重建 |
ftpTask |
1024 | Normal | 等网络 + 存储双就绪后启动 FTP(21), 单客户端会话循环 |
testTask |
2048 | BelowNormal | 板端测试套件入口; 产品构建不选套件时立即删除回收 8 KB 栈 |
uiTask |
4096 | BelowNormal | LVGL 初始化、菜单/内容页、待机屏、10 ms 刷新、远程推流 |
timeSyncTask |
640 | Normal | TCP 8888 接收 PC 推送时间并写 RTC |
adcTask |
640 | AboveNormal | 1 kHz 采样节拍消费者: TPAFE 原子快照 + STM32 ADC1 DMA; 喂 TASK_WD_ADC |
iec104Task |
640 | Normal | IEC 60870-5-104 被控站服务(TCP 2404); 喂 TASK_WD_IEC104 |
protectTask |
512 | Normal | 20 ms 保护判据节拍: prot_elm_run()、采样故障闭锁、定值校验; 喂 TASK_WD_PROTECT |
idle/timer由 FreeRTOS 内核创建。任务栈从 CCM 中的 FreeRTOS heap 分配, 不占主 SRAM。 改栈或加大局部变量前后必须重跑scripts/stack_report.py; 新增任务前先核算 RAM 预算(见开发指南)。
3. 就绪屏障(Event Flags)
图: 就绪屏障 - 状态位 NoClear, 命令位消费.
任务启动顺序不靠魔法延时, 而靠 CMSIS-RTOS2 Event Flags(sys_evtHandle)。生产者置位, 消费者等待。
| bit | 名称 | 类型 | 语义 |
|---|---|---|---|
| 0 | SYS_EVT_NET_READY |
状态位 | netTask: 网络初始化 + PHY 稳定完成 |
| 1 | SYS_EVT_STORAGE_READY |
状态位 | defaultTask: FTL/FatFS 挂载 + 配置就绪 |
| 2 | SYS_EVT_FTP_READY |
状态位 | ftpTask: FTP 启动完成(预留) |
| 3 | SYS_EVT_TIMESYNC_READY |
状态位 | 首次对时完成(预留) |
| 4 | SYS_EVT_NET_RECONFIG |
命令位 | UI 请求立即应用新网口配置 |
| 5 | SYS_EVT_CFG_SAVE |
命令位 | UI 请求保存配置(defaultTask 消费) |
| 6 | SYS_EVT_CONSOLE_TX |
命令位 | 控制台环形缓冲有数据待发送 |
| 7 | SYS_EVT_PROT_SET_SAVE |
命令位 | 保护定值脏, 请求落盘 |
两条铁律:
- 状态位必须
osFlagsNoClear: 就绪位表达持久状态, 任何消费者都不许消费它。曾因默认消费导致ftpTask的WaitAll永不成立、21 端口静默不监听。 - 命令位必须消费型: 命令位要恰好被消费一次, 否则会反复写盘或反复重建网络。
4. 启动时序
sequenceDiagram
participant M as 复位 / main.c
participant A as app_main_init
participant K as FreeRTOS
participant T as 任务
M->>M: HAL_Init + 时钟 + 外设
M->>A: fault_handler_enable
A->>A: syslog + 复位原因
A->>A: SD2506 + sys_clock
A->>A: RS-485 / NAND / TPAFE
A->>A: 采集处理 / 相量 / 测频 / 保护判据
A->>A: SD2506 诊断 + TIM3 1 kHz
A->>K: osKernelInitialize / MX_FREERTOS_Init
K->>T: osKernelStart
T-->>T: 就绪屏障 + 节拍运行
osKernelStart之前是“内核前模式”: 禁止任何 FreeRTOS/CMSIS-RTOS 创建类 API; 只能用纯寄存器/HAL 轮询、无锁静态缓冲, 内核启动后再惰性创建真正的队列。详见docs/架构设计/项目启动顺序管理.md。
5. 数据流
5.1 采集与保护
flowchart TB
TIM["TIM3 更新事件<br/>1 kHz"] -->|CONVST| T["TPAFE5160<br/>8 路电气量<br/>并行 16 位"]
TIM -->|TRGO| A["STM32 ADC1<br/>9 路<br/>DMA 连续请求"]
T --> S["原子快照"]
A --> S
S --> TASK["adcTask<br/>纯消费者<br/>每拍 poll"]
TASK --> L1["采集处理层<br/>adc_input / adc_health"]
L1 --> L2["相量层<br/>sample_ring / phasor"]
L2 --> F["测频<br/>freq"]
L2 --> L3["保护判据层<br/>prot_set / prot_elm"]
L3 --> P["protectTask<br/>20 ms"]
F --> M["遥测快照<br/>meas 200 ms"]
M --> I["IEC 60870-5-104<br/>TCP 2404"]
P --> I
详见采集与算法。
5.2 存储
flowchart TB
APP["应用 / FTP / 配置 / 日志"] --> FF["FatFs FAT32"]
FF --> D["diskio"]
D --> FTL["dhara FTL"]
FTL --> N["GD5F2GQ5UE NAND"]
defaultTask 是配置引擎属主与 syslog 唯一写者; ftpTask 通过 FatFs 读写, FatFs 打开 FF_FS_REENTRANT 做卷级互斥。详见存储子系统。
5.3 网络
flowchart TB
CH["CH395F SPI2"] --> NS["net_socket + net_select"]
NS --> Q["netMsgQueue 深度 8"]
Q --> NT["netTask 串行执行"]
NT --> FTP["FTP :21"]
NT --> TS["对时 :8888"]
NT --> UI["远程显示 :7003"]
NT --> IEC["IEC 104 :2404"]
CH395F 是单连接模型: Socket 0 复用监听与数据通道, 四个 TCP 服务串行占用连接, 断开后自动回 LISTEN。详见网络子系统。
5.4 UI 与日志
- UI:
uiTask把 LVGL 渲染到 160x160、1bpp 的g_ui_fbuf(3200 B), 经ui_net_sink在 TCP 7003 推流; 远端按键回注。 - 日志:
syslog_post()写定长 64 B 记录到/log/run.log//log/selftest.log; 实时调试流走 USART1, 由defaultTask单写者发送。 - 看门狗: 各任务置心跳位,
defaultTask每 100 ms 采样, 连续 800 ms 不达标就停止喂 IWDG, 约 2.5 s 后复位。
6. 线程间通信与单写者
| 机制 | 对象 | 用途 |
|---|---|---|
| Event Flags | sys_evtHandle |
启动屏障、配置保存、网络重建、控制台、定值落盘 |
| Message Queue | netMsgQueue(深度 8) |
所有 CH395F 操作串行化到 netTask |
| 任务通知 | xTaskNotify() |
net_* 公开 API 的错误码回传(net_msg_t 按值拷贝, 改副本调用方看不到) |
| 环形缓冲 | 控制台 4 KB | 多任务日志入队, defaultTask 唯一发送 |
单写者纪律: 配置文件属主 = defaultTask; syslog 唯一写者 = defaultTask; 控制台唯一发送者 = defaultTask。netTask/uiTask 不得直接触碰配置引擎。
7. 目录地图
| 目录 | 职责 | 可改性 |
|---|---|---|
Src/ Inc/ |
CubeMX 生成: main.c、freertos.c、HAL 外设、中断、时基 |
只写 USER CODE 区 |
App/ |
应用层: app/ 启动与就绪事件、task/ 任务、algo/ 采集与算法、cfg/ 配置、log/ 日志、fs/ 卷锁、sync/ 对时、util/ 工具 |
手写 |
Drivers/BSP/ |
手写驱动与服务: TPAFE5160 / CH395F / NET(socket + lftpd)/ NETCFG / GD5F2GQ5UE / SD2506 / RS485 / UI | 手写 |
Drivers/STM32F4xx_HAL_Driver/ Drivers/CMSIS/ Middlewares/ |
ST HAL / CMSIS / FreeRTOS | 第三方, 只读 |
Lib/ |
LVGL、FatFs、dhara + MCU 端 lv_conf.h |
只读(本地补丁须登记) |
MDK-ARM/ |
Keil 工程、scatter、下载脚本 | 工程配置手改; UV4 抖动不入库 |
simulator/ |
LVGL PC 模拟器(CMake + SDL2), 与固件同标准受检 | 手写 |
test/ |
board/ 板级套件、host/ 主机侧单测与脚本 |
手写 |
scripts/ tools/ |
门禁与报告脚本、配图/字体/菜单生成器 | 手写 |
docs/ |
全量设计/测试/规范文档(入口 docs/README.md) |
手写, 受 doc-links 门禁 |
.dsh/skills/ .gitea/ .serialtest/ |
agent skills、CI 工作流、串口/烧录配置 | 手写 |
8. 延伸阅读
| 主题 | 文档 |
|---|---|
| 全景架构(图 + 跨层依赖) | docs/架构设计/项目架构总览.md |
| 启动顺序与内核前模式 | docs/架构设计/项目启动顺序管理.md |
| 存储栈 | docs/架构设计/STM32F4-Base存储架构说明.md |
| 产品需求基线 | docs/产品需求/产品需求设计文档.md |
| 看门狗 | docs/子系统设计/看门狗设计说明.md |
| ADC 采样节拍 | docs/子系统设计/ADC采样节拍设计说明.md |
| IEC 104 | docs/子系统设计/IEC104上行设计说明.md |
| 内存预算 | docs/内存管理/RAM使用分析与优化方案.md |
STM32F4-Base 百科
入门
子系统
开发与验证
参考
仓库
STM32F4-Base 百科 · 基于仓库 master 分支整理 · 最后更新: 2026-11-01
内容以源码、AGENTS.md 与 docs/ 为准; 发现页面过期, 请在 维护指南 中按流程更新。