401 lines
18 KiB
Markdown
401 lines
18 KiB
Markdown
# STM32F4-Base
|
||
|
||
基于 STM32F407ZGTx 的工业级嵌入式平台固件,集成以太网通信、NAND Flash 存储、ADC 采集、RS-485 通信及 FTP 文件服务。
|
||
|
||
## 硬件平台
|
||
|
||
- **MCU**: STM32F407ZGTx @ 168MHz (HSE 8MHz → PLL M=4/N=168/P=2)
|
||
- **封装**: LQFP144
|
||
- **RTOS**: FreeRTOS V10.3.1 (CMSIS-RTOS V2)
|
||
|
||
### 外设接口
|
||
|
||
| 外设 | 接口 | 引脚 | 说明 |
|
||
|------|------|------|------|
|
||
| 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 |
|
||
| USART1 | 串口 | PA9 TX, PA10 RX | 115200bps 调试串口 |
|
||
| 6x LED | GPIO | PC4, PC5, PB1, PB2, PF11, PF12 | 低电平点亮 |
|
||
| RS-485 | UART5 | PC12 TX, PD2 RX, PD0 DE | 半双工通信 |
|
||
|
||
## 项目架构
|
||
|
||
```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
|
||
```
|
||
|
||
> 更详细的全景架构(六层分层 + 任务与就绪屏障 + 启动时序 + 存储/网络/UI 栈 + 目录组织)见 **`docs/项目架构总览.md`**。
|
||
|
||
### 启动流程
|
||
|
||
```
|
||
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() // 时间子系统优先
|
||
│ ├─ rs485_init()
|
||
│ ├─ gd5f2gq5ue_init()
|
||
│ ├─ tpafe5160_init()
|
||
│ ├─ SD2506 诊断(ID/时间/温度/电池)
|
||
│ └─ tpafe5160_start_conv_irq() // 首次 ADC 转换
|
||
├─ osKernelInitialize()
|
||
├─ MX_FREERTOS_Init() // 创建任务和事件组
|
||
└─ osKernelStart() // 启动调度器
|
||
```
|
||
|
||
### FreeRTOS 任务
|
||
|
||
| 任务 | 栈大小 | 优先级 | 职责 |
|
||
|------|--------|--------|------|
|
||
| defaultTask | 2048 words | Normal | FTL + FatFS 挂载(一次性) |
|
||
| netTask | 4096 words | Normal | 网络初始化 + CH395F 轮询 |
|
||
| ftpTask | 4096 words | Normal | FTP 服务(等待网络+存储就绪) |
|
||
| testTask | 4096 words | BelowNormal | 硬件测试入口 |
|
||
| uiTask | 16384 words | BelowNormal | LVGL UI 界面 |
|
||
| timeSyncTask | 2048 words | Normal | 墙钟时间同步 |
|
||
|
||
### 任务启动顺序管理
|
||
|
||
使用 CMSIS-RTOS v2 Event Flags 实现就绪屏障(readiness barrier):
|
||
|
||
- `SYS_EVT_NET_READY` (bit 0): netTask 置位
|
||
- `SYS_EVT_STORAGE_READY` (bit 1): defaultTask 置位
|
||
- `SYS_EVT_FTP_READY` (bit 2): ftpTask 置位(预留)
|
||
- `SYS_EVT_TIMESYNC_READY` (bit 3): timeSyncTask 置位(预留)
|
||
|
||
消费者通过 `osEventFlagsWait()` 阻塞等待,零占用,取代魔法延时和全局变量轮询。
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
STM32F4-Base/
|
||
├── Src/ # CubeMX 生成的源文件(USER CODE 区域可编辑)
|
||
│ ├── main.c # 程序入口
|
||
│ ├── freertos.c # FreeRTOS 任务创建
|
||
│ ├── gpio.c / dma.c / spi.c / i2c.c / usart.c
|
||
│ └── stm32f4xx_hal_msp.c / stm32f4xx_it.c
|
||
├── Inc/ # CubeMX 生成的头文件
|
||
│ ├── main.h / FreeRTOSConfig.h / stm32f4xx_hal_conf.h
|
||
│ └── gpio.h / dma.h / spi.h / i2c.h / usart.h
|
||
├── App/ # 应用层代码
|
||
│ ├── app_main.c/h # 应用初始化入口
|
||
│ ├── app_cfg.h # 功能模块编译开关
|
||
│ ├── sys_events.h # 系统就绪事件定义
|
||
│ ├── sys_clock.c/h # 墙钟时间管理
|
||
│ ├── time_sync.c/h # 时间同步任务
|
||
│ ├── task/ # FreeRTOS 任务实现
|
||
│ │ ├── net_task.c/h # 网络任务
|
||
│ │ ├── ui_task.c/h # UI 任务
|
||
│ │ ├── adc_task.c/h # ADC 任务
|
||
│ │ └── rs485_task.c/h # RS-485 任务
|
||
│ ├── protocol/ # 通信协议(预留)
|
||
│ └── util/ # 工具函数(CRC、环形缓冲等)
|
||
├── Drivers/
|
||
│ ├── BSP/ # 板级驱动(手工编写)
|
||
│ │ ├── CH395F/ # 以太网控制器驱动
|
||
│ │ ├── GD5F2GQ5UE/ # NAND Flash 驱动 + FTL
|
||
│ │ ├── TPAFE5160/ # ADC 驱动
|
||
│ │ ├── SD2506/ # RTC 驱动
|
||
│ │ ├── RS485/ # RS-485 通信驱动
|
||
│ │ ├── NET/ # BSD Socket API 网络抽象层
|
||
│ │ │ ├── net_socket.c/h # Socket API
|
||
│ │ │ ├── net_select.c/h # select/poll 多路复用
|
||
│ │ │ └── lftpd/ # 轻量 FTP 服务器
|
||
│ │ ├── UI/ # LVGL UI 组件
|
||
│ │ └── dbg_log.h / dbg_cfg.h # 调试日志(DBG_INFO 等)
|
||
│ ├── STM32F4xx_HAL_Driver/ # ST HAL 库
|
||
│ └── CMSIS/ # ARM CMSIS
|
||
├── Lib/ # 第三方库
|
||
│ ├── dhara/ # NAND FTL 算法
|
||
│ ├── FatFs/ # FAT 文件系统
|
||
│ └── lvgl/ # 图形库
|
||
├── Middlewares/
|
||
│ └── Third_Party/FreeRTOS/ # FreeRTOS 内核
|
||
├── MDK-ARM/ # Keil 工程
|
||
│ ├── STM32F407-Demo.uvprojx # 工程文件
|
||
│ ├── build.bat # 命令行编译脚本
|
||
│ ├── download.bat # 烧录脚本
|
||
│ └── startup_stm32f407xx.s # 启动文件
|
||
├── test/ # 测试代码与脚本
|
||
│ ├── run_boot_test.ps1 # 自动化启动测试
|
||
│ ├── verify_log.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 # 存储性能测试
|
||
│ ├── 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/ # 项目文档
|
||
│ ├── UI 设计/ # LVGL UI:架构 / 菜单页面 / 制作流程 / 字体 / 模拟器 / 自动化测试 + mockups 样机
|
||
│ ├── 代码规范/ # C 代码规范、pre-commit / cppcheck 使用说明
|
||
│ ├── 问题记录/ # 已知陷阱与解决方案
|
||
│ ├── 测试说明/ # 测试指南
|
||
│ ├── 芯片手册/ # 硬件数据手册
|
||
│ ├── 测试开发标准流程.md # 测试开发标准流程
|
||
│ ├── 测试文档模板规范.md # 测试文档模板规范
|
||
│ ├── 图形绘制流程.md # 文档配图绘制流程(SVG 生成器 / Mermaid 选型 / 约定 / 检查清单)
|
||
│ └── *.md # 存储架构 / 墙钟时间 / 启动顺序等(UI 相关文档在 UI 设计/)
|
||
├── scripts/ # pre-commit 本地钩子脚本
|
||
│ ├── check_coding_standard.py # 代码规范机械检查
|
||
│ └── check_mojibake.py # U+FFFD 乱码检查
|
||
├── simulator/ # LVGL PC 模拟器(CMake + SDL2,与 MCU 共用 UI 源码)
|
||
│ ├── CMakeLists.txt # 模拟器构建脚本
|
||
│ ├── main.c # 模拟器入口(SDL → LVGL → 菜单 → 主循环)
|
||
│ ├── sim/ # 平台层(sim_port 显示/输入、net_socket_sim、推流/网口配置 backend)
|
||
│ ├── lv_conf.h # LVGL 配置(1bpp + SDL)
|
||
│ ├── i1_to_png.py # 截图 I1(1bpp) → PNG 转换工具
|
||
│ ├── tests/ # 无头回归脚本 + 黄金参考(菜单像素回归 / 内容页黄金参考)
|
||
│ └── SDL2/ # SDL2 2.32.10 预编译库
|
||
├── tools/ # 开发工具
|
||
│ ├── font_gen/ # 中文字体生成工具
|
||
│ └── serial_tool/ # Python 串口助手(常驻 daemon + CLI,见 docs/测试说明/串口助手设计说明.md)
|
||
├── ui_cn_chars.txt # 中文字体字符集
|
||
├── requirements.txt # Python 依赖清单(统一 .venv 环境,见 AGENTS.md「Python 环境」)
|
||
├── STM32F407-Demo.ioc # CubeMX 工程文件
|
||
├── .pre-commit-config.yaml # pre-commit 钩子配置
|
||
├── .gitlint # commit message 检查规则
|
||
├── opencode.json # opencode 配置
|
||
├── .opencode/ # opencode 本地配置(串口等)
|
||
└── AGENTS.md # AI 开发规范
|
||
```
|
||
|
||
## 构建系统
|
||
|
||
### 环境要求
|
||
|
||
- **Keil MDK-ARM v5** (ARMCC 编译器)
|
||
- **Python 3**(统一入口为仓库内 `.venv`,依赖见 `requirements.txt`,重建方法见 AGENTS.md「Python 环境」)
|
||
- **ST-Link** 或兼容调试器
|
||
|
||
### 编译
|
||
|
||
```bash
|
||
# 方式一:命令行编译(推荐)
|
||
MDK-ARM\build.bat
|
||
|
||
# 方式二:Keil IDE
|
||
# 打开 MDK-ARM\STM32F407-Demo.uvprojx → Build (F7)
|
||
```
|
||
|
||
退出码:0 = 成功 | 1 = 有警告 | 2+ = 错误
|
||
|
||
编译日志:`MDK-ARM/build_log.txt`
|
||
|
||
### 烧录
|
||
|
||
```bash
|
||
MDK-ARM\download.bat
|
||
```
|
||
|
||
### LVGL PC 模拟器
|
||
|
||
PC 端 UI 开发调试(无需烧录 MCU,与 MCU 共用 `Drivers/BSP/UI/` 源码),详见 `docs/UI 设计/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
|
||
```
|
||
|
||
UI 改动回归门禁(菜单像素回归 + 内容页黄金参考 + 池水位校验):
|
||
|
||
```powershell
|
||
.venv\Scripts\python.exe simulator/tests/check_menu_rows.py
|
||
.venv\Scripts\python.exe simulator/tests/check_content_pages.py
|
||
```
|
||
|
||
详见 `docs/UI 设计/UI_自动化测试流程.md`。
|
||
|
||
## 驱动开发指南
|
||
|
||
### CH395F 以太网
|
||
|
||
- 单连接模式:Socket 0 复用监听和数据通道
|
||
- 中断统一处理:所有中断在 `net_poll()` 中通过 `GET_GLOB_INT_STATUS` 集中读取清除
|
||
- SPI 事务必须用 `ch395f_spi_begin()` / `ch395f_spi_end()` 包裹
|
||
- SPI 分频系数必须为 8(PCB 设计限制)
|
||
|
||
### GD5F2GQ5UE NAND Flash
|
||
|
||
- 三层软件栈:FatFS → dhara FTL → NAND 驱动
|
||
- FTL 提供 LBA 映射、磨损均衡、坏块管理、垃圾回收
|
||
- 物理分区:全部 2048 块用于 FTL + FatFS
|
||
|
||
### 网络层 (NET)
|
||
|
||
- BSD Socket API 抽象:`net_socket.h/c`
|
||
- select/poll I/O 多路复用:`net_select.h/c`
|
||
- 线程安全通过消息队列(`netMsgQueue`)实现
|
||
- 所有 CH395F 操作在 netTask 中串行处理
|
||
|
||
### 时间子系统
|
||
|
||
- SD2506 RTC 提供初始时间
|
||
- sys_clock 将 RTC 时间转为 Unix epoch 墙钟基准
|
||
- timeSyncTask 通过 TCP 同步墙钟时间
|
||
|
||
## 自动化测试
|
||
|
||
### 启动测试
|
||
|
||
```bash
|
||
# 一键测试:构建 → 串口捕获 → 烧录 → 日志校验
|
||
powershell -ExecutionPolicy Bypass -File test\run_boot_test.ps1
|
||
```
|
||
|
||
退出码:0 = PASS | 1 = FAIL | 2 = 错误
|
||
|
||
### 测试模块
|
||
|
||
| 模块 | 测试文件 | 说明 |
|
||
|------|----------|------|
|
||
| CH395F 硬件 | `ch395f_test_task.c` | SPI 通信、寄存器读写 |
|
||
| NAND Flash | `gd5f_test_task.c` | 页读写、块擦除、ECC |
|
||
| 网络层 | `net_test_task.c` | BSD Socket、TCP/UDP |
|
||
| 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 → 板子) |
|
||
|
||
### 串口调试
|
||
|
||
通过仓库内置 Python 串口助手(`tools/serial_tool/`)自主读取 USART1 串口打印:
|
||
|
||
- 端口配置:`.opencode/serial_config.json`(单一配置源)
|
||
- 用法详见 `docs/测试说明/串口助手使用指南.md`,设计见 `docs/测试说明/串口助手设计说明.md`
|
||
|
||
## 开发规范
|
||
|
||
### 源码编辑安全
|
||
|
||
**铁律**:绝不用 `Get-Content` / `Set-Content` / `cmd` 重写含中文的源码文件,会导致不可逆乱码。
|
||
|
||
- **改代码只用 Edit 工具**(精确子串替换)
|
||
- 发现乱码先评估能否用 Edit 修复,不要急着 `git checkout`
|
||
|
||
### CubeMX 生成文件
|
||
|
||
- `Inc/` 和 `Src/` 中的文件带有 `USER CODE BEGIN`/`END` 标记
|
||
- 自定义代码必须写在这些区域之间
|
||
- `Drivers/BSP/` 下的驱动文件为纯手工代码,不受 CubeMX 保护
|
||
|
||
### 编译验证
|
||
|
||
**所有代码修改后必须编译通过(0 错误 0 警告)才能提交。**
|
||
|
||
### 新增文件
|
||
|
||
新文件需手动添加到 Keil MDK 工程才能编译。
|
||
|
||
### 自动化代码审查(pre-commit)
|
||
|
||
每次 `git commit` 自动执行检查,任一失败即拦截提交:
|
||
|
||
- 行尾空格 / 文件尾换行(自动修复)
|
||
- 大文件 / 冲突标记 / YAML 语法(拦截)
|
||
- **cppcheck 静态分析**:warning / performance / portability / style 四类,发现问题即拦截
|
||
- **代码规范检查**:头文件保护宏、命名(宏大写/`_t` 后缀)、函数注释、default 分支、禁用 strcpy/sprintf/goto/Tab 等(规范 V1.0 可机械校验项)
|
||
- U+FFFD 乱码(拦截,不可逆损坏)
|
||
- commit message 格式(gitlint,拦截)
|
||
|
||
本地钩子脚本:`scripts/check_coding_standard.py`、`scripts/check_mojibake.py`(由 `.pre-commit-config.yaml` 引用)。
|
||
|
||
```bash
|
||
# 新机器启用钩子
|
||
pre-commit install
|
||
# 全库扫描(配置变更后验证)
|
||
pre-commit run --all-files
|
||
```
|
||
|
||
详见 `docs/代码规范/pre-commit使用说明.md` 与 `docs/代码规范/cppcheck使用说明.md`。
|
||
|
||
## 关键文件索引
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `Src/main.c` | 程序入口,CubeMX 生成 + USER CODE 区域 |
|
||
| `Src/freertos.c` | FreeRTOS 任务创建 |
|
||
| `App/app_main.c` | 应用初始化流程编排 |
|
||
| `App/task/net_task.c` | 网络任务主循环 |
|
||
| `App/sys_events.h` | 系统就绪事件定义 |
|
||
| `App/app_cfg.h` | 功能模块编译开关 |
|
||
| `Drivers/BSP/CH395F/ch395f.c` | 以太网控制器驱动 |
|
||
| `Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c` | NAND Flash 驱动 |
|
||
| `Drivers/BSP/NET/net_socket.c` | BSD Socket API |
|
||
| `MDK-ARM/build.bat` | 编译脚本 |
|
||
| `test/run_boot_test.ps1` | 自动化测试脚本 |
|
||
|
||
## 已知问题
|
||
|
||
详见 `docs/问题记录/` 目录:
|
||
- `CH395F_Trap_Records.md` — 以太网控制器已知陷阱
|
||
- `GD5F2GQ5UE_Trap_Records.md` — NAND Flash 已知陷阱
|
||
- `SD2506_Trap_Records.md` — RTC 已知陷阱
|
||
|
||
## 文档
|
||
|
||
| 文档 | 说明 |
|
||
|------|------|
|
||
| `docs/项目架构总览.md` | **项目全景架构**(六层分层 + 任务/就绪屏障 + 启动时序 + 存储/网络/UI 栈 + 目录组织) |
|
||
| `docs/项目部署环境要求.md` | **部署环境要求**(开发机 / 目标板 / 网络与现场 / 远端客户端)+ 分步安装命令 + 下载来源速查 + 验收清单 |
|
||
| `docs/STM32F4-Base存储架构说明.md` | 三层存储软件栈详解(FatFS → dhara FTL → NAND) |
|
||
| `docs/项目启动顺序管理.md` | Event Flags 就绪屏障设计 |
|
||
| `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/UI 设计/UI_设计架构.md` | LVGL UI 系统架构(菜单 / 内容页 / 内存预算) |
|
||
| `docs/UI 设计/菜单页面设计.md` | 菜单导航行为、数据流与内容页设计 |
|
||
| `docs/UI 设计/UI_界面制作流程.md` | 参考图 → 设计规格 → LVGL 代码管线(P0~P4 门禁) |
|
||
| `docs/UI 设计/UI_中文字体生成与配置.md` | 中文字体生成与配置 |
|
||
| `docs/UI 设计/LVGL模拟器部署与使用说明.md` | LVGL PC 模拟器部署 |
|
||
| `docs/UI 设计/UI_自动化测试流程.md` | UI 回归门禁(脚本 + 池水位常量 + 黄金参考更新) |
|
||
| `docs/代码规范/嵌入式C语言代码规范(V1.0).md` | C 语言代码规范 |
|
||
| `docs/代码规范/pre-commit使用说明.md` | 自动化代码审查部署与使用 |
|
||
| `docs/代码规范/cppcheck使用说明.md` | cppcheck 规则、配置与误报抑制 |
|
||
| `docs/测试说明/自动化测试流程.md` | 构建 → 烧录 → 串口校验闭环 |
|
||
| `docs/测试说明/` | 各模块测试指南(CH395F / NAND / FTP / RTC / 串口调试) |
|
||
| `docs/测试说明/测试开发标准流程.md` / `docs/测试说明/测试文档模板规范.md` | 测试开发流程与文档模板 |
|
||
| `docs/问题记录/` | 已知陷阱与解决方案(CH395F / NAND / RTC) |
|
||
| `docs/芯片手册/` | 硬件数据手册 |
|
||
|
||
## 许可证
|
||
|
||
本项目为私有项目,未经授权不得分发。
|