1. 协议栈概述:TCP/IP 分层模型与嵌入式协议栈选型
各位同学,咱们正式开始。这一章我打算先聊聊 TCP/IP 协议栈的底子——分层模型,再对比几款常见的嵌入式协议栈,最后说说移植前要准备什么。这些东西看着基础,但我在项目里见过太多人因为底层概念不清,后面移植时踩坑。所以,咱们把地基打牢。
1.1 TCP/IP 协议栈分层模型
TCP/IP 协议栈,说白了就是一套通信规则。它把复杂的网络通信拆成四层,每层只管自己的事。这样做的好处是——哪层出问题,就修哪层,不用动其他层。
我习惯把这四层记成:应用层 → 传输层 → 网络层 → 网络接口层。从上往下,数据一层层打包;从下往上,数据一层层拆包。
| 层级 | 核心协议 | 职责 | 我在项目中遇到的坑 |
|---|---|---|---|
| 应用层 | HTTP, MQTT, CoAP, FTP | 为用户提供网络服务接口 | MQTT 的 QoS 等级没选对,丢包严重 |
| 传输层 | TCP, UDP | 端到端可靠传输(TCP)或尽力而为(UDP) | TCP 窗口大小没调,小内存设备直接 OOM |
| 网络层 | IP, ICMP, ARP | 路由寻址、报文转发 | ARP 缓存超时设置太短,网络频繁中断 |
| 网络接口层 | 以太网, PPP, SLIP | 物理介质上的数据帧收发 | MAC 地址过滤配置错误,设备无法入网 |
核心要点:数据从应用层往下走,每层加一个头部(Header),这叫封装。接收端从下往上走,每层剥一个头部,这叫解封装。你想想看,这就像寄快递——你写地址(应用层),快递公司贴单(传输层),分拣中心规划路线(网络层),最后快递员骑车送(网络接口层)。
为什么会这样分层?我个人的理解是——解耦。你换网卡驱动,不用改 TCP 代码;你升级 HTTP 版本,不用动 IP 层。我在一个工业网关项目里,就因为底层 PHY 芯片换了,但上层协议栈完全没动,三天就搞定了移植。要是没分层,估计得重写一半代码。
1.2 常见嵌入式协议栈对比
嵌入式世界里,TCP/IP 协议栈不是只有一种。选型选错了,后面移植就是给自己挖坑。我这些年用过 lwIP、uC-TCP-IP、FreeRTOS+TCP,还有轻量级的 uIP。下面这张表,是我个人的经验总结。
| 协议栈 | 资源占用(ROM/RAM) | 许可证 | 适用场景 | 我踩过的坑 |
|---|---|---|---|---|
| lwIP | ~40KB ROM / ~10KB RAM | BSD | 资源受限的 MCU,如 STM32、ESP32 | 内存池配置不当,导致 pbuf 分配失败 |
| uC-TCP-IP | ~60KB ROM / ~20KB RAM | 商业(Micrium) | 需要商业支持、高可靠性的工业设备 | 许可证费用高,小公司慎选 |
| FreeRTOS+TCP | ~50KB ROM / ~15KB RAM | MIT | 已用 FreeRTOS 的项目,无缝集成 | 网络缓冲区大小默认值偏小,大包传输丢数据 |
| uIP | ~10KB ROM / ~2KB RAM | BSD | 超低资源设备,如 8 位 MCU | 功能太精简,不支持 TCP 窗口缩放 |
我的建议:如果你用的是 Cortex-M3/M4 以上的 MCU,RAM 在 64KB 以上,直接上 lwIP。社区活跃,资料多,遇到问题好查。我当年第一次移植 lwIP 到 STM32F407 上,从零开始到 ping 通,花了大概一周。后来熟了,两天就能搞定。
注意:uC-TCP-IP 虽然稳定,但商业许可证不便宜。我有个朋友在小公司,老板图省事直接买了 uC-TCP-IP,结果产品卖得不好,许可证费用都收不回来。选型时一定要算好成本账。
1.3 移植前的准备工作
移植协议栈,不是把源码拷进去就能跑的。我见过有人直接复制 lwIP 源码到工程里,编译报了两百多个错误,然后跑来问我怎么回事。嗯,这里要注意——准备工作做不好,后面全是坑。
我个人习惯,移植前先检查这三样东西:
- 硬件环境确认
- MCU 的 RAM 和 Flash 够不够?我建议至少留出 20% 的余量。
- 网卡芯片(PHY)型号是什么?常用的有 LAN8720、DP83848、KSZ8081。
- MAC 层是用 MCU 内置的,还是外挂的?比如 STM32 内置 MAC,需要外接 PHY。
- 软件环境准备
- 操作系统(RTOS)有没有?lwIP 可以跑在裸机上,但建议配合 RTOS 使用。
- 编译器版本和优化等级。我遇到过 -O2 优化下,lwIP 的临界区代码被优化掉,导致死锁。
- 调试手段:串口打印、LED 指示、逻辑分析仪,至少准备一种。
- 协议栈源码获取与结构理解
- 从官网或 GitHub 下载稳定版本。lwIP 我推荐 2.1.x 系列,稳定且文档全。
- 理解源码目录结构:src/core(核心协议)、src/netif(网络接口)、src/api(API 层)。
- 找到移植接口文件:通常叫
lwipopts.h和cc.h,这两个文件是移植的关键。
避坑指南:我曾经在一个项目里,MCU 的 RAM 只有 32KB,却选了 lwIP 的默认配置。结果一跑 TCP 连接,内存就爆了。后来我把 MEM_SIZE 从 1600 降到 512,PBUF_POOL_SIZE 从 16 降到 8,才稳定运行。所以,移植前一定要根据你的硬件资源,裁剪协议栈配置。
下面这张图,是我总结的 TCP/IP 协议栈移植前的知识体系。你看一眼,心里就有数了。