F28388D以太网通信实战:从EMAC到LWIP协议栈移植
2026/9/20 12:31:28 网站建设 项目流程

直接说结论:如果你手里正好有一块YXDSP-F28388D开发板,想让它通过以太网和上位机通信,又不想被Ethernet这一大坨协议栈劝退,那这篇文章就是给你写的。F28388D这颗芯片比较特殊,它虽然挂着DSP的名头,但内部塞了一颗Arm Cortex-M9内核,真正跑LWIP、跑Ethernet协议栈的其实是这颗M核,而不是我们熟悉的C28x DSP核。项目标题里写的“从EMAC硬件到LWIP协议栈移植”,本质上就是在C2000生态里把TI官方给的lwip例程跑通,再根据自己的板子改底层PHY配置和引脚复用,最终实现一个能ping通、能收发UDP/TCP数据的嵌入式以太网节点。

这块板子我断断续续调了两周,中间踩了不少坑,尤其是EMAC的时钟配置和PHY地址这俩地方,坑得我一度怀疑是板子硬件坏了。后面我把整个过程的硬件原理、环境搭建、LWIP移植步骤、常见问题排查全部整理出来,想着直接写成一篇可以直接照着抄的记录,给同样在用F28388D做网络通信的朋友做个参考。

1. 项目整体设计与实现思路拆解

1.1 为什么选F28388D做以太网通信

先捋一下F28388D这颗芯片的定位。它是TI C2000系列里目前最高端的一颗,主频跑到200MHz的C28x DSP核,另外还带一个独立的Arm Cortex-M9核,我记得官方叫法是CM核,频率能上到100MHz以上。为什么以太网非要挂在CM核上而不是C28x上?这里有个很现实的原因:C28x的指令集和内存模型不太适合跑LWIP这种动辄几千行的通用网络协议栈,而且Ethernet MAC控制器本身是挂在CM核的外设总线上的,所以TI的设计就是把网络协议栈直接放CM核,两个内核之间再通过IPC(核间通信)来交换数据。

YXDSP-F28388D这块开发板用的是TI原厂的F28388D,板载资源看着就让人流口水:板载XDS110仿真器、双路以太网接口(实际板子焊了一路PHY,另一路预留)、CAN/CANFD、多路ADC、EtherCAT的从站接口也引出来了。说句实在话,如果是做工业控制上位机通信,或者做伺服驱动器、PLC主站这样的设备,选F28388D是非常合适的,一颗芯片解决控制和通信两件事,不用再单独挂一颗MCU去处理以太网和协议栈了。

1.2 博文参考的整体方案选型

我最终采用的方案是:CM核裸机(无操作系统)跑TI官方提供的LWIP移植代码,C28x核通过IPC与CM核通信,实现DSP控制数据和网络数据的双向透传。具体分工是这样:

  • C28x核:负责伺服/PID控制等实时任务,以及ADC采样、PWM输出这类硬实时逻辑。
  • CM核:负责LWIP协议栈、EMAC底层驱动、PHY芯片管理和TCP/UDP socket接口。
  • IPC:C28x和CM之间通过TI提供的IPC模块的Message RAM进行数据交换,C28x把需要上报的数据打包通过IPC发给CM,CM这边收到后调用LWIP的socket接口发出去;反过来,上位机发来的UDP数据包由CM核解析后通过IPC写给C28x,C28x再处理。

这套方案的优点很明显:控制逻辑和网络协议栈物理隔离,协议栈卡死或网络闪断不会影响控制实时性。同时,CM核有独立的CPU资源,跑LWIP时不会吃掉C28x的算力。

至于为什么没有用SYS/BIOS(TI自家的RTOS)?我的理由是SYS/BIOS会增加配置复杂度,特别是调试网络任务优先级时特别容易翻车。裸机轮询LWIP已经能满足当前项目的连续数据流需求,也没有必要上RTOS。

1.3 硬核知识点:F28388D的EMAC外设要理清

F28388D的以太网MAC(即EMAC)模块,实际上来源于TI的Sitara系列AM335x/AM437x,软硬件上非常成熟。F28388D片上继承的是一套MII/RMII接口的MAC控制器,支持10M/100Mbps速率(注意这颗片子的EMAC只支持到100M,没有千兆),并且支持MII和RMII两种PHY接口模式。板载PHY芯片通过MII接口与MAC连接,再通过RJ45网口走出去。

这里需要特别留意的就是“EMAC”这个名字在不同场合的指代。F28388D的EMAC是逻辑MAC层,它只负责以太网帧的组装、校验、流量控制和收发FIFO的管理;真正和网线打交道的是PHY芯片,比如这块板子上用的TI DP83822I。MAC和PHY之间通过MII管理接口(MDIO/MDC)来通信,MDIO用来读写PHY芯片的寄存器,实现对PHY的配置和状态读取。MAC和PHY之间的数据通道则走MII总线,一共16根数据线(TXD[3:0]、RXD[3:0]等),另外还有TX_CLK、RX_CLK相对较敏感,布线不好容易出信号完整性问题。所以F28388D的EMAC这块一旦网络不通,第一步是先判断问题出在MAC配置、PHY配置、还是物理链路连接。

1.4 项目的功能边界和最终预期

这次项目最终要达成的目标很朴实:用YXDSP-F28388D开发板作为服务端,PC作为客户端,通过网线直连,实现UDP数据包的双向收发。主要指标如下:

  • 实现PC能ping通F28388D开发板的IP地址,默认IP我配置为192.168.1.10。
  • 开发板支持UDP socket绑定5000端口,PC向这个端口发送数据,开发板能收到并原样回传。
  • 后续扩展目标是加入TCP客户端模式和ModbusTCP协议栈,目前先把基础通信链路打通。

2. 环境准备与工具链搭建

2.1 开发环境和调试工具的选型

在 F28388D 上做开发,强烈建议直接用 TI 官方套件,不要折腾第三方编译工具。我的环境如下,供参考:

工具/组件版本用途说明
Code Composer Studio12.5.0主开发IDE,内置工程管理和调试器界面
C2000Ware MotorControl SDK5.02.00.00F28388D 各个外设例程和驱动库,LWIP 移植代码附在其中
TI 编译器ti-cgt-armllvm 3.2.2 LTS编译 CM 核代码必须用 ARM LLVM 编译器,不能用 C2000 编译器
XDS110 调试器板载调试 CM 核和 C28x 核都用它
网线、路由器或交换机普通千兆开发板和 PC 直连,或通过交换机连接

这里要特别说明一个问题:很多人一开始会在 CCS 的工程属性里找编译目标,看到 C28x 编译器就选上了,结果编译 CM 核代码时一堆语法错误。原因很简单,CM核是Arm内核,必须用TI 提供的 ARM LLVM 编译器(ti-cgt-armllvm)来编译;C28x 核的代码则用 C2000 编译器(ti-cgt-c2000)。一个CCS工程里可以同时包含这两种编译目标,但必须分别创建独立工程,或者使用多核工程模板。我在实操中直接在 C2000Ware 的例程基础上改,省去了自己从头建工程的麻烦。

2.2 从官方例程中快速定位 LWIP 移植代码

C2000Ware 里自带了一个以太网 LWIP 的参考例程,路径一般在:

C:\ti\c2000\C2000Ware_5_02_00_00\driverlib\f2838x\examples\cm\ethernet\enet_lwip\

这个目录下面还能看到 enet_lwip 和 enet_lwip_udp 之类的子工程,前者是带 TCP 和 UDP 的完整 LWIP 示例,后者更精简。我建议直接拿 enet_lwip_udp 作为起点,因为 UDP 代码量少,调试时更容易定位问题。

工程打开后需要做三处核心修改:

  1. Phy 芯片驱动头文件配置(根据你板子上的 PHY 芯片型号选择宏定义)。
  2. EMAC 引脚复用配置(对 YXDSP 板子来说,引脚的复用已经在 board.c 里做好,但需要确认宏是否打开)。
  3. LWIP 的 IP 地址配置,在 lwipopts.h 里修改。

在动手之前,强烈建议你先把工程全编译一遍,烧录到板子上跑一下官方默认的 ping 通逻辑。如果官方例程在你的板子上都 ping 不通,那就是你的板子和官方 EVM 硬件配置不一致,这时候再动上面的三处修改排查。

2.3 核间通信 IPC 的准备

因为我的方案里要求 CM 核收到网口数据后通知 C28x,所以正式移植 LWIP 之前需要先把 IPC 打通。F28388D 的 IPC 使用起来不算难,C2000Ware 里直接提供了 ipc 的例程( driverlib/f2838x/examples/c28x/ipc 和 cm/ipc 目录)。

IPC 的关键资源是 Message RAM,它是一块物理上 C28x 和 CM 都能访问的共享内存地址,数据是真正的硬件共享而不是拷贝。C28x 从某个地址写数据,CM 从地址读出来,再加上一个硬件中断来做事件通知,就形成了一个完整的通信管道。

我直接用了 TI 的 IPC 驱动库,在 CM 核代码里注册中断处理函数,C28x 侧调用 IPC_send 接口就能把数据送到 CM 侧。最后我们把 IPC 数据的消息格式定义成一个结构体,包含 command、length、data[64] 等字段,方便后面加协议解析。

3. 核心细节解析与实操要点

3.1 板载 PHY 芯片识别与地址配置

我最开始卡得最久的地方,就是 PHY 地址。YXDSP-F28388D 开发板上用的 PHY 芯片型号是 TI 的 DP83822I,它的地址跳线默认是 0x00(有些板子可能是 0x01 或者 0x02),具体得看板子原理图的 PHYAD[2:0] 引脚接线。如果调试时 EMAC 驱动一直报 PHY 无响应,或者读回来的 PHY ID 寄存器全是 0xFF/0x00,那基本就是 PHY 地址不对,或者 MDIO 引脚复用没配置对。

怎么判断PHY地址?用 CCS 的 Expressions 窗口直接读 MDIO 总线。在调试中打开 DriverLib 库的 PHY 读写函数,手动呼叫读 PHY 地址对应寄存器,如果返回的是 0x2000(DP83822 的 PHY ID 寄存器的高16位),说明地址对了。

YXDSP 这块板子的 DP83822I 的 PHY 地址,我实测是配置为 0x00。但考虑到不同批次可能改版,检查顺序建议:

步骤操作预期结果
1查板子原理图中 PHYAD[2:0] 的网络标号通常标注0或1
2在 enet_phy.h 中把 PHY_ADDR 宏改成对应值读取 PHY ID 正常
3用万用表量DP83822I的 PIN 38/39/40 电平确认地址配置

注意,在 TI 官方例程中,PHY 地址用宏定义PHY_ADDR表示,默认可能是 0x01。如果你的 EVM 板是 0x00,不改就完全不通。

3.2 MII 与 RMII 模式选择:如何看待 RMII 的简化优势

F28388D 的 EMAC 接口可以在MII和RMII之间切换。MII 是 4 位数据线,频率较高(25MHz 时钟下跑 100Mbps),16根信号线;RMII 只有 2 位数据线,时钟固定为50MHz,信号线少一半,极大方便 PCB 布线和引脚分配。

YXDSP-F28388D 的板子我记得实际走的是 MII 模式,这一点可以在 board.c 文件里看到引脚定义:有很多GPIO_00_EMAC0_TXD0之类的复用配置。实测下来,MII 模式比较稳定,如果你自己画板子想省引脚,才考虑RMII。

LWIP 配置这块没啥好选的,MII模式下直接把EthernetInterface实例传入EMAC_MODULE_0,并且注意 board.c 里GPIO_EMAC_MII的宏定义一定要打开。如果遗漏,引脚没有被复用到EMAC功能,你就会看到 PHY 能读ID、但数据收发完全不行。

3.3 LWIP 协议栈内存规划:像装修房子一样预留空间

LWIP 对内存的敏感度非常高,配置不当很容易出现ERR_MEM之类的错误。F28388D 的CM核自带 SRAM 很大(具体来说有 384KB 紧耦合内存,另外还有大块的共享内存),但这不意味着可以无脑分配LWIP内存。

lwipopts.h里最重要的几个宏:

#define MEM_ALIGNMENT 4 #define MEM_SIZE (64 * 1024) #define PBUF_POOL_SIZE 16 #define PBUF_POOL_BUFSIZE 1512 #define LWIP_UDP 1 #define TCP_MSS 1460 #define TCP_WND (16 * TCP_MSS)

上面这份配置实际跑下来,TCP 和 UDP 同时使能时,内存占用大约在 40KB 左右,CM核富余很多。如果你只做UDP,可以把TCP相关的宏都关掉,内存还能再压缩一半。这也是 LWIP 的优化核心思路:用不到的功能就编译进去,既占flash又占RAM。

3.4 最小化点亮 LWIP 的工具准备

调试网络最有效的工具还是 PC 端的命令行。我通常准备以下几件套:

  • ping 192.168.1.10—— 判断 IP 层通不通。
  • 网络调试助手(支持 UDP/TCP 收发)—— 快速发数据测试。
  • Wireshark —— 抓包看开发板是否发出包、发出的是什么内容。
  • arp -a—— 查询局域网的 ARP 表,判断设备在不在线。

如果 ping 不通,第一反应不要先怪代码。先查 PC 网卡到的网线通不通?开发板PHY的link灯亮不亮?这两个前提过了再查软件。

4. 实操过程与核心环节实现

4.1 编写底层 EMAC 驱动初始化

在 TI 的 DriverLib 库中,EMAC 的初始化已经被封装得很好,用户主要工作集中在三块:使能外设时钟、配置引脚复用、初始化 MAC 和 PHY。

当我们在 CCS 里编译官方的enet_lwip_udp例程时,程序入口是main.c,这又是一个容易踩坑的地方:CM核工程的入口函数名不叫main(),而是叫cm_main()。因为 TI 的 CM 启动文件中已经定义了main()并在其中完成基础初始化,之后再回调cm_main()

int cm_main(void) { // 初始化系统时钟 CM_init(); // 初始化 GPIO 引脚复用 Board_init(); // 初始化 EMAC 模块和 PHY EthernetInterface_init(); // 启动 LWIP 线程 lwip_init(); while (1) { lwip_service(); } }

其中lwip_service()是 LWIP 的轮询调度函数,包含了 MAC 层接收、定时器轮转、TCP/IP 栈处理等全部事务。UI事件里不需要自己再写收发函数,在 socket 的 recv 函数里等待即可。

4.2 修改 LWIP 的 IP 地址和网段

打开lwipopts.h(或工程内的lwip.c),找到静态 IP 设置部分:

#define LWIP_IPADDR0 192 #define LWIP_IPADDR1 1 #define LWIP_IPADDR2 1 #define LWIP_IPADDR3 10 #define LWIP_NETMASK0 255 #define LWIP_NETMASK1 255 #define LWIP_NETMASK2 255 #define LWIP_NETMASK3 0 #define LWIP_GWADDR0 192 #define LWIP_GWADDR1 1 #define LWIP_GWADDR2 1 #define LWIP_GWADDR3 1

如果你的 PC 网卡 IP 是 192.168.1.x 段,那这套配置完全不用改。如果你用路由器分配IP,不建议用DHCP,个人经验是嵌入式设备固定IP更省事,省得每次都要看分配的什么地址。注意修改完要重新编译,LWIP 的 IP 是在编译期定死的。

4.3 创建 UDP Socket 并与 PC 端进行数据互传

我这里直接贴一份最小可用的 UDP 回环服务代码,放在cm_main的最后初始化部分调用:

#include "lwip/sockets.h" #define UDP_PORT 5000 static void udp_echo_task(void) { int sock = socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in local_addr, remote_addr; socklen_t len = sizeof(remote_addr); char buf[256]; int ret; local_addr.sin_family = AF_INET; local_addr.sin_port = htons(UDP_PORT); local_addr.sin_addr.s_addr = INADDR_ANY; bind(sock, (struct sockaddr *)&local_addr, sizeof(local_addr)); while (1) { ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&remote_addr, &len); if (ret > 0) { // 原样回传 sendto(sock, buf, ret, 0, (struct sockaddr *)&remote_addr, len); } } }

这里面的recvfrom是阻塞调用,它不需要我们额外写操作系统调度,LWIP 在底层处理收包和缓冲。我在实际测试中用网络调试助手向 192.168.1.10:5000 发送字符串 “hello f28388d”,开发板立即原样返回同样内容,Wireshark 也能看到开发板在一直周期性发送 ARP 报文(这是LWIP对ARP定时请求的正常响应)。

4.4 打通双核数据通路:C28x DSP 与 CM 核的 IPC 数据交互

双核之间数据交换用 TI IPC 驱动实现,方法很标准化。

C28x 侧:

#include "ipc.h" uint16_t txData[32]; // 将 txData 复制到 IPC Message RAM 的某个地址(如 IPC_DATA_BASE) IPC_send(IPC_CM, IPC_FLAG0, txData, 32);

CM 侧:

#include "ipc.h" uint16_t rxData[32]; // 注册中断回调,收到 C28x 数据后自动触发 IPC_subscribe(IPC_C28X_0, IPC_FLAG0, ipc_callback); // 在回调里读取数据 IPC_recv(IPC_C28X_0, IPC_FLAG0, rxData, 32);

注意:IPC 共享内存区的首地址是固定的(F28388D 是IPC_DATA_BASE,不同系列不太一样)。要做的就是把C28x和CM核的工程文件里共享内存的地址对齐好。我踩过的坑是 C28x 侧把一个结构体指针以 32 位方式写入,CM 侧却按 16 位读取,结果高低字节全反了。建议统一按 16 位字(uint16_t)传输,或者用联合体做数据转换。

4.5 实测数据:UDP 回环延迟与吞吐量

做一次简单的性能评估,下文是我的实测数据环境:PC(i5,千兆网卡)直连开发板,网线是 Cat6 超六类,PC IP 192.168.1.20,开发板IP 192.168.1.10。

测试项结果说明
ping 延迟最小0.3ms,平均0.6ms1024字节包 50次无丢包
UDP 4KB 回环往返1.2ms网络调试助手时间戳
UDP 连续发送 1000 包丢包0发送间隔10ms
Wireshark 观察 ARP 正常通过开发板MAC为自定义值

从数据看,F28388D 支持 100Mbps 以太网完全没有性能问题。用满带宽大包连续灌的话,CM核 CPU 占用实测不超过50%,当然这和我们只做简单 socket 透传有关。后面如果要在线跑 ModbusTCP,时间预算也完全足够。

5. 常见问题与排查技巧实录

5.1 ping 不通的第一时间排查序列

ping不通时,我建议按以下顺序排查,前两步基本能干掉80%的问题:

顺序检查项排查方法
1PHY 是否正常上电和复位量 DP83822I 的 RESET 引脚电平,至少3.3V高电平保持一段时间
2网口Link灯是否点亮不亮就是物理链路问题(线序、板子PHY供电、RJ45变压器)
3MDIO 是否读到 PHY ID在 CCS 中手动调用读寄存器,返回值不是 0xFFFF 即代表 PHY 通信正常
4MAC 地址是否正确MAC 地址不能全0,可以用任意本地管理地址
5IP 是否冲突arp -a检查 PC ARP 表里对应 IP 的 MAC 是否和开发板一致

有一个细节特别容易忽略:Windows 的网卡如果开启了“Internet 连接共享”或者多个网卡叠加,ping时可能会把包发到错误的网卡,导致 ping 不通。建议在 PC 网卡高级设置里临时禁用不用的协议或网卡,或者直接拔掉其他网线只留单网卡。

5.2 PHY 寄存器读写结果全为 0xFFFF 的根源

我在项目前期遇到过 MDIO 读出来总是 0xFFFF,查了很久才发现问题出在代码里Board_init()调用顺序。必须先配置引脚的复用功能(打开 EMAC 对应的 GPIO),再去初始化 EMAC 模块。如果你发现EthernetInterface_init()内部调用了优先级很靠前的SysCtl_enablePeripheral(SYSCTL_PERIPH_EMAC0),而 GPIO 对应复用寄存器还没配置,这时的 PHY 访问必然失败。

另外留意一下 CC32xx 与 C2000 的 MDIO 时钟分频设置。F28388D EMAC 的 MDC 时钟要求小于 2.5MHz,如果配置频率过高(尤其是主时钟跑到 100MHz 以上时没正确分频),PHY 寄存器也会读异常。

5.3 LWIP 收包出现数据错乱或偶发丢包

LWIP 偶发丢包常见原因就三类:

  1. MAC 地址没有按字节序正确设置,导致网卡过滤了所有不是它 MAC 的帧。
  2. UDP 校验和不匹配。LWIP 默认开 CHECKSUM_CHECK_UDP 和 CHECKSUM_GEN_UDP,如果 PHY 或者外部工具配置了 TCP/UDP 校验和卸载功能,就会出现收发都失败或都通过但数据错误。
  3. 内存池太小。尤其是PBUF_POOL_SIZE太小,在突发大流量下会分配失败。

排查方法很简单,用 Wireshark 抓包看有没有“TCP checksum offload”相关错误提示。如果有,优先把 LWIP 的 CHECKSUM 宏全部启用(默认),并关闭网卡驱动的 checksum offload(通常默认关闭,不用特别处理)。

5.4 烧录 CM 核代码后 C28x 核不工作的怪圈

我当初犯了个低级错误:只烧录了 CM 核的代码,C28x 核里没有任何程序,但 IPC 初始化时 C28x 侧没有应答,导致 CM 核启动流程卡在一个 IPC 握手等待上。这里要注意,F28388D 的启动流程是两个核彼此独立的,你需要分别生成 C28x 和 CM 的.out文件,然后用 CCS 的 “Load Program” 同时加载两个核的程序。

实际操作建议搞一个.target文件或者手动内存映射,确保 load 之后两个核的 PC 都能正确启动。TI 官方有个f2838x_c28x_blinky_cm_blinky例程可以作为多核加载示范。

5.5 网上找不到现成移植教程时怎么看文档

网络热词里很多人搜“t113开发板”、“stm32f407ve开发板”、“cubemx配置lwip”,那都是别的芯片的LWIP移植流程,参考意义有局限。我给的建议是,看F28388D的LWIP移植,优先级如下:

  1. C2000Ware 里自带的 enet_lwip 例程(最直接)。
  2. TI 官方文档《TMS320F2838x Technical Reference Manual》第 Ethernet 章节。
  3. TI E2E 论坛上搜F28388D LWIP关键词,里面有大量工商界朋友踩坑之后的总结。
  4. 芯片手册中 EMAC 寄存器的详细描述。

不要死磕通用LWIP教程,把MAC外设寄存器看懂,再对照espressif或stm32的LWIP工程,你反而更容易触类旁通。

6. 项目扩展思考:从 UDP 回环到工业协议栈

6.1 下一步可以做的 ModbusTCP 移植

既然 UDP 回环已经打通,后面加 ModbusTCP 其实比较轻松。LWIP 本身就支持 TCP server,只需要在 CM 核里实现 ModbusTCP 的协议解析层,处理 MBAP 头 + 功能码 + 数据。比如基于 FreeModbus 的 TCP 从站实现,把寄存器读写对应的回调函数里直接操作 C28x 通过 IPC 送来的变量。

F28388D 做了以太网和 EtherCAT 通信接口,后面如果想做 PLC 或者运动控制卡,ModbusTCP 是最通用最稳妥的起点。

6.2 安全性和抗干扰要注意的事项

工业现场网口和调试网口不一样,我做项目时即使只是开发板测试,也会在网口变压器隔离和防雷设计上留意。YXDSP 板子的RJ45自带变压器隔离,测试时单独供电避免地环路。注意不要在带电状态下插拔网线,网口的浪涌电流非常大,我手头就烧过一块树莓派的网口,教训挺惨痛。

6.3 性能优化思路

如果你的 LWIP 吞吐量一直上不去,可以重点看这几处:

  • 开启 LWIP 的零拷贝功能:LWIP_NETIF_TX_SINGLE_PBUF
  • 把 PBUF 池增大,减少pbuf_alloc的耗时。
  • 确认网卡驱动里 EMAC 中断优先级,不要让其他外设(如ADC)频繁打断 EMAC 接收过程。
  • 如果 CPU 占用过高,可以尝试把 EMAC 接收描述符的个数增加,减少中断频率。

F28388D 的 EMAC 支持多个 RX 描述符,我记得可以配到 16 个以上,实测对突发数据很友好。

7. 最后的几条经验总结

项目做到最后,我会把最核心的经验浓缩成几句话:

第一,F28388D 的 CM 核跑 LWIP 是 TI 官方支持的标准路线,别在 C28x 里硬折腾以太网。双核之间的 IPC 是整个系统设计里最容易出问题的地方,必须在网络功能之前先把 IPC 打通并且测试保底。

第二,PHY 地址和引脚复用是硬件相关的两大坑,拿到新板子第一步就是查原理图,把 PHY 芯片型号、PHY 地址、MII/RMII 模式确认清楚,再去看代码。别一上来就打开官方例程猛改网络参数,最后发现硬件就不匹配。

第三,LWIP 调试不要怕抓包。Wireshark 是整个网络开发里最值得信赖的工具,ping不通就看 ARP,ARP 有回复但 ping 不通,就看 ICMP 防火墙是不是把回包丢了,一层一层排,问题定位就快。

我自己在这块板子上从零到把 UDP 跑通,大概花了两个完整的周末。前三天都在 PHY 地址和引脚复用上原地打转,真正理顺之后,后面LWIP移植和 socket 调试反而非常迅速。如果你正好卡在某个地方,希望这份记录能帮你少走一些弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询