From 229b961f8e0e2845abe38ff568208042e6b33e5f Mon Sep 17 00:00:00 2001 From: xiao Date: Fri, 17 Apr 2026 07:07:43 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=9B=BA=E5=8C=96ARP=E4=B8=8EICMP?= =?UTF-8?q?=E8=81=94=E8=B0=83=E7=BB=8F=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 工程调试指南.md | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/工程调试指南.md b/工程调试指南.md index db2dc81..3f9d8e1 100644 --- a/工程调试指南.md +++ b/工程调试指南.md @@ -206,6 +206,93 @@ void vApplicationMallocFailedHook(void) 2. TCP Server 是否在指定端口监听 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] 联调指导 @@ -256,6 +343,10 @@ void vApplicationMallocFailedHook(void) 4. 不要在基础寄存器读写尚不可信时,直接调高层业务 5. 不要在 ISR 中执行复杂 SPI 事务或调用阻塞 API 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 层 ---