4、令牌传递机制:令牌帧结构、令牌持有时间、令牌环初始化与维护
好,咱们接着聊令牌传递。说实话,在Modbus多主站方案里,令牌传递是我个人比较偏爱的一种方式。为什么?因为它确定性好,不会出现数据碰撞,每个主站什么时候能说话,那是板上钉钉的事。我在一个污水处理厂的项目里用过这套机制,三个主站轮着来,两年没出过岔子。
令牌传递,说白了就是谁拿到令牌,谁就有发言权。其他主站只能听着,不能抢话。这跟咱们小时候玩击鼓传花是一个道理——花在你手里,你才能表演节目。
4.1 令牌帧结构
令牌本身也是一个数据帧,但它不是普通的Modbus报文。我习惯把它设计成一个精简的专用帧,结构如下:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| 起始符 | 1 | 固定值 0xAA,用于帧同步 |
| 目标地址 | 1 | 下一个要持有令牌的主站地址 |
| 源地址 | 1 | 当前释放令牌的主站地址 |
| 令牌类型 | 1 | 0x01 普通令牌,0x02 初始化令牌,0x03 维护令牌 |
| 时间戳 | 4 | 令牌生成时的系统时间,用于超时判断 |
| 校验和 | 2 | CRC16,覆盖前面所有字段 |
你可能会问,为什么要有时间戳?嗯,这里有个坑。我曾经遇到过一个情况,令牌在传输过程中被干扰了,虽然CRC没报错,但时间戳对不上,导致整个环都乱了。加上时间戳后,每个节点都能判断这个令牌是不是“过期货”,直接丢弃,避免环网崩溃。
关键点:令牌帧必须短小精悍。我见过有人把整个Modbus报文当令牌传,那效率太低了。记住,令牌只是控制权,不是数据。数据通信走正常的Modbus读写指令就行。
4.2 令牌持有时间
令牌不能一直攥在手里不放,否则其他主站就得干等着。所以必须设定一个最大持有时间,我一般叫它 THT(Token Holding Time)。
THT 怎么定?这得看你的应用场景。我举个例子:
- 如果每个主站只需要读几个寄存器,THT 设 50ms 就够了
- 如果要做固件升级,THT 可能要 500ms 甚至更长
- 如果系统对实时性要求高,THT 建议不超过 100ms
我个人习惯的做法是:THT = 单个最大报文传输时间 × 2 + 安全余量。比如你的Modbus报文最长256字节,在9600波特率下传输时间大约是 270ms,那 THT 就设 600ms 左右。这样既保证能发完一个完整报文,又不会拖太久。
小技巧:可以在每个主站里加一个“提前释放”机制。如果当前主站已经完成了所有要发的指令,没必要等到THT耗尽,直接释放令牌给下一家。这样能提高总线利用率。
还有一个细节:令牌持有时间是从收到令牌那一刻开始算的,不是从开始发数据算。我曾经犯过这个错,把计时起点搞错了,结果每个主站都超时,环网乱成一锅粥。
4.3 令牌环初始化
系统上电后,令牌环是空的,得有人来“点火”。我一般指定一个环主节点,通常是地址最小的那个主站,比如地址0x01。
初始化流程是这样的:
- 每个主站上电后,先监听总线一段时间(比如2秒),看看有没有令牌在跑
- 如果没检测到令牌,且自己是环主节点,就主动生成一个初始化令牌
- 环主节点把初始化令牌广播出去,里面包含所有已知的主站地址列表
- 其他主站收到后,回复自己的地址和状态,确认加入环网
- 环主节点收集完所有回复,生成一个完整的节点列表,然后开始正常令牌传递
注意:初始化阶段最容易出问题的是“多主同时抢权”。如果两个主站都认为自己是环主节点,同时发初始化令牌,那就冲突了。我的解决办法是:每个主站在发初始化令牌前,先随机等待一个时间(0~1000ms),谁先发谁就是老大。这招我在现场屡试不爽。
4.4 令牌环维护
环网建好之后,还得有人维护。维护工作主要包括三件事:
第一,节点丢失检测。如果某个主站挂了,令牌传过去就没人接,整个环就卡住了。我一般设一个令牌超时时间,比如 THT × 2。如果超时了还没收到下一站的确认,就认为那个节点丢了,直接跳过它,把令牌传给再下一家。
第二,新节点加入。系统运行中,可能有个新主站要加进来。我习惯的做法是:每个主站每隔一段时间(比如10秒)发一个“环网探测帧”,新节点收到后回复自己的地址。环主节点发现新地址后,更新节点列表,下次传令牌时就带上它。
第三,令牌丢失恢复。这是最头疼的。令牌可能因为干扰、节点掉电等原因丢了。我遇到过这种情况,整个环网静默了5秒钟,现场工程师差点把PLC重启了。
我的恢复策略是:每个主站都设一个总线空闲定时器。如果连续 N 个 THT 时间内总线上没有任何活动,就认为令牌丢了。这时候,环主节点重新生成一个令牌,从自己开始重新传递。N 一般取 3~5,太短容易误判,太长恢复慢。
避坑指南:我曾经把 N 设成 2,结果有一次某个主站处理任务慢了半拍,总线空闲了 1.2 个 THT,就被误判为令牌丢失,环主节点重新初始化,把正常节点都踢出去了。后来我改成 N=4,再没出过这种乌龙。
好了,令牌传递这块的核心内容就这些。说白了,令牌帧要短、持有时间要准、初始化要稳、维护要勤。你把这些搞明白了,Modbus多主站通讯的骨架就算搭起来了。下一节咱们聊聊实际工程中怎么选型,是走令牌还是走CSMA,到时候再细说。