增加了一些架构图片

This commit is contained in:
2026-09-02 10:06:14 +08:00
parent 7f0087d430
commit 3f0ea5761c
2 changed files with 94 additions and 33 deletions
+73 -20
View File
@@ -21,22 +21,26 @@
## 项目架构
```
┌─────────────────────────────────────────────────────────────┐
│ 应用层 (App/) │
│ app_main.c │ net_task.c │ ui_task.c │ time_sync.c │
├─────────────────────────────────────────────────────────────┤
│ 驱动层 (Drivers/BSP/) │
│ CH395F/ │ GD5F2GQ5UE/ │ TPAFE5160/ │ SD2506/ │ RS485/ │ UI/ │
├─────────────────────────────────────────────────────────────┤
│ 中间件 (Middlewares/ & Lib/) │
│ FreeRTOS │ FatFs │ dhara FTL │ LVGL │
├─────────────────────────────────────────────────────────────┤
│ HAL 层 (Drivers/STM32F4xx_HAL_Driver/) │
│ CMSIS (Drivers/CMSIS/) │
├─────────────────────────────────────────────────────────────┤
│ 硬件 (STM32F407ZGTx) │
└─────────────────────────────────────────────────────────────┘
```mermaid
flowchart TB
subgraph APP["应用层 (App/)"]
direction LR
A1["app_main.c"] ~~~ A2["net_task.c"] ~~~ A3["ui_task.c"] ~~~ A4["time_sync.c"]
end
subgraph BSP["驱动层 (Drivers/BSP/)"]
direction LR
B1["CH395F"] ~~~ B2["GD5F2GQ5UE"] ~~~ B3["TPAFE5160"] ~~~ B4["SD2506"] ~~~ B5["RS485"] ~~~ B6["UI"]
end
subgraph MW["中间件 (Middlewares/ & Lib/)"]
direction LR
C1["FreeRTOS"] ~~~ C2["FatFs"] ~~~ C3["dhara FTL"] ~~~ C4["LVGL"]
end
subgraph HAL["HAL 层 / CMSIS"]
direction LR
D1["STM32F4xx_HAL_Driver/"] ~~~ D2["CMSIS/"]
end
HW["硬件 (STM32F407ZGTx)"]
APP --> BSP --> MW --> HAL --> HW
```
### 启动流程
@@ -46,11 +50,13 @@ main.c
├─ HAL_Init()
├─ SystemClock_Config() // 168MHz 系统时钟
├─ MX_GPIO/DMA/UART/SPI/I2C_Init() // CubeMX 外设初始化
├─ app_main_init() // 应用层初始化(时间→RS485→NAND→ADC→RTC)
├─ app_main_init() // 应用层初始化(时间→RS485→NAND→ADC→诊断)
│ ├─ sd2506_init() + sys_clock_init() // 时间子系统优先
│ ├─ rs485_init()
│ ├─ gd5f2gq5ue_init()
│ └─ tpafe5160_init()
│ ├─ tpafe5160_init()
│ ├─ SD2506 诊断(ID/时间/温度/电池)
│ └─ tpafe5160_start_conv_irq() // 首次 ADC 转换
├─ osKernelInitialize()
├─ MX_FREERTOS_Init() // 创建任务和事件组
└─ osKernelStart() // 启动调度器
@@ -114,7 +120,8 @@ STM32F4-Base/
│ │ │ ├── net_socket.c/h # Socket API
│ │ │ ├── net_select.c/h # select/poll 多路复用
│ │ │ └── lftpd/ # 轻量 FTP 服务器
│ │ └── UI/ # LVGL UI 组件
│ │ ├── UI/ # LVGL UI 组件
│ │ └── dbg_log.h / dbg_cfg.h # 调试日志(DBG_INFO 等)
│ ├── STM32F4xx_HAL_Driver/ # ST HAL 库
│ └── CMSIS/ # ARM CMSIS
├── Lib/ # 第三方库
@@ -132,20 +139,42 @@ STM32F4-Base/
│ ├── run_boot_test.ps1 # 自动化启动测试
│ ├── verify_log.ps1 # 日志校验脚本
│ ├── serial_capture.ps1 # 串口捕获脚本
│ ├── test_config.c/h # 测试任务配置
│ ├── ch395f_test_task.c/h # CH395F 硬件测试
│ ├── gd5f_test_task.c/h # NAND Flash 测试
│ ├── net_test_task.c/h # 网络层测试
│ ├── sd2506_test_task.c/h # RTC 测试
│ └── storage_test_task.c/h # 存储性能测试
│ ├── storage_test_task.c/h # 存储性能测试
│ ├── ch395f_socket_test.py # Socket 通信测试(主机端)
│ ├── ftp_test.py # FTP 服务器测试(主机端)
│ ├── ftp_up_dl_test.py # FTP 上传下载测试(主机端)
│ ├── ftp_speed_test.py # FTP 传输速度测试(主机端)
│ ├── ftp_capture.py # FTP 流量抓取(主机端)
│ └── time_sync_server.py # 时间同步推送服务(主机端)
├── docs/ # 项目文档
│ ├── 代码规范/ # C 代码规范、pre-commit / cppcheck 使用说明
│ ├── 问题记录/ # 已知陷阱与解决方案
│ ├── 测试说明/ # 测试指南
│ ├── 芯片手册/ # 硬件数据手册
│ ├── 测试开发标准流程.md # 测试开发标准流程
│ ├── 测试文档模板规范.md # 测试文档模板规范
│ └── *.md # 存储架构 / UI 规划 / 墙钟时间 / 启动顺序 / LVGL 模拟器
├── scripts/ # pre-commit 本地钩子脚本
│ ├── check_coding_standard.py # 代码规范机械检查
│ └── check_mojibake.py # U+FFFD 乱码检查
├── simulator/ # LVGL PC 模拟器(CMake + SDL2)
│ ├── CMakeLists.txt # 模拟器构建脚本
│ ├── main.c / sim_port.c/h # 模拟器入口与移植层
│ ├── lv_conf.h # LVGL 配置(1bpp + SDL)
│ └── SDL2/ # SDL2 2.32.10 预编译库
├── tools/ # 开发工具
│ └── font_gen/ # 中文字体生成工具
├── ui_cn_chars.txt # 中文字体字符集
├── STM32F407-Demo.ioc # CubeMX 工程文件
├── .pre-commit-config.yaml # pre-commit 钩子配置
├── .gitlint # commit message 检查规则
├── opencode.json # opencode 配置
├── .opencode/ # opencode 本地配置(串口等)
└── AGENTS.md # AI 开发规范
```
@@ -177,6 +206,17 @@ MDK-ARM\build.bat
MDK-ARM\download.bat
```
### LVGL PC 模拟器
PC 端 UI 开发调试(无需烧录 MCU),详见 `docs/LVGL模拟器部署与使用说明.md`:
```powershell
cd simulator
cmake -B build -G "Visual Studio 16 2019" -A x64
cmake --build build --config Debug
# 运行 simulator\build\Debug\lvgl_sim.exe
```
## 驱动开发指南
### CH395F 以太网
@@ -226,6 +266,17 @@ powershell -ExecutionPolicy Bypass -File test\run_boot_test.ps1
| RTC | `sd2506_test_task.c` | 时间读写、温度、电池 |
| 存储性能 | `storage_test_task.c` | FTL/FatFS 读写速度 |
### 主机端测试脚本(Python)
| 脚本 | 说明 |
|------|------|
| `ch395f_socket_test.py` | Socket 通信测试 |
| `ftp_test.py` | FTP 服务器基础测试 |
| `ftp_up_dl_test.py` | FTP 上传/下载测试 |
| `ftp_speed_test.py` | FTP 传输速度测试 |
| `ftp_capture.py` | FTP 流量抓取 |
| `time_sync_server.py` | 时间同步推送服务(PC → 板子) |
### 串口调试
通过 `serial-mcp-server` 自主读取 USART1 串口打印:
@@ -267,6 +318,8 @@ powershell -ExecutionPolicy Bypass -File test\run_boot_test.ps1
- U+FFFD 乱码(拦截,不可逆损坏)
- commit message 格式(gitlint,拦截)
本地钩子脚本:`scripts/check_coding_standard.py`、`scripts/check_mojibake.py`(由 `.pre-commit-config.yaml` 引用)。
```bash
# 新机器启用钩子
pre-commit install
+21 -13
View File
@@ -95,21 +95,29 @@ static volatile uint32_t s_base_unix_secs = UINT32_MAX; /* 基准对应的 Unix
## 6. 初始化流程(`sys_clock_init`)
```
Step 1 从 SD2506 读取初始时间 sd2506_get_time(&sd_time)
├─ 注意:sd_time.year 已是完整年份(驱动内已 +2000),
│ 后续换算【不得】再加 2000,否则年份虚增 → Unix 秒数超 uint32 回绕
└─ 可选校时(见第 9 节 RTC_DEFAULT_INIT_* 宏)
```mermaid
sequenceDiagram
autonumber
participant SC as sys_clock_init
participant RTC as SD2506 RTC
participant HAL as HAL Tick
Step 2 将 RTC 时间换算为 Unix epoch 秒数
├─ 累计 1970 至当前年份的整年天数(含闰年 366 天判定)
├─ 加上当年 1 月至当前月的累计天数
├─ 加当月已过天数、时/分/秒
└─ 用 int64_t 累加,避免中间溢出;结果截断存入 uint32_t(受 2038 限制,见第 12 节)
Note over SC,RTC: Step 1 从 SD2506 读取初始时间
SC->>RTC: sd2506_get_time(sd_time)
RTC-->>SC: sd_time(year 已是完整年份)
Note right of SC: 后续换算【不得】再加 2000<br>否则年份虚增 → Unix 秒数超 uint32 回绕
Note right of SC: 可选校时(见第 9 节 RTC_DEFAULT_INIT_* 宏)
Step 3 建立基准
s_base_tick = HAL_GetTick();
s_base_unix_secs = (uint32_t)unix_secs;
Note over SC: Step 2 将 RTC 时间换算为 Unix epoch 秒数
SC->>SC: 累计 1970 至当前年份的整年天数(含闰年 366 天判定)
SC->>SC: 加上当年 1 月至当前月的累计天数
SC->>SC: 加当月已过天数、时/分/秒
SC->>SC: 用 int64_t 累加,避免中间溢出;结果截断存入 uint32_t(受 2038 限制,见第 12 节)
Note over SC,HAL: Step 3 建立基准
SC->>HAL: HAL_GetTick()
HAL-->>SC: 当前 tick
Note right of SC: s_base_tick = HAL_GetTick()<br>s_base_unix_secs = (uint32_t)unix_secs
```
初始化后,所有后续取时都基于 Step 3 的基准推算,不再访问 RTC。