Files
STM32F4-Base/README.md
T
2026-08-31 17:09:59 +08:00

12 KiB
Raw Blame History

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 半双工通信

项目架构

┌─────────────────────────────────────────────────────────────┐
│                    应用层 (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)                     │
└─────────────────────────────────────────────────────────────┘

启动流程

main.c
  ├─ HAL_Init()
  ├─ SystemClock_Config()           // 168MHz 系统时钟
  ├─ MX_GPIO/DMA/UART/SPI/I2C_Init()  // CubeMX 外设初始化
  ├─ app_main_init()                // 应用层初始化(时间→RS485→NAND→ADC→RTC)
  │   ├─ sd2506_init() + sys_clock_init()  // 时间子系统优先
  │   ├─ rs485_init()
  │   ├─ gd5f2gq5ue_init()
  │   └─ tpafe5160_init()
  ├─ 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 组件
│   ├── 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     # 日志校验脚本
│   ├── serial_capture.ps1 # 串口捕获脚本
│   ├── 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 # 存储性能测试
├── docs/                   # 项目文档
│   ├── 问题记录/           # 已知陷阱与解决方案
│   ├── 测试说明/           # 测试指南
│   └── 芯片手册/           # 硬件数据手册
├── tools/                  # 开发工具
│   └── font_gen/          # 中文字体生成工具
├── STM32F407-Demo.ioc     # CubeMX 工程文件
└── AGENTS.md              # AI 开发规范

构建系统

环境要求

  • Keil MDK-ARM v5 (ARMCC 编译器)
  • Python 3(测试脚本)
  • ST-Link 或兼容调试器

编译

# 方式一:命令行编译(推荐)
MDK-ARM\build.bat

# 方式二:Keil IDE
# 打开 MDK-ARM\STM32F407-Demo.uvprojx → Build (F7)

退出码:0 = 成功 | 1 = 有警告 | 2+ = 错误

编译日志:MDK-ARM/build_log.txt

烧录

MDK-ARM\download.bat

驱动开发指南

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 同步墙钟时间

自动化测试

启动测试

# 一键测试:构建 → 串口捕获 → 烧录 → 日志校验
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 读写速度

串口调试

通过 serial-mcp-server 自主读取 USART1 串口打印:

  • 端口配置:.opencode/serial_config.json
  • 详见 docs/测试说明/serial-mcp-server_串口调试.md

开发规范

源码编辑安全

铁律:绝不用 Get-Content / Set-Content / cmd 重写含中文的源码文件,会导致不可逆乱码。

  • 改代码只用 Edit 工具(精确子串替换)
  • 发现乱码先评估能否用 Edit 修复,不要急着 git checkout

CubeMX 生成文件

  • Inc/ 和 Src/ 中的文件带有 USER CODE BEGIN/END 标记
  • 自定义代码必须写在这些区域之间
  • Drivers/BSP/ 下的驱动文件为纯手工代码,不受 CubeMX 保护

编译验证

所有代码修改后必须编译通过(0 错误 0 警告)才能提交。

新增文件

新文件需手动添加到 Keil MDK 工程才能编译。

关键文件索引

文件 说明
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 — Event Flags 就绪屏障设计
  • docs/STM32F4-Base存储架构说明.md — 三层存储软件栈详解
  • docs/嵌入式C语言代码规范(V1.0).md — 代码规范
  • docs/测试说明/自动化测试流程.md — 测试流程说明
  • docs/芯片手册/ — 硬件数据手册

许可证

本项目为私有项目,未经授权不得分发。