docs: 固化ARP与ICMP联调经验

This commit is contained in:
2026-04-17 07:07:43 +08:00
parent 4970f17254
commit 229b961f8e
+91
View File
@@ -206,6 +206,93 @@ void vApplicationMallocFailedHook(void)
2. TCP Server 是否在指定端口监听 2. TCP Server 是否在指定端口监听
3. TCP Client 是否成功连接远端 3. TCP Client 是否成功连接远端
### 6.5 P3.5:确认 ARP / ICMP 基础网络可达
在继续 TCP 联调前,建议先把 `ARP + ping(ICMP)` 跑通。对于当前 `CH390 + lwIP + FreeRTOS` 架构,这一步不是可选项,而是 TCP 可达之前必须成立的网络基线。
#### 6.5.1 推荐最小验证顺序
1. 先确认板卡 IP、掩码、MAC 与 PC 所在网段一致
2. 上电后先观察 RTT,确认 `ETH init: done` 已出现
3. 在 PC 侧执行一次 `ping <板卡IP>`,同时开启 Wireshark 抓包
4. 先看是否出现发往板卡 IP 的 ARP request,再看设备是否回 ARP reply
5. ARP 正常后,再看是否出现 ICMP echo request / echo reply 成对出现
#### 6.5.2 当前工程推荐观察点
如果网络基础链路有疑问,建议按以下分层观察,不要只看某一层:
1. **raw RX 层**CH390 是否确实收到了以太网帧
2. **Ethernet demux 层**`ethernet_input()` 是否识别到 `ETHTYPE_ARP` / `ETHTYPE_IP`
3. **协议处理层**`etharp_input()` / `ip_input()` 是否真正进入
4. **协议发包层**:lwIP 是否已经生成待发送的 ARP reply / ICMP reply
5. **驱动发送层**`low_level_output()` / CH390 TX 是否真正把帧送出
这次 bring-up 证明,`raw RX 正常` 并不等于 `lwIP 已真正处理该帧`。如果只看到底层收到了包,就直接假设协议栈一定会回复,通常会把排查方向带偏。
#### 6.5.3 这次 ARP / ICMP bring-up 的关键结论
本轮调试中,最终根因位于:
- `Drivers/LwIP/src/netif/ethernet.c`
问题本质是:
1. `ethernet_input()``ETHTYPE_ARP` 分支中,曾直接调用 `etharp_input(p, netif)`
2.`etharp_input()` 要求 `p->payload`**ARP 头** 开始,而不是从 Ethernet 头开始
3. 因此如果没有先执行:
```c
pbuf_remove_header(p, SIZEOF_ETH_HDR)
```
则 ARP 包虽然被收到了,但会在 `etharp_input()` 的早期校验中被静默丢弃,最终表现为:
1. Wireshark 能看到 PC 发来的 ARP request
2. 板子侧底层收包计数在增长
3. 但设备始终不回 ARP reply
4. ping 也自然不会成功
当前应保留的正确处理方式如下:
```c
case ETHTYPE_ARP:
if (netif->flags & NETIF_FLAG_ETHARP) {
if (pbuf_remove_header(p, SIZEOF_ETH_HDR)) {
pbuf_free(p);
return ERR_OK;
}
etharp_input(p, netif);
} else {
pbuf_free(p);
}
return ERR_OK;
```
#### 6.5.4 为什么这类问题容易漏看
这类问题常见但隐蔽,原因通常有三点:
1. 根因非常小,外在表现却像“整个发送链路都坏了”
2. 多个低层信号可能同时正常,容易误导为 SPI / TX / CH390 初始化问题
3. `rx ok``ARP 帧计数在涨``链路已 up` 都不代表协议层一定接受了该帧
因此,后续遇到“收得到包但就是不回”的问题时,优先检查:
1. 传给上层协议处理函数时,`pbuf->payload` 是否已经对齐到正确协议头
2. glue-layer 是否和 lwIP 原生调用约定一致
3. 观察点是否已经覆盖到 `demux -> protocol handler -> linkoutput` 这一整条链
#### 6.5.5 建议保留的最小验收标准
在认定网络基线“已经打通”之前,至少应满足:
1. Keil 工程可稳定构建通过
2. 上电后可稳定看到网络初始化完成日志
3. Wireshark 中能看到设备对本机 ARP request 做出 reply
4. PC 对设备 `ping` 时,能看到 ICMP echo request / reply 成对出现
5. RTT 中无 `STACK OVERFLOW``MALLOC FAILED`、异常 trap 等故障信号
--- ---
## 7. MUX / NET / LINK[idx] 联调指导 ## 7. MUX / NET / LINK[idx] 联调指导
@@ -256,6 +343,10 @@ void vApplicationMallocFailedHook(void)
4. 不要在基础寄存器读写尚不可信时,直接调高层业务 4. 不要在基础寄存器读写尚不可信时,直接调高层业务
5. 不要在 ISR 中执行复杂 SPI 事务或调用阻塞 API 5. 不要在 ISR 中执行复杂 SPI 事务或调用阻塞 API
6. 不要忽视 `configCHECK_FOR_STACK_OVERFLOW` 报告 6. 不要忽视 `configCHECK_FOR_STACK_OVERFLOW` 报告
7. 不要把“底层已经收到 ARP 包”等同于“lwIP 一定已经正确处理 ARP 包”
8. 不要忽略 glue-layer 对 `pbuf->payload` 起始位置的约定,特别是 `Ethernet header -> ARP/IP header` 的切换
9. 不要在 ARP / ICMP 还没闭环前,就直接怀疑 TCP Server / TCP Client 逻辑
10. 不要在没有抓包和分层观测点的情况下,只凭单一日志就断言故障位于 TX 或 SPI 层
--- ---