DLMS/COSEM 蓝皮书解读(四十):S-FSK MAC counters(class_id = 53)—— S-FSK 的"运行账本":同步/失同步/中继/收发/CRC 全统计
系列说明:本系列基于 DLMS UA《Blue Book(蓝皮书)第 16 版 · 第 2 部分》,一个接口类一篇。第 37/38/39 篇讲了 S-FSK 的 Phy&MAC 参数、发起方、超时机制——都是"配置与状态"。本篇讲"统计":设备跑了一段时间后,同步了多少次、因为什么原因失同步、中继/发送了多少帧、CRC 对错多少,全记在这里。
上篇回顾:第 39 篇的超时计时器决定了"什么时候失同步/回未配置";本篇的
synchronization_register和desynchronization_listing正好把"同步成功了多少次、因 5 种原因各失同步多少次"记成账本——两篇一前一后,把 S-FSK 的可靠性量化出来。
0. 为什么需要这个类 —— 抄表网络要靠"账本"证明自己靠谱
PLC 信道恶劣,S-FSK 设备跑久了,你总得回答:"这台表中继了多少帧?链路质量好不好(CRC 错帧多不多)?它到底稳定同步在哪个主站上、还是频繁掉线?"这些问题不能靠猜,得有计数器。S-FSK MAC counters就是这套计数器集合,全部 dynamic、只读(除reset),是现场诊断 PLC 网络健康度的第一手数据。
蓝皮书原文(
S-FSK MAC counters, Overview):
“An instance of the ‘S-FSK MAC counters’ IC stores counters related to the frame exchange, transmission and repetition phases.”
1. 类蓝图
S-FSK MAC counters 0…n class_id = 53, version = 0| 属性 | 静态/动态 | 数据类型 | Min | Max | Def | Short name |
|---|---|---|---|---|---|---|
| logical_name | static | octet-string | — | — | — | x |
| synchronization_register | dyn. | array | — | — | — | x + 0x08 |
| desynchronization_listing | dyn. | structure | — | — | — | x + 0x10 |
| broadcast_frames_counter | dyn. | array | — | — | — | x + 0x18 |
| repetitions_counter | dyn. | double-long-unsigned | 0 | — | 0 | x + 0x20 |
| transmissions_counter | dyn. | double-long-unsigned | 0 | — | 0 | x + 0x28 |
| CRC_OK_frames_counter | dyn. | double-long-unsigned | 0 | — | 0 | x + 0x30 |
| CRC_NOK_frames_counter | dyn. | double-long-unsigned | — | — | 0 | x + 0x38 |
Specific methods(m/o):
| 方法 | 必选/可选(m/o) | Short name |
|---|---|---|
| reset (data) | — | x + 0x50 |
2. 属性逐条解读
2.1 logical_name
蓝皮书原文:
"Identifies the ‘S-FSK MAC counters’ object instance."
示例 OBIS:0.0.26.3.0.255(非蓝皮书原文)。
2.2 synchronization_register(dyn, array of structure)
蓝皮书原文:
"Holds the MIB variable synchronization-register (variable 23)... This variable counts the number of synchronization processes performed by the system."
synchronization_register ::= array of synchronization_couples synchronization_couples ::= structure { mac_address: long-unsigned, // 12 位 S-FSK MAC synchronizations_counter: double-long-unsigned }蓝皮书原文(只记"导致同步"的过程):“Processes that lead to a synchronization loss due to the detection of a wrong initiator are registered. The other processes that lead to a synchronization loss (time-out, management writing) are not registered.”
蓝皮书原文(如何更新):看 SA/DA 字段,若对应某 client MAC address (CMA),则对应 couple 的计数 +1;没出现就新增 couple 初始化为 (CMA, 1)。若 SA/DA 都不是 CMA,则按预定义 NEW (FFE) 登记。
蓝皮书原文(溢出与容量):“When a synchronizations-counter field reaches the maximum value, it automatically returns to 0 on the next increment.”/“The maximum number of synchronization couples … should be specified in the implementation specifications. When this maximum is reached, the updating … follows a First-In-First-Out (FIFO) mechanism.”
蓝皮书原文:“The default value of this variable is an empty array.”
要点:这是"本设备都在哪些发起方上同步过、各多少次"的账本,按 MAC 地址归账;因超时/管理写导致的失同步不计入(只计"成功同步"和"wrong-initator 失同步");容量有限,满后 FIFO 只留最新。
2.3 desynchronization_listing(dyn, structure)
蓝皮书原文:
"Holds the MIB variable desynchronization-listing (variable 24)... This variable counts the number of desynchronizations that occurred depending on their cause."
desynchronization_listing ::= structure { nb_physical_layer_desynchronization: double-long-unsigned, nb_time_out_not_addressed_desynchronization: double-long-unsigned, nb_timeout_frame_not_OK desynchronization: double-long-unsigned, nb_write_request_desynchronization: double-long-unsigned, nb_wrong_initiator_desynchronization: double-long-unsigned }蓝皮书原文:“On reception of synchronization loss notification, the Management Entity updates this attribute by incrementing the counter related to the cause of the desynchronization.”/“When one of the counters reaches the maximum value, it automatically returns to 0 on the next increment.”/ 缺省为"全 0 的 structure"。
五种失同步原因一目了然:物理层、未寻址超时(第 39 篇)、帧错误超时(第 39 篇)、写请求(管理写/reset)、错误发起方。
2.4 broadcast_frames_counter(dyn, array of structure)
蓝皮书原文:
"Holds the MIB variable broadcast-frames-counter (variable 19)... It counts the broadcast frames received by the server system and issued from a client system (source-mac-address = any valid client-mac-address, destination-mac address = ALL-physical)."
broadcast_frames_counter ::= array of broadcast-couples broadcast-couples ::= structure { source-mac-address: long-unsigned, frames-counter: double-long-unsigned }蓝皮书原文:“The counter is incremented even if the LLC-destination-address is not valid on the server system.”/ 同样有最大容量 + FIFO。
要点:按"来源 MAC"统计收到的广播帧数;即使 LLC 目的地址在本机不合法也计数(用于衡量"链路上有多少广播噪声/活动")。
2.5 repetitions_counter / transmissions_counter(dyn, double-long-unsigned)
蓝皮书原文(repetitions):“Counts the number of repetition phases. The repetition phases following a transmission are not counted. If the MAC sub-layer is configured in the no-repeater mode, this variable is not updated.”/“A received frame repeated five times (from CC=4 to CC=0) is counted only once… since it corresponds to one repetition phase.”
蓝皮书原文(transmissions):“Counts the number of transmission phases. A transmission phase is characterized by the transmission and the repetition of a frame. A repetition phase, which follows the reception of a frame, is not counted.”/“A client system can write this variable to update the counter.”
要点:两者统计"阶段"而非"帧"。repetitions_counter衡量本设备作为中继的活跃度(非中继模式不更新);transmissions_counter衡量本设备自身发送的活跃度(客户端可写以校准)。
2.6 CRC_OK_frames_counter / CRC_NOK_frames_counter(dyn, double-long-unsigned,缺省 0)
蓝皮书原文:“Counts the number of frames received with a correct / incorrect Frame Check Sequence Field.”/ 溢出自动回 0。
这是链路质量最直接的指标——CRC_NOK / (CRC_OK + CRC_NOK)即近似误帧率。
3. 方法:reset (data)
蓝皮书原文:“Clears all counters.”
data ::= integer (0)蓝皮书原文(reset):方法参数为
integer (0)——固定传 0,含义是"清所有计数器"。调用后 7 个计数属性全部归零(或空数组/全 0 structure)。
4. 【实战举例】
示例 1:synchronization_register 的 A-XDR 编码(示例值)
假设本设备曾在两个发起方上同步过:
array (长度=2) ├─ structure { mac_address: long-unsigned 0x0C00, synchronizations_counter: double-long-unsigned 12 } // 在 C00 上同步 12 次 └─ structure { mac_address: long-unsigned 0x0C01, synchronizations_counter: double-long-unsigned 3 } // 在 C01 上同步 3 次说明:字节为示意(非蓝皮书原文)。
mac_address是 12 位 S-FSK MAC,C00/C01 属发起方范围(FIMA–LIMA)。
示例 2:desynchronization_listing 结构(示例值)
structure { nb_physical_layer_desynchronization: 5, nb_time_out_not_addressed_desynchronization: 2, // 被"遗忘回收"2 次(联动第 39 篇) nb_timeout_frame_not_OK desynchronization: 1, // 帧错误超时失同步 1 次 nb_write_request_desynchronization: 0, nb_wrong_initiator_desynchronization: 3 // 锁错发起方失同步 3 次 }看到nb_wrong_initiator_desynchronization高 → 说明附近有"假发起方"或本设备频繁在多个 DCU 间摇摆。
示例 3:用 CRC 计数器算误帧率(工程诊断)
某日读数:CRC_OK = 98000,CRC_NOK = 200。
误帧率 ≈ 200 / (98000 + 200) ≈ 0.20%说明:这是工程示意计算(非蓝皮书原文公式)。误帧率持续走高说明信道噪声大或增益该调(联动第 37 篇
max_receiving_gain)。
示例 4:调用 reset 清空所有计数器
ACTION reset (data = integer 0)调用后synchronization_register变空数组、desynchronization_listing变全 0 structure、repetitions_counter/transmissions_counter/CRC_*全归 0。适合"换季巡检前清零、跑一个月再看趋势"。
示例 5:broadcast_frames_counter 的"噪声"含义
某表broadcast_frames_counter里某个来源 MAC 计了 50000 帧,但本机 LLC 目的地址常不匹配——说明链路上有大量广播活动(可能是别的网络的广播、或中继风暴)。这不影响本机通信,但是信道繁忙度的信号。
示例 6:FIFO 行为(容量有限)
若实现规格规定最多存 16 个synchronization_registercouple,第 17 个不同发起方同步时,最旧的那个被挤出(FIFO)。排障时若"查不到某个 DC 的同步记录",不一定代表没同步过,可能是被 FIFO 覆盖了——要看实现规格的容量上限。
示例 7:现场"PLC 健康度仪表盘"(工程示意,结合四篇)
一个集中器下的某表,月度巡检读取:
| 指标 | 读值 | 健康判断 |
|---|---|---|
| synchronization_register | 1 个 couple,count=3000 | 稳定锁在单一 DC,好 |
| desynchronization_listing.nb_wrong_initiator | 0 | 无错误发起方干扰,好 |
| CRC_NOK / (OK+NOK) | 0.3% | 链路质量可接受(<1%) |
| repetitions_counter | 150000 | 中继活跃,确实在帮邻居转发 |
| transmissions_counter | 8000 | 自身发送正常 |
说明:阈值(如误帧率<1%)为工程经验值(非蓝皮书原文)。该表把第 37/38/39 篇的状态与本篇统计拼成"一张健康快照"。
示例 8:容量规划——synchronization_register 的 FIFO 容量
实现规格若规定最多 16 个 couple:
第 1–16 个不同 DCU 同步 → 各建 1 个 couple 第 17 个 DCU 同步 → 最旧 couple 被挤出(FIFO)若某片区 DCU 数量 > 16,老 DCU 的同步记录会被覆盖。审计"长期归属历史"不能只靠本对象,应让Profile generic(7) 周期性抓取synchronization_register落库。
示例 9:repetitions_counter 与"中继贡献"的关系
一台表repetitions_counter月增 50 万、transmissions_counter月增 1 万——说明它主要在做中继(帮别的表转发),自身业务很少。部署上它是"关键中继节点",断电会影响一大片;运维应优先保障这类表的供电与 PLC 耦合。
示例 10:reset 的审计影响
reset会清零所有计数器(含synchronization_register空数组、desynchronization_listing全 0)。做"对比实验"(如换增益前后)前 reset,能干净地只看新参数下的统计;但 reset 也会丢掉历史故障线索,正式故障排查时先读再 reset,别一上来就清。
5. 工程上容易踩的坑
- 全 dynamic、只读统计:除
reset外别试图 SET 这些计数;要清零只能调reset。 - 计数器溢出自动回 0:任一计数达最大值后下一次 +1 变 0,读取时要警惕"突然变小"是溢出而非真归零。
synchronization_register只记"成功同步":因超时/管理写导致的失同步不计入(只有 wrong-initator 失同步算);想看失同步全貌得结合desynchronization_listing。desynchronization_listing区分 5 种原因:物理层/未寻址/帧错误/写请求/错误发起方——定位掉线根因先看这张表。repetitions_counter≠transmissions_counter:前者计"中继活动"(非中继模式不更新),后者计"自身发送";别混用评估设备负载。broadcast_frames_counter即使 LLC 目的地址无效也计数:它反映的是"链路广播活跃度",不是"发给本机的有效广播"。reset参数固定integer(0):传别的值(或 structure)不符合原文。- couple 容量由实现定,FIFO 回收:老记录可能被覆盖,审计长周期要用
Profile generic(7) 周期抓取本对象。 - 与第 37/38/39 篇联动:失同步计数来自第 39 篇的超时触发、来自第 38 篇的
reset/管理写、来自第 37 篇的mac_address状态机——排 S-FSK 故障要把这几篇当一套看。
6. 小结 & 下期预告
本篇要点:
S-FSK MAC counters(53) 是 S-FSK 的"运行账本",7 个计数属性全 dynamic、只读(除reset);synchronization_register(按 MAC 归账的同步次数)+desynchronization_listing(5 种失同步原因)构成"同步健康度"主轴;broadcast_frames_counter/repetitions_counter/transmissions_counter/CRC_OK/CRC_NOK覆盖收发、中继、链路质量;reset (data = integer 0)一键清所有计数器;容量有限时 FIFO 回收旧记录。
下一篇(第 41 篇):IEC 61334-4-32 LLC setup(class_id = 55)—— 为 S-FSK 网络配置 LLC 子层的最大帧长与待读 L-SAP 回复列表,是 S-FSK 通信栈从 MAC 层向上移交到 LLC 层的衔接类。
参考资料:DLMS UA《Blue Book Ed.16 Part 2 – COSEM interface classes》,S-FSK MAC counters(class_id = 53, version = 0) 章节;文中属性、数据类型、Short name 偏移、结构与引文均与原文一致;示例中的计数/字节/误帧率计算为帮助理解而构造(标注"示例/非蓝皮书原文",实际以设备对象列表及项目配套规范为准)。