协议基础概念:什么是协议、协议的三要素、协议分层模型
各位同学,咱们今天正式开课。
做嵌入式通信这么多年,我经常被新人问一个问题:「老师,协议到底是个啥?」
说白了,协议就是通信双方约定好的规矩。没有规矩,你发你的,我收我的,数据全乱套。
我记得刚入行那会儿,调试一块串口屏,发过去的数据屏上显示的全是乱码。折腾了两天,最后发现是数据位格式没对齐——我这边设的是8位数据位,屏那边默认是7位。你看,这就是协议没对上。
1.1 什么是协议
协议,英文叫 Protocol。你可以把它理解成两个人打电话时的规则:
- 谁先说话?
- 说多久?
- 说错了怎么重来?
- 说完了怎么确认?
在嵌入式系统里,两个设备之间要交换数据,就必须遵守一套共同的规则。这套规则就是协议。
核心定义:协议是通信双方为了实现数据交换而共同遵守的一组规则和约定。
举个例子,你家的 WiFi 路由器跟手机通信,用的是 IEEE 802.11 协议;你调试单片机时用的 UART,背后是 RS-232 协议。没有协议,设备就是聋子和哑巴。
1.2 协议的三要素
我习惯把协议拆成三个维度来看:语法、语义、同步。这三个要素缺一不可。
| 要素 | 含义 | 通俗理解 | 嵌入式例子 |
|---|---|---|---|
| 语法 | 数据的格式和结构 | 信封怎么写 | UART 的起始位、数据位、停止位 |
| 语义 | 每段数据的含义 | 信里写了什么 | Modbus 中 0x03 代表读保持寄存器 |
| 同步 | 收发双方的时序规则 | 什么时候寄信、什么时候回信 | I²C 的时钟线 SCL 控制数据采样时刻 |
咱们一个一个说。
语法
语法规定了数据长什么样。比如一个数据帧,开头是什么、中间是什么、结尾是什么,每个字段占多少位。
我举个例子,一个简单的自定义协议帧:
帧头(1字节) | 地址(1字节) | 命令(1字节) | 数据长度(1字节) | 数据(N字节) | 校验(1字节) | 帧尾(1字节)
0xAA 0x01 0x10 0x02 0x01 0x02 0x?? 0x55
这就是语法。收发双方必须按这个格式来,否则解析就会错位。
我的经验:设计协议时,帧头和帧尾一定要选不常用的字节值(比如 0xAA、0x55),避免数据内容里出现相同值导致误判。我曾经见过有人用 0x00 做帧头,结果数据里全是 0x00 的时候,解析器直接崩溃。
语义
语义规定了每个字段代表什么意思。同样是 0x10,在 Modbus 协议里可能是「读输入寄存器」,在你自己的协议里可能是「设置参数」。没有语义,语法再漂亮也没用。
你想想看,收到一个字节 0x03,你总得知道它是「读操作」还是「写操作」吧?这就是语义干的事。
同步
同步解决的是什么时候发、什么时候收的问题。同步方式分两种:
- 同步通信:双方共用一个时钟信号,比如 I²C、SPI。时钟边沿一到,数据必须到位。
- 异步通信:双方各自用自己的时钟,靠起始位和停止位对齐,比如 UART。
我记得有一次调试 SPI 总线,从设备老是丢数据。查了半天,发现是主设备时钟极性设反了——数据在时钟上升沿采样,我设成了下降沿。这就是同步没对齐。
避坑指南:异步通信(如 UART)的波特率误差不能超过 ±2%。我曾经因为用了精度不够的晶振,9600 波特率下误差到了 3%,结果 10 个字节里错 3 个。后来换了有源晶振,问题解决。
1.3 协议分层模型
协议分层,说白了就是把复杂问题拆成多层,每层只管自己的事。这样做的好处是:某一层改了,不影响其他层。
我刚开始学网络协议时,觉得七层模型太抽象。后来做项目,自己写了一个从物理层到应用层的完整协议栈,才真正体会到分层的好处——调试的时候,哪层出问题就查哪层,不用从头翻到尾。
OSI 七层模型
OSI 是国际标准化组织(ISO)提出的参考模型。虽然实际应用中很少完全照搬,但它是理解协议分层的最佳框架。
| 层号 | 名称 | 核心功能 | 嵌入式常见协议 |
|---|---|---|---|
| 7 | 应用层 | 为用户提供网络服务接口 | HTTP、MQTT、CoAP |
| 6 | 表示层 | 数据格式转换、加密、压缩 | TLS、SSL |
| 5 | 会话层 | 建立、管理、终止会话 | NetBIOS |
| 4 | 传输层 | 端到端可靠传输 | TCP、UDP |
| 3 | 网络层 | 路由选择、逻辑寻址 | IP、ICMP |
| 2 | 数据链路层 | 帧封装、差错检测、介质访问 | Ethernet、PPP |
| 1 | 物理层 | 比特流传输、电气特性 | RS-232、RS-485、CAN PHY |
实际项目中,我们通常不会把七层全用上。比如一个简单的传感器采集系统,可能只用到物理层和数据链路层。但理解七层模型能帮你建立全局视野。
TCP/IP 四层模型
TCP/IP 模型是互联网的事实标准。它把 OSI 七层压缩成了四层:
- 应用层:对应 OSI 的应用层、表示层、会话层。HTTP、FTP、MQTT 都在这一层。
- 传输层:对应 OSI 的传输层。TCP 提供可靠连接,UDP 提供快速无连接。
- 网络层:对应 OSI 的网络层。IP 协议负责寻址和路由。
- 网络接口层:对应 OSI 的数据链路层和物理层。负责把数据发到物理介质上。
你想想看,你在浏览器里输入一个网址,背后就是这四层模型在协同工作。应用层发 HTTP 请求,传输层用 TCP 保证数据不丢,网络层用 IP 找到目标服务器,网络接口层通过网线或 WiFi 把比特流发出去。
我的建议:做嵌入式开发,重点掌握 TCP/IP 四层模型就够了。OSI 七层模型用来理解概念,TCP/IP 模型用来落地干活。
协议分层对比
| 对比维度 | OSI 七层模型 | TCP/IP 四层模型 |
|---|---|---|
| 层数 | 7 层 | 4 层 |
| 提出时间 | 1984 年 | 1970 年代 |
| 标准化组织 | ISO | IETF |
| 实际应用 | 理论参考模型 | 互联网事实标准 |
| 嵌入式适用性 | 适合教学和理解 | 适合实际开发 |
1.4 协议分层结构图
下面这张图是我自己画的,把 OSI 七层和 TCP/IP 四层的对应关系画清楚了。你保存下来,以后看协议文档时对照着看,会清晰很多。
嗯,这张图你多看几遍。左边是 OSI 七层,右边是 TCP/IP 四层,中间的虚线箭头表示对应关系。你会发现,TCP/IP 的应用层其实把 OSI 的上三层(应用层、表示层、会话层)合并了。网络接口层则把数据链路层和物理层合并了。
我个人习惯在项目初期先用 OSI 七层模型做协议设计,把每一层的职责划清楚。等到了编码阶段,再按 TCP/IP 四层模型去实现。这样既不会漏掉细节,也不会被理论框架束缚住手脚。
一个小技巧:调试协议问题时,先确定问题出在哪一层。物理层的问题(比如信号质量差)表现往往是「时通时断」;传输层的问题(比如丢包重传)表现往往是「速度慢但最终能通」。定位到层,问题就解决了一半。
好了,这一章的内容就到这里。协议的三要素和分层模型是后面所有章节的基础。你把这些概念吃透了,后面学 Modbus、CAN、MQTT 这些具体协议时,会发现它们都逃不出这个框架。