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_register couple,第 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 偏移、结构与引文均与原文一致;示例中的计数/字节/误帧率计算为帮助理解而构造(标注"示例/非蓝皮书原文",实际以设备对象列表及项目配套规范为准)。