找回密码
 立即注册
首页 业界区 安全 嵌入式视角看OSI模型

嵌入式视角看OSI模型

事值 2025-8-9 10:15:34
OSI 模型这个话题,虽然在教材和网络上已经被讲了无数次,但大多数讲解都以计算机网络为背景,从 HTTP、TCP 等协议展开说明。
说实话作为既非计算机科班出身,也非网络相关行业从业者的我来说,计算机网络是十分陌生且晦涩的,对初学者不太友好。当初我看完计算机网络书籍之后,仍云里雾里的,还是不太理解分层的真正意义和它跟实际开发有什么关系。
经过几年工作实践,动手写协议、调通信、分析数据包,才逐渐理解每一层的价值,所以今天想尝试抛开传统的网络角度,站在“嵌入式通信协议”的视角,重新解释一下 OSI 模型。
本文内容仅为个人工作实践总结,能力有限,如有谬误,欢迎指正,谢谢。
OSI 模型(Open Systems Interconnection Model,开放式系统互联模型)是一个用于描述网络通信过程的分层模型,共分为了七层,每层有各自的清晰的职责分工,十分便于系统设计和协议开发。
受限于资源,在嵌入式中通常不会完整实现 OSI 七层,但该模型对于通信协议的设计和开发非常有指导意义,在实际项目中会根据系统需求简化为3~5层通信协议结构。
完整的模型分层如下图(图片来自《嵌入式系统:硬件、软件及软硬件协同》,作者Tammy Noergaard):
1.png

下层对于上层都是透明的,即在逻辑上两个设备上对应层之间是可以直接交互的。
第1层:物理层

该层提供电气和物理规格
关注内容

  • 通信需要通过几根线相连?
  • 工作电压多少?多少电压代表“1”,多少电压代表“0”
  • 通信速率是多少?
  • 数据支持的传输方向?单工、半双工、双工?
  • 设备连接方式?点对点、一主多从、多主多从?
UART示例:

  • 需要Vcc、Tx、Rx、GND四根线;
  • 电平标准是RS232或者TTL;
  • 通信速率不定,设备双方约定好即可,常见的速率有115200bps、9600bps等;
  • 支持全双工,即可同时收发数据;
  • 设备连接是点对点;
第2层:数据链路层

描述字节如何在物理线缆上传输。
关注内容

  • 在多设备场景中,当前的数据是要发给谁的?
  • 数据帧的bit如何定义?帧头、帧尾、校验码?
  • 数据帧有无校验?什么校验方式?
  • 每帧数据的数据量是多少?
  • 数据的传输流向如何规定?
UART示例:

  • 由于UART设备点对点连接,第一个问题无需考虑,而在支持多设备的协议中,如SPI使用CS进行片选、IIC使用设备地址进行选择;
  • UART数据定义一帧数据有起始位(帧头)+8位数据位+校验位(可选)+停止位(帧尾);
  • UART可选使用奇偶校验,不是所有协议都在该层有校验,如SPI;
  • UART每帧10~11.5bits;
  • UART数据全双工,也无需考虑,如半双工的IIC则是通过ACK来交换数据线的控制权的;
第3层:网络层

该层负责将一个可变长的信息(包)从一端传送到另一端。
关注内容

  • 当前信息是要发给谁的?和上层第一个问题不同的是,这里表述的是软件层面上的地址,而不是物理地址
  • 数据帧要如何分包组包?
软件地址用来指向设备中的抽象主体,这在嵌入式中比较少见,一般就一个主体去处理通信信息。举个比较相似的例子,一般使用IIC去读写外部寄存器时:起始->从设备地址(读/写)->寄存器地址->ACK/NACK;其中的寄存器地址就如同软件地址;
UART一帧数据有效位只有8位,显然不能满足大部分应用需求,所以需要接收/发送多帧,最后将多帧数据组合成完整的数据包。这个时候就需要规定哪些帧是属于同一包的:

  • 定长,规定固定8帧或者16帧为一包?
  • 超时,规定多久没有数据流那前面的数据为一包?
  • 魔数,特定包头包尾来进行划分?
AT指令示例:AT+ID?
一帧数据发送一个ASCII码,该指令可以分解为 "A"  "T" "+" "I" "D" "?" "\r" "\n"共8帧
"AT"可作包头,"\r\n"可作包尾。
第4层:传输层

该层提供可靠的机制来传输数据。
关注内容

  • 整包数据是否完整准确?
  • 丢包、错包是否重传?
基于传输效率考虑,数据链路层不会提供过于复杂的校验,甚至是无校验。那为了保证整包数据的准确性,增加校验是必要的,常见的校验方式有CheckSum校验、CRC校验;
那校验后发现个别数据帧错漏要请求重传呢?比如,如果有包序信息,那就可以单独请求该包序号的数据重新发送。
第5层:会话层

负责建立、管理和终止会话。
关注内容

  • 会话的交互流程?如请求—应答—结束三步走流程
我觉得可以把会话换成交互来理解,一次会话就是两个设备之间一次完整的通信交互。
如AT指令交互:
主设备发送:                AT+BATTERY_VOLT?
从设备回复:          +BATTERY_VOLT: 3750,40
从设备确认结束:   OK
以上就是一次会话,从AT+CMD?开始建立会话,到+CMD:value进行会话交互,最后到OK终止会话。
第6层:表示层

该层定义数据结构,可能还会有压缩和加密。
关注内容

  • 定义数据结构,转换 row data 成结构体
  • 可能包含加密、压缩等(高级应用)
以上面的AT指令为例:
接收到的row_data[LEN] = {0xA6,0x0E,0x28};
数据定义结构定义struct {uint16_t volt;uint8_t percent};
经过表示层处理后即可输出volt = 3750;percent = 40;
第7层:应用层

该层接受用户交互并形成一个通信请求。
关注内容

  • 提供接口供业务模块调用,发起通信请求
  • 屏蔽底层通信细节
即提供一个调用接口给其他模块,用来发起通信。
如:send_cmd_to_slave(uint8_t cmd,uint8_t *param);
那当其他模块,如按键模块,识别到Key1被按下时就查询从设备电量,可以调用send_cmd_to_slave(CMD_REQUEST_BAT_PERCENT, NULL);发起通信查询。
这样,其它模块就不需要关心底层用的什么协议,什么接口,内部具体什么交互逻辑。
嵌入式常用通信结构

在资源极其有限的mcu中,一般会简化到3层:

  • 物理层:收发数据,例如 UART/SPI/I2C 驱动;
  • 数据链路层:处理帧结构,分帧/组帧,处理包校验;
  • 应用层:处理数据业务逻辑,如 AT 指令解析;
当项目稍微复杂后,推荐使用 5 层:

  • 物理层:收发数据,例如 UART/SPI/I2C 驱动;
  • 链路层:处理帧结构,分帧/组帧,处理包校验;
  • 网络层:软件地址识别,拆包组包;
  • 表示层:结构化数据,映射为具体含义的变量;
  • 应用层:负责通信业务逻辑,如命令处理、回复响应。
小结

OSI 模型虽然来源于计算机网络,但其“分层设计”的理念在嵌入式通信中同样适用。
其实对于嵌入式开发者来说,学习OSI 模型最重要的并不是去死记硬背每一层的具体定义,而是要理解“为什么要分层”、“每层解决什么问题”。清晰的职责划分才能带来更好的可维护性、可扩展性。

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册