3、数据链路层基础:数据链路层的功能(帧同步、差错控制、流量控制)、常见的链路层协议(HDLC、PPP)、MAC地址与寻址方式
各位工程师朋友,咱们今天聊聊数据链路层。这一层在智能电表通信里,地位相当特殊。它夹在物理层和网络层中间,说白了就是个“承上启下”的角色。我做了这么多年电力通信,发现很多现场问题,追根溯源都出在这一层。
物理层只管把比特流发出去,但发出去之后呢?有没有丢?有没有错?谁该接收?这些问题,物理层一概不管。这就是数据链路层的活儿。它要把物理层那个不可靠的传输通道,变成一条看起来没有差错的逻辑链路。
3.1 数据链路层的三大核心功能
数据链路层要干的事,我总结为三件:帧同步、差错控制、流量控制。这三件事,一个都不能少。
3.1.1 帧同步
物理层传的是比特流,就像一条河里的水,没有边界。数据链路层要做的第一件事,就是给这些比特流“画格子”。这个格子,就是帧。
帧同步,就是让接收方知道:一帧从哪里开始,到哪里结束。我见过不少刚入行的工程师,觉得帧同步很简单。其实不然。在电力线这种噪声环境里,比特流里随便一个干扰,就可能让接收方“找不着北”。
常用的帧同步方法有几种:
- 字符填充法:用特殊字符标记帧的边界。比如HDLC协议用的0x7E。
- 比特填充法:连续5个1之后插入一个0,防止误判。
- 违规编码法:利用物理层编码中的非法码型表示帧边界。
我个人习惯:在智能电表这种资源受限的设备上,我倾向于用比特填充法。它实现简单,而且对传输效率影响不大。我曾经在一个项目中,因为用了字符填充法,结果在电力线噪声干扰下频繁出现帧同步失败。换成比特填充法后,问题迎刃而解。
3.1.2 差错控制
电力线通信环境有多恶劣?我这么说吧,电机启动、开关切换、甚至节能灯点亮,都能在电力线上产生巨大的噪声脉冲。比特在传输过程中,被“篡改”是家常便饭。
差错控制,就是要发现并纠正这些错误。常用的方法有:
- 检错码:比如CRC(循环冗余校验)。它只能发现错误,不能纠正。发现错误后,通常要求发送方重传。
- 纠错码:比如汉明码、卷积码。它不仅能发现错误,还能定位并纠正。但代价是增加了冗余比特。
在智能电表通信中,CRC是最常用的。我建议你至少用CRC-16,条件允许的话用CRC-32。为什么?因为电力线环境下的误码率,比你想象的高得多。
避坑指南:我曾经在一个项目中,为了省那一点点计算资源,用了简单的奇偶校验。结果呢?现场频繁出现数据错误,排查了整整一周才发现是校验强度不够。从那以后,我再也不敢在电力通信里用奇偶校验了。
3.1.3 流量控制
流量控制解决的是“快慢问题”。发送方发得太快,接收方来不及处理,数据就会丢失。你想想看,智能电表的主站可能同时管理几千个电表,如果每个电表都拼命发数据,主站肯定扛不住。
常用的流量控制机制:
- 停等协议:发一帧,等确认,再发下一帧。简单,但效率低。
- 滑动窗口协议:允许连续发送多帧,接收方通过窗口大小控制流量。效率高,实现也复杂一些。
在智能电表这种低功耗、低带宽的场景下,我一般建议用滑动窗口协议。窗口大小设为4或8,既能保证效率,又不会占用太多内存。
3.2 常见的链路层协议
讲完功能,咱们看看具体的协议。在智能电表领域,最常碰到的就是HDLC和PPP。
3.2.1 HDLC(高级数据链路控制)
HDLC是个老协议了,但老不代表过时。它结构清晰,实现简单,非常适合嵌入式系统。
HDLC的帧结构是这样的:
| 标志 (0x7E) | 地址 | 控制 | 信息 | 帧校验 (FCS) | 标志 (0x7E) |
每个字段都有讲究:
- 标志字段:固定为0x7E,用于帧同步。
- 地址字段:在多点链路中标识站地址。
- 控制字段:标识帧类型(信息帧、监控帧、无编号帧)。
- 信息字段:承载上层数据。
- FCS:帧校验序列,通常用CRC-16或CRC-32。
HDLC有三种工作模式:正常响应模式、异步平衡模式、异步响应模式。在智能电表通信中,最常用的是异步平衡模式。为什么?因为它支持点对点通信,而且双方都可以主动发起传输,非常适合电表和主站之间的交互。
注意:HDLC的0x7E标志在信息字段中出现时,需要进行“透明传输”处理。具体做法是:遇到0x7E就转义成0x7D 0x5E,遇到0x7D就转义成0x7D 0x5D。这个细节很容易被忽略,但一旦忽略,帧同步就会出问题。
3.2.2 PPP(点对点协议)
PPP是HDLC的“升级版”。它保留了HDLC的帧结构,但增加了链路控制协议(LCP)和网络控制协议(NCP)。
PPP的优势在于:
- 链路建立和配置:通过LCP协商参数,比如最大接收单元、认证方式等。
- 多协议支持:通过NCP,可以在同一条链路上承载IP、IPX等多种网络层协议。
- 认证机制:支持PAP、CHAP等认证方式,安全性更高。
在智能电表远程通信中,PPP经常用在GPRS或4G模块上。电表通过PPP拨号连接到运营商网络,然后获取IP地址,进行数据上报。
我记得有个项目,电表通过GPRS模块上报数据,但总是断线重连。排查后发现,是PPP的LCP保活机制没有配置好。调整了保活间隔后,链路就稳定了。
3.3 MAC地址与寻址方式
说到寻址,很多人第一反应就是MAC地址。没错,MAC地址是数据链路层的核心寻址方式。
MAC地址,也叫物理地址、硬件地址。它通常固化在网络设备的ROM中,长度48位,用12个十六进制数表示。比如:00:1A:2B:3C:4D:5E。
MAC地址的分配是有规矩的:
- 前24位:组织唯一标识符(OUI),由IEEE分配给设备制造商。
- 后24位:由制造商自行分配,保证唯一性。
在智能电表通信中,MAC地址的寻址方式主要有三种:
- 单播:一对一通信。发送方指定接收方的MAC地址,只有该设备会接收。
- 广播:一对所有通信。发送方使用广播地址(全F,即FF:FF:FF:FF:FF:FF),链路上所有设备都会接收。
- 组播:一对多通信。发送方使用组播地址,只有加入该组播组的设备才会接收。
我建议:在智能电表网络中,尽量少用广播。为什么?因为广播会唤醒所有设备,增加功耗和网络负载。我见过一个现场,主站用广播方式抄表,结果整个台区的电表都频繁唤醒,电池寿命缩短了三分之一。后来改成单播+组播的方式,问题就解决了。
另外,在电力线载波通信中,MAC地址的寻址还有一个特殊问题:信号衰减。电力线不是理想的传输介质,不同相线之间的信号衰减很大。所以,有些电力线通信协议会引入“逻辑地址”或“路由地址”,来辅助MAC地址进行寻址。
嗯,数据链路层的基础就讲到这里。下一章,咱们深入聊聊HDLC和PPP在智能电表中的具体实现。到时候我会拿出一些实际的代码片段,咱们一起分析。