为自建代码目录补齐 README,建立目录级导航体系

- 新增 26 份目录 README:App/(+log,task,util,protocol)、Drivers/BSP/(+8子系统)、
  Src/、Inc/、scripts/、tools/(+6子工具)、test/、MDK-ARM/、simulator/(+sim,tests)
- 每份含:定位、文件清单表、关键约束/陷阱、指向 docs 权威文档
- 第三方库与生成代码目录排除(CMSIS/HAL/Middlewares/Lib/SDL2)
- docs/文档规范.md 新增 §1.1b 代码目录 README 约定;根 README 目录结构加入说明
This commit is contained in:
2026-09-26 12:25:36 +08:00
parent 8d86fb1149
commit 39bd06adea
31 changed files with 1149 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
# Drivers/BSP/CH395F/ — CH395F 以太网控制器驱动
> CH395F 是 SPI 接口的 10/100M 以太网 MAC+PHY 控制器。本目录是其**底层寄存器级驱动**,
> 上层的 BSD Socket 抽象见 `../NET/`。
## 文件一览
| 文件 | 作用 |
|---|---|
| `ch395f.c/h` | SPI 命令收发、寄存器读写、芯片初始化、通道/中断管理 |
## 关键点
- **SPI 接口**:SPI2(PB12 CS / PB13 SCK / PB14 MISO / PB15 MOSI)
- **每次 SPI 事务必须 `ch395f_spi_begin()` / `ch395f_spi_end()` 包裹**
- **SPI 分频系数必须为 8**(PCB 信号完整性约束,**勿"优化"改快**)
- 芯片最多 8 个 socket,本层用**事件中断 + 周期轮询**驱动
- PHY 强制 **100M 全双工**(`net_task` 中配置)
## ⚠️ 改本驱动前必读陷阱(Trap Records)
| Trap | 问题 | 状态 |
|---|---|---|
| Trap 21 | TC-NET-604 "RX 窗口冻结" 判定为**非缺陷**(原报告系测试程序自吞数据 + 判读工具误判) | ✅ 结案 |
| Trap 22 | **快速复连丢 CONNECT/DISCONNECT 中断 → 监听静默死亡**;修复 = `net_reconcile_tick()` 周期对账自愈 | ✅ 已修 |
| Trap 23 | **上传中止后首笔复连被静默截断(≤2048B)并误报成功**;修复 = 异常释放后复监听隔离排空 | ✅ 已修 |
> 完整台账与复现配方见 `docs/问题记录/CH395F_Trap_Records.md`(**改驱动前必读**)。
## 相关文档
- 测试指南:`docs/测试说明/CH395F_Test_Guide.md`
- 上层抽象:`../NET/README.md`
- 台架探针:`MDK-ARM/tcp_reconnect_probe.py`、`MDK-ARM/ftp_abort_probe.py`
+46
View File
@@ -0,0 +1,46 @@
# Drivers/BSP/GD5F2GQ5UE/ — GD5F2GQ5UE SPI NAND 驱动 + FTL
> 256MB SPI NAND Flash 驱动,以及之上的 **FTL(Flash 转换层,`nand_ftl.c`)**——
> 提供逻辑块映射、坏块管理、磨损均衡。再上层是 dhara(坏块/磨损算法)与 FatFs。
## 文件一览
| 文件 | 作用 |
|---|---|
| `gd5f2gq5ue.c/h` | NAND 芯片底层驱动:读/写/擦除、页/块管理、ID 与状态查询 |
| `nand_ftl.c/h` | **FTL 层**:逻辑地址 → 物理地址映射、坏块表、磨损均衡 |
## 硬件接口
- **SPI1**:PE0 CS / PB3 SCK / PB4 MISO / PB5 MOSI / PB8 WP / PE1 HOLD
## 三层存储栈
```
FatFs(文件系统)
↓
dhara(坏块管理 + 磨损均衡算法,Lib/dhara/)
↓
nand_ftl.c(本目录,FTL 适配)
↓
gd5f2gq5ue.c(本目录,芯片驱动)
↓
GD5F2GQ5UE 芯片
```
## ⚠️ 改本驱动前必读陷阱
| 陷阱 | 说明 |
|---|---|
| **FatFs 打开模式** | `FA_OPEN_APPEND`(0x30) **不含 `FA_WRITE`(0x02)**——追加写必须 `FA_WRITE\|FA_OPEN_APPEND`,否则 `f_write` 恒返 `FR_DENIED`(7) |
| **FatFs 文件名** | 严格 8.3 短名、**不得以点开头**(`.fschk` 会 `FR_INVALID_NAME`,纯 RAM 判定不碰盘);自愈逻辑**严禁**把名字类错误归入"卷损坏"触发集 |
| **`f_write` 簇分配失败返回 `FR_OK` + 短写** | 判失败必须**校验写回字节数**(无错误码) |
| **禁用 C 库堆分配** | MicroLIB 堆仅 512B,`malloc` 必返回 NULL;用 `pvPortMalloc/vPortFree` |
> 完整台账见 `docs/问题记录/GD5F2GQ5UE_Trap_Records.md`。
## 相关文档
- 存储架构:`docs/架构设计/STM32F4-Base存储架构说明.md`
- 测试指南:`docs/测试说明/GD5F2GQ5UE_Test_Guide.md`
- 容量恢复:`docs/测试说明/存储维护与容量恢复.md`
+64
View File
@@ -0,0 +1,64 @@
# Drivers/BSP/NET/ — 网络抽象层(BSD Socket API)
> 在 CH395F 硬件驱动之上提供 **BSD Socket 风格 API**,使上层(FTP 服务、时间同步、UI 推流)
> 以标准 socket 语义编程,无需关心芯片细节。核心是**阻塞模型 + 事件驱动 + 周期对账自愈**。
## 文件一览
| 文件 | 作用 |
|---|---|
| `net_socket.c/h` | **BSD Socket API 实现**:`net_socket` / `net_connect` / `net_send` / `net_recv` / `net_close` / `net_listen` / `net_accept`,含 L3 挂起(pending)与错误码 |
| `net_select.c/h` | `select`/`poll` 多路复用(基于芯片中断事件 + 周期轮询) |
| `net_types.h` | 网络层公共类型定义 |
| `net_config.h` | 网络层编译期配置(缓冲区大小、超时、对账周期等) |
| `lftpd/` | **轻量 FTP 服务器**(第三方移植,见其子目录) |
## 核心机制
### 阻塞模型(L3 pending)
- 一期(RECV)已落地:`net_recv` 等支持带超时的阻塞(`pending` 挂起 + tick 唤醒)
- 二期(ACCEPT + SEND)待做 → `docs/待处理内容.md` N-4
### 周期对账自愈(Trap 22 修复)
- `net_reconcile_tick()`(200ms)回读芯片状态修正三类失同步:
本层 ESTABLISHED 而芯片已断 → 断开;本层 LISTENING 而芯片已握手 → 补 accept;
本层 LISTENING 而芯片监听消失 → 重建
- **去抖(连续 2 次)+ 冷却(1s)**——单次状态读的重建动作**必须去抖**,
否则"刚 listen 未生效"瞬态会反复重建直至 `relisten give up`(三监听口全死)
### 异常复监听隔离(Trap 23 修复)
- 异常释放(TIMEOUT)的 socket 复监听前隔离:排空 RX 残渣 + 主动 close + 等 CLOSED
- 400ms 起、800ms 上限强制放行(上限须 < 重试放弃时限 2000ms)
- 仅异常路径生效,正常 FIN 路径零改动
### 错误码(E-03 修复)
- **按任务隔离**:`s_net_errno_slots[8]`(每槽 `{任务句柄, err}`),替代原全局 `s_net_errno`
- `net_get_errno()` 只读本任务槽位,**对外语义不变**(成功不清零)
## 依赖关系
```
上层(FTP / timeSync / UI 推流)
↓ BSD Socket API
net_socket.c ←→ net_select.c
↓ ch395f_* 接口
Drivers/BSP/CH395F/
```
## ⚠️ 改本模块前必读
- 就绪屏障位(`SYS_EVT_NET_READY` 等)等待必须 `osFlagsNoClear`,**不能用默认消费型**
- 每次 CH395F SPI 事务须 `ch395f_spi_begin()/end()` 包裹
- **改任何自愈/重建逻辑必须去抖**,否则会引发重建风暴
- 相关陷阱:`docs/问题记录/CH395F_Trap_Records.md` Trap 21/22/23
## 相关文档
- 上层用法:`docs/网络/BSD_Socket_API_使用指南.md`
- 内部调用关系:`docs/网络/BSD_Socket_API_函数调用关系.md`
- 演进方案:`docs/问题记录/Net层阻塞模型业界对照与演进方案.md`
- 测试:`docs/测试说明/CH395F_Test_Guide.md`、`docs/测试说明/FTP_Test_Guide.md`
+41
View File
@@ -0,0 +1,41 @@
# Drivers/BSP/NET/lftpd/ — 轻量 FTP 服务器(第三方移植)
> ⚠️ **第三方开源库移植**(lftpd,许可证见 [`LICENSE.txt`](LICENSE.txt)),**非自研代码**。
> 本目录 README 仅说明其在本项目中的**定位与对接方式**;库内部逻辑请参考上游。
## 文件一览
| 文件 | 作用 |
|---|---|
| `lftpd.c/h` | FTP 服务器主体(命令解析、状态机、数据通道) |
| `lftpd_io.c` | I/O 适配层(**本项目对接 FatFs 的关键所在**) |
| `lftpd_inet.c` | 网络适配(对接本项目的 BSD Socket API) |
| `lftpd_log.c` | 日志输出适配 |
| `lftpd_string.c` | 字符串工具 |
| `private/*.h` | 内部头文件 |
| `LICENSE.txt` | 上游许可证 |
## 在本项目中的对接
```
ftpTask(App/ 侧创建)
↓ 等待 SYS_EVT_NET_READY + SYS_EVT_STORAGE_READY(osFlagsNoClear!)
lftpd(本目录)
├── lftpd_inet.c → Drivers/BSP/NET/net_socket.c(BSD Socket API)
└── lftpd_io.c → Lib/FatFs(文件读写)
```
## ⚠️ 项目相关注意
- **ftpTask 就绪屏障**:`osEventFlagsWait` 等两位就绪必须加 `osFlagsNoClear`,
否则位被先到的消费者清掉 → FTP 21 端口静默不监听(无日志无报错)
- **lftpd 大局部缓冲**:已按 `docs/内存管理/RAM使用分析与优化方案.md` §1.4 静态化 9 处
大局部缓冲(BSS +4.6KB),使 ftpTask 栈峰值从 3480B 降到 1184B——**勿改回局部变量**
- **上传中止截断**:FTP STOR 中途断开后首笔复连被截断(Trap 23)已在 `net_socket.c` 侧修复
- 本目录受 pre-commit 的**部分排除**(第三方代码)
## 相关文档
- 测试指南:`docs/测试说明/FTP_Test_Guide.md`
- 台架探针:`MDK-ARM/ftp_abort_probe.py`、`MDK-ARM/ftp_freeze_probe.py`
- 内存优化:`docs/内存管理/RAM使用分析与优化方案.md` §1.4
+36
View File
@@ -0,0 +1,36 @@
# Drivers/BSP/NETCFG/ — 网络配置
> 网络参数的**加载 / 保存 / 旧档迁移**(IP、掩码、网关等)。
> 本模块是**网络配置的持久化层**,与 `App/cfg_file.c`(配置引擎)配合工作。
## 文件一览
| 文件 | 作用 |
|---|---|
| `net_cfg.c/h` | 网络配置加载(`net_cfg_load`)/ 保存(`net_cfg_save_run`)+ RAM 副本管理 |
| `net_cfg_legacy.c/h` | **旧版配置档迁移**(首启时把旧格式转换为当前格式) |
## 工作流
```
defaultTask:net_cfg_load(含旧档迁移)→ 置 STORAGE_READY
↓ (网络配置在屏障前已加载)
netTask:只读 RAM 副本 → net_stack_bring_up(不在 netTask 里读盘)
↓
UI 改配置 → SYS_EVT_CFG_SAVE 事件 → defaultTask 执行 net_cfg_save_run + cfg_file_poll
↓
netTask 消费 SYS_EVT_NET_RECONFIG → 立即重建网络(新 IP 免重启生效)
```
## ⚠️ 约束
- **网络配置在 `STORAGE_READY` 屏障之前由 defaultTask 加载完毕**,netTask 只读 RAM 副本
- UI 保存请求经 `SYS_EVT_CFG_SAVE` 事件交由 **defaultTask**(配置引擎属主)执行,
**netTask/uiTask 不得直接触碰配置引擎**(`cfg_file` 是静态态、单任务收敛)
- 网络代次号(generation)用于各 TCP 服务判断是否需重建监听
## 相关文档
- `docs/子系统设计/网络配置说明.md` — 网口设置页与即时生效机制
- `docs/子系统设计/配置文件设计说明.md` — 配置引擎
- `docs/架构设计/项目启动顺序管理.md` — 就绪屏障
+46
View File
@@ -0,0 +1,46 @@
# Drivers/BSP/ — 板级支持包(纯手工自研代码)
> **本目录全部为手工编写的板级驱动与中间层**(非 CubeMX 生成、非第三方库、非 ST HAL)。
> 每个芯片/子模块一个子目录。改驱动前**必读对应模块的 Trap Records**(见下)。
## 子模块一览
| 目录 | 芯片/模块 | 接口 | 职责 | 关键文档 |
|---|---|---|---|---|
| `CH395F/` | CH395F 以太网控制器 | SPI2 | 以太网 MAC/PHY 控制器底层驱动 | `docs/问题记录/CH395F_Trap_Records.md` |
| `GD5F2GQ5UE/` | GD5F2GQ5UE SPI NAND | SPI1 | NAND 驱动 + FTL(`nand_ftl.c`) | `docs/问题记录/GD5F2GQ5UE_Trap_Records.md` |
| `TPAFE5160/` | TPAFE5160 高精度 ADC | 并行 16 位 | ADC 采样驱动(CONVST/BUSY 时序) | — |
| `SD2506/` | SD2506 RTC | I2C | 实时时钟驱动 | `docs/问题记录/SD2506_Trap_Records.md` |
| `RS485/` | RS-485 半双工 | UART5 | 收发方向控制(DE 引脚)+ 时序 | — |
| `NET/` | BSD Socket 网络抽象层 | — | Socket API + select + 轻量 FTP 服务器 | `docs/网络/`、`docs/问题记录/Net层阻塞模型业界对照与演进方案.md` |
| `NETCFG/` | 网络配置 | — | `/config.ini` 网络段的加载/保存 + 旧档迁移 | `docs/子系统设计/网络配置说明.md` |
| `UI/` | LVGL UI 组件 | — | 菜单/内容页/组件/中文字体 | `docs/UI设计/` |
## 根级文件
| 文件 | 作用 |
|---|---|
| `dbg_log.h` | **调试日志宏**(`DBG_INFO` 等),编译期开关 |
| `dbg_cfg.h` | 调试配置项 |
## 子模块 README
- [`NET/README.md`](NET/README.md) — 网络抽象层(Socket / select / FTP)
- [`UI/README.md`](UI/README.md) — LVGL UI 组件
## ⚠️ 改驱动前必读(踩坑速查)
| 模块 | 陷阱 |
|---|---|
| CH395F | SPI 事务须 `ch395f_spi_begin()/end()` 包裹;分频系数**必须为 8**(PCB 约束,勿"优化");快速复连会丢中断致监听死亡(Trap 22 已修);上传中止后首笔复连截断(Trap 23 已修) |
| GD5F2GQ5UE | FatFs 移植版打开模式陷阱(`FA_OPEN_APPEND` 不含写位);文件名严格 8.3 短名、不得以点开头;`f_write` 簇分配失败返 `FR_OK` + 短写,须校验字节数 |
| NET | 就绪屏障位必须 `osFlagsNoClear`;`s_net_errno` 已按任务隔离(勿改回全局) |
| 通用 | 自研代码**禁用 C 库堆分配**(MicroLIB 堆仅 512 B),动态内存只用 `pvPortMalloc/vPortFree` |
> 完整平台约束见根 `AGENTS.md`「平台约束」章,以及各模块的 Trap Records。
## 相关文档
- 架构全景:`docs/架构设计/项目架构总览.md`
- 存储栈:`docs/架构设计/STM32F4-Base存储架构说明.md`
- 测试指南:`docs/测试说明/*_Test_Guide.md`
+26
View File
@@ -0,0 +1,26 @@
# Drivers/BSP/RS485/ — RS-485 半双工通信驱动
> RS-485 半双工收发驱动:DE(发送使能)方向控制 + 收发时序管理。
> 配合 `App/task/rs485_task.c` 与 `App/util/crc.c`、`App/util/ringbuf.c` 组成完整协议栈。
## 文件一览
| 文件 | 作用 |
|---|---|
| `rs485.c/h` | 驱动初始化、DE 引脚方向切换、收发缓冲管理 |
## 硬件接口
- **UART5**:PC12 TX / PD2 RX / **PD0 DE**(发送使能,低=接收、高=发送)
## 关键点
- **半双工**:发送前拉高 DE 并等待发送完成,发送后立即拉低 DE 切回接收
- 方向切换时序与波特率相关——切换过快会截断末字节,过慢会阻塞总线
- 接收经 `ringbuf`(SPSC 无锁环形缓冲)缓冲,供协议层解析
## 相关文档
- 协议工具:`App/util/crc.c`、`App/util/ringbuf.c`
- 任务实现:`App/task/rs485_task.c`
- 硬件引脚:根 `README.md`「外设接口」
+28
View File
@@ -0,0 +1,28 @@
# Drivers/BSP/SD2506/ — SD2506 RTC 驱动
> SD2506 实时时钟芯片驱动(I2C 接口):时间读写、温度、电池状态、诊断。
> 是 `sys_clock`(墙钟)的**硬件时间基准**。
## 文件一览
| 文件 | 作用 |
|---|---|
| `sd2506.c/h` | RTC 初始化、时间读写、ID/温度/电池读取、诊断 |
## 硬件接口
- **I2C**(具体引脚见根 `README.md` 与 `Inc/main.h`)
## 关键点
- **时间子系统优先初始化**:`app_main_init` 中最先调用 `sd2506_init` +
`sys_clock_init`,使后续日志都带时间戳
- 开机执行 **SD2506 诊断**(ID / 时间 / 温度 / 电池),失败触发"时钟芯片异常"自检上报
- RTC 故障时 `sys_clock_init` **降级到默认时间基准并返回 -1**
- 时间源同步由 `App/time_sync.c`(timeSyncTask)负责
## 相关文档
- 墙钟维护:`docs/子系统设计/系统墙钟时间维护说明.md`
- 测试指南:`docs/测试说明/SD2506_Test_Guide.md`
- 陷阱台账:`docs/问题记录/SD2506_Trap_Records.md`
+32
View File
@@ -0,0 +1,32 @@
# Drivers/BSP/TPAFE5160/ — TPAFE5160 高精度 ADC 驱动
> TPAFE5160 是**并行 16 位**接口的高精度 ADC。本目录为寄存器级驱动:
> 转换启动(CONVST)、忙信号(BUSY)、数据读取(RD)时序管理。
## 文件一览
| 文件 | 作用 |
|---|---|
| `tpafe5160.c/h` | ADC 初始化、转换启动(轮询 + 中断)、16 位并行数据读取 |
## 硬件接口
- **并行 16 位**:PG0–PG15 数据总线 / **PD3 RD**(读选通)/ **PD4 CONVST**(转换启动)/ **PD7 BUSY**(转换中)
- 部分引脚为 GPIO 模拟时序(非硬件 SPI/FSMC)
## 关键点
- **首次转换在 `app_main_init` 末尾由 `tpafe5160_start_conv_irq` 启动**(中断驱动)
- 采样数据由 `App/task/adc_task.c` 消费处理
- CONVST→BUSY→RD 三段时序对**建立/保持时间敏感**,改动需对照芯片手册
- ⚠️ 本项目 ADC 相关功能**新增任务/缓冲前须核算 RAM**(见 `docs/内存管理/`)
## 已知问题
- `docs/问题记录/TPAFE5160.md` 有 **16 张图片断链**(文档引用了但图从未入库)——已登记,暂缓处理
## 相关文档
- 芯片手册转录:`docs/芯片手册/TPAFE5160.md`(注:其配图有断链)
- 任务实现:`App/task/adc_task.c`
- 硬件引脚:根 `README.md`「外设接口」
+57
View File
@@ -0,0 +1,57 @@
# Drivers/BSP/UI/ — LVGL UI 组件
> 基于 LVGL 的界面实现:菜单树、内容页、通用组件、中文字库、待机页。
> **与 PC 模拟器共用同一套 UI 源码**(`simulator/` 只提供平台层)。
## 结构
### 核心 / 框架
| 文件 | 作用 |
|---|---|
| `ui_port.c/h` | **LVGL 移植层**:显示驱动、输入设备、tick 注册 |
| `ui_menu.c/h` | 菜单框架(树结构与导航) |
| `ui_menu_view.c/h` | 菜单视图渲染 |
| `ui_menu_tab.c/h` | 页签组件 |
| `ui_deco.c/h` | 界面装饰元素(图标、边框等) |
| `ui_standby.c/h` | 待机页 |
| `ui_pwd_def.h` | 密码页默认值定义 |
| `ui_font_cn_12.c` | **中文字库**(由 `tools/font_gen/` 生成,勿手改) |
### 内容页
| 文件 | 作用 |
|---|---|
| `ui_content_page.c/h` | 内容页框架 |
| `ui_page_ac.c/h` | 交流量页 |
| `ui_page_dc.c/h` | 直流量页 |
| `ui_page_device_info.c/h` | 设备信息页 |
| `ui_page_net_cfg.c/h` | 网口设置页 |
| `ui_page_password.c/h` | 密码页 |
| `ui_page_runlog.c/h` | 运行日志页 |
| `ui_page_selftest.c/h` | 自检页 |
### 数据汇入(推流)
| 文件 | 作用 |
|---|---|
| `ui_net_sink.c/h` | 远端显示总线(RemoDispBus)数据汇入口 |
| `ui_net_sink_backend.h` | 后端抽象接口(MCU / 模拟器分别实现) |
| `ui_net_sink_backend_mcu.c` | MCU 端后端实现 |
## ⚠️ 编码注意(本目录含中文字符串)
- 本目录文件**带 UTF-8 BOM**(`.c` 内含中文字符串字面量,BOM 使 ARMCC 按 UTF-8 解码)
- **Edit 工具会剥掉 BOM**:改完必须核对并按原样补回 3 字节 `EF BB BF`,
否则 ARMCC 改按 CP936 解读 → `#870-D: invalid multibyte character sequence`
- UI 改动一律走 **`ui-verify` skill 五步门禁**
- 含新汉字的文案提交前先跑 **`font-regen` skill** 重生成 `ui_font_cn_12.c`
## 相关文档
- UI 架构:`docs/UI设计/UI_设计架构.md`
- 菜单设计:`docs/UI设计/菜单页面设计.md`、`docs/UI设计/内容页架构.md`
- 字体:`docs/UI设计/UI_中文字体生成与配置.md`
- 模拟器:`docs/UI设计/LVGL模拟器部署与使用说明.md`
- 自动化测试:`docs/UI设计/UI_自动化测试流程.md`
- 协议:`docs/UI设计/RemoDispBus协议与接收设计说明.md`