TCP可以正常使用
This commit is contained in:
59
AGENTS.md
59
AGENTS.md
@@ -13,6 +13,13 @@ STM32F4-Base/
|
||||
├── Drivers/
|
||||
│ ├── BSP/
|
||||
│ │ ├── CH395F/ # CH395F 以太网芯片驱动(手写)
|
||||
│ │ ├── NET/ # BSD Socket API 网络抽象层(手写)
|
||||
│ │ │ ├── net_config.h # 网络配置宏定义
|
||||
│ │ │ ├── net_types.h # 类型定义、地址结构、Socket 控制块
|
||||
│ │ │ ├── net_socket.h # BSD Socket API 头文件
|
||||
│ │ │ ├── net_socket.c # API 核心实现 + 状态机
|
||||
│ │ │ ├── net_select.h # select/poll API 头文件
|
||||
│ │ │ └── net_select.c # select/poll 实现
|
||||
│ │ ├── GD5F2GQ5UE/ # GD5F2GQ5UE NAND Flash 驱动(手写)
|
||||
│ │ │ ├── gd5f2gq5ue.h/c # 底层 SPI 驱动
|
||||
│ │ │ ├── fal_flash_gd5f2gq5ue.c # FAL 设备适配层
|
||||
@@ -37,6 +44,8 @@ STM32F4-Base/
|
||||
|---|---|
|
||||
| `Src/main.c` | 程序入口,初始化序列及主循环 |
|
||||
| `Drivers/BSP/CH395F/ch395f.c/h` | CH395F 以太网芯片 SPI 驱动 |
|
||||
| `Drivers/BSP/NET/net_socket.c/h` | BSD Socket API 网络抽象层 |
|
||||
| `Drivers/BSP/NET/net_select.c/h` | select/poll I/O 多路复用 |
|
||||
| `Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c/h` | GD5F2GQ5UE NAND Flash SPI 驱动 |
|
||||
| `Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c` | FAL 设备适配层 |
|
||||
| `Drivers/BSP/TPAFE5160/tpafe5160.c/h` | TPAFE5160 ADC 并行接口驱动 |
|
||||
@@ -52,6 +61,29 @@ STM32F4-Base/
|
||||
- C 标准:C99
|
||||
- 全局宏定义:`USE_HAL_DRIVER, STM32F407xx`
|
||||
|
||||
### 命令行编译(Agent 使用)
|
||||
|
||||
修改代码后必须执行命令行编译验证,编译脚本位于 `MDK-ARM/build.bat`:
|
||||
|
||||
```
|
||||
cmd /c "cd /d "工作目录" && build.bat"
|
||||
```
|
||||
|
||||
实际执行示例(从项目根目录):
|
||||
|
||||
```
|
||||
cmd /c "cd /d "D:\Code\DTU 程序\STM32F4-Base\MDK-ARM" && build.bat"
|
||||
```
|
||||
|
||||
**编译结果判读:**
|
||||
- 退出码 0:无错误无警告,编译成功
|
||||
- 退出码 1:有警告无错误,编译失败(警告不可接受,需修复)
|
||||
- 退出码 2+:编译失败,需查看 `MDK-ARM/build_log.txt` 定位错误
|
||||
|
||||
**UV4.exe 路径:** `C:\Keil_v5\UV4\UV4.exe`
|
||||
**工程文件:** `MDK-ARM/STM32F407-Demo.uvprojx`
|
||||
**目标名称:** `STM32F407-Demo`
|
||||
|
||||
## 硬件配置
|
||||
|
||||
- **主频:** HSE 25MHz → PLL 168MHz (4/168/2)
|
||||
@@ -96,6 +128,11 @@ HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_USART1_UART_Init()
|
||||
- **`SET_PHY` 必须在 `INIT_CH395` 之后**,它会复位 MAC/PHY 建立物理链路,不影响已锁定的协议栈参数
|
||||
- **`CMD_PING_ENABLE` 不需要显式调用**,INIT 后默认可用
|
||||
- 每次 SPI 事务需调用 `ch395f_spi_begin()` / `ch395f_spi_end()` 包裹
|
||||
- **大数据量收发使用 SPI2 DMA**:`ch395f_write_send_buf()` 和 `ch395f_read_recv_buf()` 已改造为 DMA 批量传输(DMA1_Stream3 RX, DMA1_Stream4 TX),命令和配置操作仍使用逐字节轮询
|
||||
- DMA 缓冲区:`s_spi2_dma_tx_buf[1500]` / `s_spi2_dma_rx_buf[1500]`,4 字节对齐
|
||||
- **TCP 重传参数**:`SET_RETRAN_COUNT`(默认12次,最大20)和 `SET_RETRAN_PERIOD`(默认500ms,最大1000ms)必须在 `INIT_CH395` 之前设置,总重传时间 = 次数 × 周期
|
||||
- **KeepAlive 参数必须为 500ms 的倍数**:`SET_KEEPALIVE_IDLE`(默认20000ms)、`SET_KEEPALIVE_INTVL`(默认15000ms)单位为 ms,且 IDLE 必须 > INTVL,均为 500 的倍数;传入非 500 倍数的值会导致未定义行为(CH395F 内部定时器异常,TCP 连接几秒内 TIMEOUT)
|
||||
- **KeepAlive 默认关闭**:需在 `SINT_STAT_CONNECT` 后调用 `ch395f_set_keepalive_enable(sock, 1)` 启用
|
||||
|
||||
## GD5F2GQ5UE 驱动关键点
|
||||
|
||||
@@ -124,6 +161,28 @@ HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_USART1_UART_Init()
|
||||
- 读取时序:168MHz 下 GPIO 写操作 + 5个 NOP (~30ns) 覆盖 t10=22ns 和 t14=21ns 要求
|
||||
- 硬件 RANGE 接 GND → ±5V 量程,LSB=152.59µV
|
||||
|
||||
## NET 网络层关键点
|
||||
|
||||
- **文件结构**:`Drivers/BSP/NET/` 下包含 net_config.h、net_types.h、net_socket.h/c、net_select.h/c
|
||||
- **使用前必须调用** `net_init(ip, mask, gateway)` 初始化网络子系统
|
||||
- **主循环必须调用** `net_poll()` 轮询所有 Socket 状态,处理中断事件
|
||||
- **TCP Server 多连接模式**:1 个监听 Socket + 最多 7 个数据 Socket
|
||||
- **select/poll 支持**:`net_select()` 和 `net_poll_events()` 用于 I/O 多路复用
|
||||
- **事件回调**:可通过 `net_set_event_cb()` 注册连接/断开/数据到达等事件回调
|
||||
- **非阻塞模式**:`net_recv()` 使用 `NET_MSG_DONTWAIT` 标志,或使用 select/poll
|
||||
- **字节序转换**:使用 `net_htons()/net_ntohs()/net_htonl()/net_ntohl()` 进行主机序/网络序转换
|
||||
- **IP 地址转换**:`net_inet_addr("192.168.1.100")` 字符串转网络序,`net_inet_ntoa()` 反向转换
|
||||
- **注意**:新文件需手动添加到 Keil MDK 工程中才能编译
|
||||
- **RECV 中断是电平触发的**:`net_poll()` 中 `do { ... } while(0)` 只处理一批中断,由主循环读取数据,避免无限循环导致主循环饿死
|
||||
- **TCP Server 多连接模式**:Socket 0 专职监听,Socket 1~7 自动分配
|
||||
- **多连接模式初始化顺序(关键!遗漏将导致 TCP 连接失败)**:
|
||||
1. `ch395f_set_fun_para(0x02)` — 启用多连接(在 `INIT_CH395` 之前)
|
||||
2. `ch395f_init()` — 协议栈初始化
|
||||
3. Socket 0: `SET_PROTO_TCP → SET_SOUR_PORT → OPEN → TCP_LISTEN`
|
||||
4. **Socket 1~7: `SET_PROTO_TCP → SET_SOUR_PORT(相同端口)`(不 OPEN!)**
|
||||
- 如果不配置数据 Socket 的协议类型和源端口,CH395F 不知道哪些 Socket 可用于多连接分配,客户端连接会被静默拒绝(无 CONNECT 中断)
|
||||
- **TCP Server 单连接模式**:Socket 先 `OPEN` → `SET_PROTO_TCP` → `SET_SOUR_PORT` → `OPEN` → `TCP_LISTEN`;收到 `SINT_STAT_CONNECT` 后 Socket 自动切换为数据通道;`DISCONNECT`/`TIMEOUT` 后需重新 `OPEN` → `TCP_LISTEN`
|
||||
|
||||
## 已知问题
|
||||
|
||||
### CH395F 与 RTL8305NBI 自动协商不兼容
|
||||
|
||||
Reference in New Issue
Block a user