1. emNet协议栈全景与集成目标
在嵌入式以太网项目中,TCP/IP 协议栈往往不是“要不要用”的问题,而是“用哪一层、集成到什么程度、由谁负责哪些环节”的问题。SEGGER emNet 的定位非常明确:它是一套面向裸机(no-OS)和 RTOS 环境的嵌入式 TCP/IP 协议栈,以 ANSI-C 源码形式交付,不依赖操作系统抽象层,也不要求动态内存分配。理解这一点,是理解整个集成工程的前提。
emNet 在嵌入式协议栈谱系中的位置
嵌入式 TCP/IP 方案大致可分为三类。第一类是 Linux/BSD 移植型,功能完整但资源占用大、依赖 MMU 与完整内核;第二类是轻量级开源栈(如 lwIP),可裁剪、可移植,但配置项繁多、移植层需要自行适配;第三类是商业嵌入式栈,如 emNet,特点是源码交付、移植层清晰、与自家中间件(emFile、emUSB、embOS)协同良好,并提供可选的商业支持与认证材料。
emNet 的核心特性可以归纳为以下几点:
- 零拷贝与静态内存:所有缓冲区在编译期由配置宏确定,运行期不调用 malloc/free,避免堆碎片,适合长期运行的工业设备。
- 分层可裁剪:IP、ICMP、UDP、TCP、DHCP、DNS、ARP、IGMP 等模块通过
IP_USE_xxx宏按需启用,未用模块不参与编译。 - 驱动接口统一:网络驱动只需实现
IP_HW_Init、IP_HW_Send、IP_HW_GetPacket等少数函数,即可接入 MAC 层。 - 零配置启动:支持 DHCP 自动获取地址,也支持静态 IP,便于产线测试与现场部署。
- Socket 与零拷贝 API 并存:既提供类 BSD 的
send/recv接口,也提供IP_TCP_Send等直接操作缓冲区的接口,兼顾开发效率与吞吐。
适用场景上,emNet 更适合资源受限但要求稳定性的设备:工业控制器、医疗仪器、楼宇网关、测试测量设备。若设备需要完整的 HTTP 服务器、TLS、MQTT,则通常配合 emNet 之上的 emWeb、emSSL、emMQTT 使用,而不是在协议栈内部堆叠。
集成工程的整体目标与交付物
本课程所说的“集成工程”,不是把 emNet 源码复制进工程目录就算完成,而是要让协议栈在目标硬件上真正跑通一条完整的通信链路。整体目标可以概括为:在指定 MCU 与 PHY 上,使 emNet 完成链路层初始化、IP 地址获取、UDP/TCP 收发,并通过可复现的测试用例验证其稳定性。
围绕这个目标,集成工程需要交付以下成果:
- 一份可编译的 emNet 配置头文件(
IP_Config.h或等价文件),明确启用的协议模块、缓冲区数量与大小、任务优先级。 - 一个适配目标 MAC/PHY 的驱动文件,实现 emNet 要求的硬件抽象接口,并处理中断或轮询收发。
- 一个最小可运行示例:设备上电后通过 DHCP 或静态地址获得 IP,并能响应 ICMP ping。
- 一组通信测试用例:UDP 回环、TCP 连接建立与数据往返、异常断链恢复。
- 一份集成记录,包含关键宏取值、实测吞吐、内存占用与已知限制。
从源码到链路的整体结构
为了把上述目标落到具体对象上,下图给出 emNet 集成后的分层结构与数据流向。图中左侧是应用层,右侧是物理介质,中间是 emNet 内部各模块与驱动适配层。箭头表示数据包在发送与接收方向上的传递路径,虚线框表示需要开发者自行实现或配置的部分。
图中可以看到,应用层通过 Socket 或零拷贝 API 进入 emNet 核心,核心内部按 TCP/UDP/ICMP 与 IP/ARP/DHCP 分层处理,再经驱动适配层下发到 MAC/PHY,最终到达物理介质。接收方向则相反。右侧虚线框中的编译期配置,决定了核心内部哪些模块被编译、缓冲区有多大,是集成工程中最早需要确定、也最容易出错的环节。
集成前必须明确的几个判断
在动手改代码之前,建议先回答三个问题,它们直接决定后续工作量:
| 判断项 | 典型选项 | 对集成的影响 |
|---|---|---|
| 是否使用 RTOS | 裸机轮询 / embOS / FreeRTOS | 决定 emNet 任务如何调度、驱动收发用中断还是轮询 |
| IP 地址获取方式 | 静态 IP / DHCP | DHCP 需要额外启用模块并处理超时重试,静态 IP 更适合产线固定配置 |
| MAC 接口类型 | RMII / MII / SPI 外置 MAC | 决定驱动中寄存器操作与 DMA 描述符的写法,SPI 方案吞吐通常较低 |
以常见的 Cortex-M4 + 内置 MAC + RMII PHY 为例,若采用裸机轮询,主循环中需要周期性调用 emNet 的接收处理函数;若采用 embOS,则通常创建一个优先级低于应用任务、高于空闲任务的网络任务。静态 IP 场景下,配置宏中直接写入 IP_ADDR、IP_MASK、IP_GATEWAY 即可,无需 DHCP 模块参与。
本节小结与后续衔接
emNet 的集成目标不是“把源码放进工程”,而是交付一条可验证的通信链路。理解它的分层结构、编译期配置的作用,以及驱动适配层需要实现的接口,是后续所有配置、移植与测试工作的基础。下一阶段将围绕具体的配置头文件与驱动接口展开,把本节的结构图逐层落到可编译的代码上。