1. 协议栈概述:什么是通信协议栈、分层思想(OSI与TCP/IP模型)、为什么单片机需要协议栈
大家好,我是你们的老朋友。今天咱们正式开始聊《单片机通信协议栈架构设计与实现》这门课。第一节课,我想先聊聊最基础的东西——协议栈到底是什么?为什么我们搞单片机的,也需要这玩意儿?
说实话,我刚开始做嵌入式那会儿,对“协议栈”这三个字是有点发怵的。总觉得那是搞Linux、搞网络的大神才需要碰的东西。我们单片机嘛,串口发几个字节,I2C读个传感器,不就够了?
后来我发现,我错了。而且错得挺离谱。
1.1 什么是通信协议栈?
先别想得太复杂。协议栈,说白了就是一套通信规则的集合。
你想想看,两个人要聊天,得用同一种语言吧?你说中文,我说法语,那没法聊。设备之间也一样。A设备发一串0101的比特流,B设备得知道:这串比特流是什么意思?哪些是地址?哪些是数据?校验位在哪?
这些规则,就是协议。
那为什么叫“栈”呢?因为它是分层的。每一层负责一件事,层与层之间通过固定的接口交互。就像你公司里的部门——销售部只管接单,研发部只管做产品,财务部只管收钱。各司其职,出了问题也好排查。
协议栈 = 分层 + 协议 + 接口
每一层只关心自己的事,不越界。这就是协议栈的核心思想。
我在一个物联网项目中,用过一套自制的协议栈。底层是UART,中间层做分包和重传,上层是应用数据。当时调试的时候,发现数据偶尔丢包。我直接定位到中间层的重传机制,改了几行代码就搞定了。如果所有逻辑都揉在一起,那排查起来可就头疼了。
1.2 分层思想:OSI模型与TCP/IP模型
说到分层,就绕不开两个经典模型:OSI七层模型和TCP/IP四层模型。
OSI模型是国际标准化组织搞的,理想很丰满,现实很骨感。它把通信过程分成了7层:
| 层号 | 名称 | 作用(说白了) |
|---|---|---|
| 7 | 应用层 | 你真正想传的数据,比如温度值、开关状态 |
| 6 | 表示层 | 数据格式转换,比如加密、压缩 |
| 5 | 会话层 | 建立、管理、终止会话 |
| 4 | 传输层 | 保证数据可靠到达,比如TCP的确认重传 |
| 3 | 网络层 | 寻址和路由,找到对方在哪 |
| 2 | 数据链路层 | 帧同步、差错检测,比如CRC校验 |
| 1 | 物理层 | 比特流的传输,比如电平高低、时钟 |
你可能会问:这7层,我们单片机都得实现吗?
当然不是。OSI模型更多是教学用的。实际工程中,我们用的是TCP/IP模型,它只有4层:
- 应用层:HTTP、MQTT、CoAP,或者你自己定义的私有协议
- 传输层:TCP(可靠)、UDP(快速)
- 网络层:IP协议,负责路由
- 网络接口层:以太网、Wi-Fi、PPP等
嗯,这里要注意:TCP/IP模型其实把OSI的上面三层合并成了应用层,下面两层合并成了网络接口层。更实用,也更简洁。
我个人习惯,在做单片机协议栈时,参考的是TCP/IP的分层思想,但会根据硬件资源做裁剪。比如在STM32上做Modbus协议栈,我通常只分两层:物理层(RS485)和应用层(Modbus帧)。中间如果需要可靠传输,再加一层简单的确认重传。
1.3 为什么单片机需要协议栈?
这个问题,我当年也问过自己。单片机资源那么有限,RAM才几KB,Flash几十KB,跑个协议栈会不会太奢侈?
答案是:不是奢侈,而是刚需。
我给你说几个场景:
- 场景一:多个传感器采集。一个主控要轮询读取10个传感器的数据。如果没有协议,你怎么知道哪条数据是哪个传感器的?地址、命令、数据、校验,这些都需要协议来约定。
- 场景二:远程升级(OTA)。你要通过无线给单片机升级固件。数据包可能丢失、乱序、重复。没有协议栈的确认重传机制,升级就是碰运气。
- 场景三:设备互联互通。你的设备要接入阿里云、华为云。人家云端用的就是标准的MQTT协议。你单片机不支持?那对不起,连不上。
我的经验之谈:不要觉得协议栈是“大材小用”。哪怕只是两个单片机之间用串口通信,定义一个简单的帧格式(起始符+长度+数据+校验),也算是一个微型协议栈。它能帮你省掉无数调试的麻烦。
我曾经接手过一个项目,之前的工程师把所有通信逻辑都写在了一个中断服务函数里。没有帧头、没有校验、没有超时处理。结果呢?设备偶尔死机,查了三天没找到原因。后来我花了一天时间,给它加了一个简单的协议层——帧头0xAA 0x55,长度字节,CRC16校验,超时重传。从此再也没出过问题。
你看,这就是协议栈的价值。它让通信变得可靠、可维护、可扩展。
1.4 单片机协议栈的特点
跟PC上的协议栈不同,单片机上的协议栈有几个鲜明的特点:
- 资源受限:RAM、Flash、CPU主频都有限。不能像Linux那样随便malloc。我一般用静态分配,或者内存池。
- 实时性要求高:很多场景是硬实时,比如电机控制、工业总线。协议栈的延迟必须可控。
- 裁剪灵活:不需要的功能就砍掉。比如不需要IP分片,那就不实现。不需要TCP窗口缩放,那就不支持。
- 硬件耦合紧密:直接操作寄存器、DMA、中断。不像PC上,网卡驱动已经封装好了。
避坑指南:我曾经在一个项目里,直接移植了lwIP(一个轻量级TCP/IP协议栈)到STM32F103上。结果发现,默认配置下,内存占用太大,跑不起来。后来我裁剪了TCP的窗口大小、关闭了IP分片、减少了PBUF数量,才勉强跑通。所以,移植协议栈,一定要先看资源够不够。
1.5 本课程的学习路径
这门课,我会带着大家从零开始,一步步构建一个适合单片机的通信协议栈。我们会从最底层的物理层驱动讲起,然后到数据链路层的帧封装、差错控制,再到网络层的寻址,最后到应用层的协议实现。
每一章,我都会结合我实际项目中的代码和踩过的坑来讲。你学完以后,不仅能理解协议栈的原理,还能自己动手写一个出来。
好了,第一节课就到这里。下一节,我们开始聊物理层——那些最底层的、跟硬件打交道的活儿。到时候我会拿UART和SPI举例,讲讲怎么设计一个高效的底层驱动。
咱们下节课见。