BACRouter内置的Modbus 网关

因版本4.26于2023-03-07更新

从固件版本4.x起,BACRouter内置了Modbus网关功能。这篇文章尝试解释其底层运作机制。

Modbus 读

BACRouter周期性地读取点数据并缓存。“刷新间隔”定义读取数据的间隔。

为了提高性能,BACRouter将尽可能在一次事务读取更多数据。在Modbus标准中,最多2000个位(指线圈或离散输入)或125个寄存器(指输入或保持寄存器)可以在一次请求中读回,但是特定的Modbus从站可能不支持读取大量的数据。在BACRouter的WebUI的”从站设定“页面的Modbus参数对话框中,”批量读比特位数“与”批量读寄存器数“两个参数定义了从站的对批量读数据的支持。

BACRouter不会分段读取单点的数据,即使”批量读寄存器数“小于该点占用的寄存器数。

通常来说,我们关心的数据的Modbus地址并不连续,比如我们只关心地址为1及2000的线圈,虽然我们可以一次批量读回地址1~2000的数据,然后抛弃地址2~1999的数据,先读取地址1的数据,再发请求读取地址2000的数据的做法可能更有效率。”比特位跳过“与”寄存器跳过“参数定义了在两个我们关心的数据地址中间,有多少个无用的数据允许被抛弃。假设在上述例子中,”比特位跳过“设为1998,BACRouter将尝试一次性读回地址1~2000,抛弃中间1998个数据。倘若”比特位跳过“为1997,则BACRouter将分两次读取地址1与地址2000。因为中间跳过的1998个数据大于设定值1997。

在从站的配置页面,“编组读取”显示读操作如何编组,并可进行测试。请特别关注服务端报告的非法数据地址!

Modbus 写

BACRouter不会合并写请求。当接收到写指令时将马上发出Modbus写请求。

对于写单个数据,有两个Modbus功能号可供使用。例如,功能5为写单个线圈,功能号15为写多个线圈但写数量可以为1。有的从站只支持其中一个功能号。”写单个线圈”参数指定采用哪个功能号。

同样地,”写单个寄存器“参数指定用于写单个寄存器的功能号。假设有任一个BACnet输出对象映射到多个保持寄存器,这意味着从站支持功能号16写多个寄存器,”写单个寄存器“将被关闭,功能号16将被采用。

离线

如果任何读写请求失败,BACRouter将会重试,如果连续失败次数达到3次,BACRouter将认为该从站离线。在离线状态下,BACRouter将间隔”离线刷新间隔“时间重试该请求。

在离线事件中,BACnet侧的反应将在后面描述。

Modbus 串行总线

BACRouter支持在同一条RS485总线上,不同波特率、奇偶较验、RTU/ASCII模式的从站共存。在发出请求前,BACRouter将根据从站的设定切换串口的参数。

如总线上的两个从站拥有相同的从站地址但是波特率或RTU/ASCII模式不同,BACRouter可以无冲突地通信。但是如果仅依赖不同的奇偶较验来防范冲突并不可靠,因为有的从站并不检查奇偶错误。

单设备映射模式

如VBUS网络端口未使能,BACRouter将工作于单设备模式,每个Modbus从站将被映射到”应用层设定“中定义的BACnet设备的不同对象实例空间。每个从站将占据1000实例空间。

对象的实际名称为“主站名称|从站名称|对象名称”,名隔分隔符”|”可由用户在数十个字符中选择。

依据BACnet标准的推荐做法,BACRouter将为每一个从站创建一个结构化视图对象。

本模式下当从站切换到离线状态,所有点的可靠性将被设为”COMMUNICATION_FAILURE”,当从站重新上线时,随着点数据的更新,各点的可靠性将被重新置回到”NO_FAULT_DETECTED”。

虚拟设备映射模式

当VBUS网络端口被使能,每个从站将被映射为VBUS网络上的虚拟BACnet设备。虚拟设备的MAC地址将从1开始。

在本模式下,所有从站必须有一个唯一的“设备实例号”。从站的BACnet设备名称为”主站名称|从站名称”,其中”|”为可选择的名称分隔符。

在本模式下如果从站切换到离线,依据BACnet标准的推荐做法,对应的虚拟BACnet设备将停止收发包以模拟离线状态。当从站重新上线时后,当更新完所有点数据后,虚拟BACnet设备将退出离线状态。

从站状态

针对每一个从站,BACRouter在缺省BACnet设备内创建3个对象。一个名为”online”的二进制输入对象,代表从站的上线状态。一个名为”update_delay”的模拟输入对象,代表最近平均数据更新延迟(对比”update_delay”), 最后一个是名为”fail_rate”的模拟输入对象,代表相对长时间内的Modbus侧通讯失败率。

这些对象名均有“主站名称|从站名称|comm|”的前缀,其中“|”为可选择的名称分隔符。

对象实例号分配

对象的实例号单独进行定义。当对象编辑窗口提交时,如对象被启用,将分配其声明的实例号,如该实例号被占用,将自动选择一个可用的实例号。

值对象

值对象的特性与属入对象类似,如值对象映射到可写Modbus地址时(0X或4X),此时值对象的当前值可写,写入的值被转发到Modbus侧(有以下2个例外)。

例外1:如果AV对象映射到保持寄存器,其数据类型为自定义,且其绑定的脚本不支持输出,此AV对象为只读。

例外2:如果AV对象映射到多个保持寄存器,但“写单个寄存器“参数生效,此AV对象为只读。

输出对象

输出对象对应的点值仍然会被定期读回,且设置成对象的Relinguish_Default属性。如果读回的值与上次写入的值不匹配,BACRouter将把该对象的可靠性置为 “UNRELIABLE_OTHER”,BACRouter将尝试每隔一段时间重新写入。如“容忍不匹配”选项被启用,如果读回的值与上次写入的值不匹配,该对象的可靠性将不变,BACRouter将尝试以”离线刷新间隔“重新写入。(于v4.34版更新)

因为以上的验证重写机制,BACRouter禁止2个输出对象映射的可写Modbus地址发生重叠。

浮点数的NaN

NaN是IEEE-754标准规定的特殊值,其意思为非有效数,BACRouter不接受NaN(正负无穷大仍然被视为有效值).

当一个Modbus点被定义为单精度浮点或双精度浮点,且BACRouter读到NaN值时,该点对应对象的可靠性将被设为”UNRELIABLE_OTHER”。

脚本不支持的数据

如一个模拟量对象为自定义,当从Modbus换算到BACnet时,脚本报告不支持的数据,此对象的可靠性将被置为”UNRELIABLE_OTHER”。

对于一个AO对象,如从BACnet换算到Modbus时,脚本报告不支持的数据,此对象的可靠性将被置为“PROCESS_RROR”。

对于一个AV对象,如从BACnet换算到Modbus时,脚本报告不支持的数据,此输出尝试被放弃,对象的可靠性保持不变。

BACnet MSTP自动地址分配

因为固件版本3.x,于2020.3.25添加:

因为不能保证所有设备同时上电,目前没有任何一种自动地址分配方案能够完全避免MAC地址冲突,所以我们从固件3.x版中移除了自动地址分配特性。为了帮助确定当前总线的“最大扫描地址”与空闲的MAC地址,用户可以启用“侦听”模式,然后在“运行信息”页面中,找到“当前最大扫描地址”,再通过“最近活动的其它站点”,找到未使用的MAC地址。

MSTP总线上的每一个设备必须有一个独特的MAC地址。对于主站设备,合法的地址范围为0~127,而对于从站设备的范围为128~254。

通常MAC地址采有以下几种方式确定:拨码开关,板上跳线,HMI界面,固件传输等。有的设备支持通过BACnet写属性服务修改MAC地址,但是这之前,设备必须要有合法的MAC地址以接入BACnet网络。

如果独特的MAC地址能够自动获得,就象我们将笔记本接入家庭或办公网络一样通过DHCP服务自动获取,我们就可以节省大量的调试时间。

这里讨论了好几种方案.    目前看来委员会更倾向于 “零配置方案” (附录135-2012bb)

开源的BACnet stack已经实现了 “零配置方案”.

“零配置方案” 只适用于最大扫描地址为127的情况,且自动地址分配范围为64~127。如不满足,可能带来混乱。

为了避免以上限制, BACRouter实现了私有的自动地址分配方案,并且与“零配置方案”保持兼容。它有以下吸引人的特性:

  1. 从总线流量中学习最大扫描地址。
  2. 从最大的未使用地址开始分配。

所以用户可以更加自由地规划地址,例如,将0~30留给固定地址的设备,将最大扫描地址设为40。这样自动获取地址的设备接入总线后,将从高到低依次使用40~31的地址。

不管是“零配置方案”还是BACRouter的方案,当已经自动获得地址的设备从总线中断开后,再重新接入总线,非常有可能遇到地址冲突,因为在断开期间,其地址可能被其它新接入的自动获取地址的设备占用。(BACRouter可能更容易遇到问题,因为它的地址分配不是随机的), 所以

一定要在接入总线的情况下,给自动获取地址的设备上电。

MSTP支持扩展帧设备与旧设备的互操作问题

最早的BACnet MS/TP设计只支持NPDU长度到501字节,大幅地小于IP与Ethernet链路层的1497字节长度。这限制了MS/TP的传输效率,增加了应用层的复杂度,特别当两个IP或Ethernet子网通过MS/TP子网连接在一起的时候。

扩展帧设计用于解决这个问题。标准附录此处可见. 简要地说, 此附录增加了两种帧类型:

  • 32: BACnet扩展帧须应答
  • 33: BACnet扩展帧无须应答

帧类型32由帧类型5(BACnet帧须应答)扩展而来,特殊之处在于它以COBS规则编码及NPDU长度为502到1497字节。

同样地,帧类型33由帧类型6 (BACnet帧无须应答)扩展而来。

扩展帧支持从修订版16开始正式引入标准。但是现场及市场上仍然有大量的旧设备不支持。支持扩展帧设备与旧设备之间的互操作性值得探讨。

  • 非路由旧设备与支持扩展帧设备:因为所有发往旧设备的NPDU都是应用层包,在旧设备的Device对象或发出的确认服务请求中的”最大可接受APDU长度”参数限制了NPDU包的大小,所以这种配置没有问题。
  • 旧路由与支持扩展帧设备: 须经由旧路由转发到其它子网的NPDU,如果其长度超过501字节将无法被旧路由识别而丢弃,发送方也收不到”包长超出”的网络层拒绝包。甚而,旧路由的”最大可接受APDU长度” 参数有可能是由其它路由口的参数决定的 (BACnet标准允许这种做法),因而其封包长度可能超出501字节,此时发往旧路由的应用层包也可能被丢弃。因此这种配置可能造成互操作问题。

BACRouter在非常早的版本就支持了扩展帧。从固件版本3.18开始,我们在BACRouter的MS/TP配置中引入了”扩展帧支持“选项,如果在总线上有不支持扩展帧的旧路由,此选项必须关闭以避免互操作性问题。

值得注意的是,即使”扩展帧支持“选项被关闭,不象旧路由,BACRouter仍然与支持扩展帧的设备有良好的互操作性。

(截图于2021-08-05更新,因为扩展帧是标准修订版16的强制要求,所以从固件4.13起,我们把这个功能选项移入到扩展配置模式中)

针对BACnet MSTP的帧失步攻击

如前面的文章 “BACnet MSTP 帧失步” 所指, BACnet MSTP 有一个帧失步的设计缺陷,但是是否可以利用这个缺陷,在完全遵守协议的前提下,对MSTP总线进行破坏呢?

设计这个攻击,我们先做以下几个假设:

  1. 总线上至少有3个设备,MAC地址分别为1, 8, 10。其中设备1是精心设计用来发动攻击的,设备8与10是无辜的。
  2. 设备1支持扩展帧,设备8与10不支持。
  3. 这3个设备的定时器都足够精确。

设备1的工作流程如下:

  1. 得到令牌,发送A帧
  2. 传递令牌到其它设备
  3. 再次得到令牌时,发送B帧
  4. 传递令牌到其它设备
  5. 重复步骤1.

A帧是一个合法的私有数据帧,十六进制数据如下:

55 ff 80 ff 01 00 1d a3 02 2b 72 fe 55 ff 03 08 01 00 11 a0 ff 55 ff 21 01 08 00 09 ce d4 f3 55 ff 00 01 08 00 00 bf

B帧也是一个合法的私有数据帧,十六进制数据如下:

55 ff 80 ff 01 00 1d a3 02 2b fe dc 55 ff 03 0a 01 00 11 b1 ff 55 ff 21 01 0a 00 09 fd 8a 51 55 ff 00 01 0a 00 00 8c

如果没有帧失步,一切都将正常运行。但是可能几小时,也可能几天后,设备8对设备1发出的A帧失步了,错过了A帧的帧头(设备10如对B帧失步,也是同样的效果),则设备8继续扫描A帧的数据部分,发现另一个有效帧:

55 ff 03 08 01 00 11 a0 ff 55 ff 21 01 08 00 09 ce d4 f3 55 ff 00 01 08 00 00 bf

这是发给设备8的Test-Request帧,设备8等待Tturnaround后发送Test-Response帧进行应答:

55 ff 04 01 08 00 11 ae ff 55 ff 21 01 08 00 09 ce d4 f3 55 ff 00 01 08 00 00 bf

但是此时,设备1正在传出令牌:

55 ff 00 02 01 00 00 73

令牌帧与Test_Response的前8个字节冲突了,对于设备10来说,收到了几个错误字节后,继续扫描,在Test_Response的数据部分又发现了一个帧:

55 ff 21 01 08 00 09 ce d4 f3 55 ff 00 01 08 00 00 bf

对设备10来说,这不是发给它的帧,所以他进入SKIP-DATA状态,抛弃数据,等这个帧结束,但是直到设备8发完数据,设备10还差一个字节来结束帧,他将继续等待。

对设备1来说,它发出令牌帧后,收到如下数据:

55 ff 21 01 08 00 09 ce d4 f3 55 ff 00 01 08 00 00 bf

这是一个扩展数据帧,因为它支持扩展帧,所以他按 Addendum 135-2012an规定的流程校验帧头,发现数据长度过短,中断前帧后又开始扫描,发现新帧:

55 ff 00 01 08 00 00 bf

这是一个发给设备1的令牌帧,设备1又得到令牌,经过Tturnaround后,重新发送B帧:

55 ff 80 ff 01 00 1d a3 02 2b fe dc 55 ff 03 0a 01 00 11 b1 ff 55 ff 21 01 0a 00 09 fd 8a 51 55 ff 00 01 0a 00 00 8c

在前面提到,设备10还差1个字节来结束前面一帧,因Tframe_abort>Ttrurnaround,所以解析没有中断,B帧的第一个55字节被设备10抛弃,然后开始扫描新帧,发现了:

55 ff 03 0a 01 00 11 b1 ff 55 ff 21 01 0a 00 09 fd 8a 51 55 ff 00 01 0a 00 00 8c

这是一个发给设备10的Test-Request帧,事情又开始重复。

从上面可以看出,每个设备都严格地遵守标准,但是一旦帧失步发生,整条总线就永远地瘫痪了。

更多信息见:MSTP帧失步解决方案

MSTP帧失步解决方案

于2021.7.13更新

我们曾在下面的文章中讨论过BACnet MSTP协议中有帧失步的弱点:

BACnet MSTP 帧失步

针对 BACnet MSTP 的帧失步攻击

对于BACRouter 来说,怎么来防范这个漏洞呢?让我们从标准找线索:

9.5.2 变量

SilenceTimer(翻译为静默计时器): 名义精度5ms的计时器,每当总线上有活动或每发送一个字节后清零

9.5.3 参数

Tframe_gap(翻译为字节间隔): 节点在发送一个帧时,在两个字节之间允许的最长的空闲时间: 20位时间。以我们的经验市面上几乎所有MSTP设备的字节间隔为0

Tturnaround: 节点接收到最后一个字节与开始发送之间的最小时间间隔: 40位时间

Tpostdrive: 节点发送完最后一个字节的停止位,到关闭485的驱动器之间的最长时间: 15位时间

9.5.5 发送帧流程

当SilenceTimer小于Tturnaround时, 等待 (Tturnaround – SilenceTimer)时间

9.2.3 时序

驱动器关闭: 节点应该在一个帧的最后字节的停止位起的Tpostdrive时间内关闭驱动器。标准允许但不鼓励,在帧的最后一个字节后再发送一个填充字节,如果填充字节被使用,它必须是0xFF,填充字节不被认为是帧的一部分,且应该包括在Tpostdrive时间内。

(此处并不明确Tturnaround是否包括填充字节的时间,但是在135.1的测试标准的12.1.3.4章节就描述得很清晰:Tturnaround从最后一个字节的停止位后开始计时,如果节点采用了填充字节,则应该由填充字节前一个字节的停止位后开始)

如此可见,在一个正常帧内,2个字节之间的最大空闲时间为20位时间,如果计上前一个字节拖尾的“1”位,则最长的总线空闲时间为29位时间(假设前一个字节为0xFF)。

考虑到填充字节,两帧之间的最小总线空闲时间为:Tturnaround – Tpostdrive + 9 (填充字节拖尾的”1″的位数)= 34位时间

所以BACRouter采用一个改进的接收有限状态机:

  1. 在一个MSTP帧中,字节间隔如大于20位时间,认为MSTP帧中断。
  2. 总线空闲大于等于33位时间,认为新的MSTP帧出现。
  3. 为了尽量兼容部分不遵守Tturnaround的设备,所有在有效MSTP帧后的数据认为是新的一帧。

在115200波特率下,一个数据位的时间仅8.7微秒,为了精确地测量空闲时间,BACRouter采用了5微秒精度的定时器,它有效地防止帧失步出现,并且 在115.2kbps下达到98.8%的带宽利用率 因为BACRouter发包时精确地遵守40位的Tturnaround,没有浪费多余的等待时间。

一次最大发包数与根据令牌占用时间

从固件版本2.0开始,BACRouter引入一个新的特性:根据令牌占用时间的一次最大发包数。

在BACnet MSTP标准中,一个主站得到令牌后,可以发送“一次最大发包数”的包后,再传递出令牌。“一次最大发包数”的默认值是1。路由器作为流量汇聚点,提高这个值可以改进网络交换带宽,但是会增加令牌占用时间。大多数路由的建议值为5到20。

MSTP作为常见的现场总线,通常由控制器、传感器、执行器互联,这些设备构成直接的控制回路,数据交换延迟通常要得到保证。我们建议设备得到令牌的时间间隔要小于1秒 。

路由器发送的NPDU的长度通常在10~50字节之间。但是最大可达到501字节(或扩展帧的1497字节)。越大的帧需要越长的时间来收发。

对于需要回应的NPDU来说,路由器需要等待目标设备应答。通常目标设备需要更长的时间来处理长帧,即路由器需要等待更长的时间。

所以同样的“一次最大发包数”,每次路由持用令牌的时间变化很大,对MSTP总线的延迟保证非常不利。

为避免这个问题,我们引进“根据令牌占用时间”特性来限制路由器持有令牌的时间。这个特性启用后。路由器不计算发包数,而是计量持有令牌的时间,当时间达到:

每字节发送时长 * 32 * “一次最大发包数”

就不再发送新帧,并传出令牌。例如“一次最大发包数”为10, 波特率为76.8kbps,每字节发送时长为0.13毫秒,则最大令牌持有时间为:

0.13 * 32 * 10 = 41.6 毫秒.

这个特性可以通过WebUI方便地启用与关闭。

MSTP包延时保证

BACnet有两种类型的服务,分为无确认与有确认。有确认服务的发送者(客户端)会等待应答直至超时。

通常情况下,无确认服务的包延时不会带来副作用。但对于有确认服务的请求包与应答包,过长的包延时将导致应答包因为超时而被抛弃,浪费了通讯带宽。

更有甚者,过迟到达的应答包可能导致应用层的逻辑错误!原因如下:

有确认服务的请求包头带有一个InvokeID,值范围0~255。应答包有同样的InvokeID。客户端通过这个InvokeID匹配请求与应答。在一个繁忙的客户端,InvokeID会快速耗尽, 此时只能回收重用已完成的服务的InvokeID。

如果一个有确认服务的应答包被过分延迟,客户端可能因为超时而结束服务,其InvokeID被回收,并被重新分配使用。此时被延迟的应答包被收到后,其InvokeID将被匹配到错误的服务。例如:

  • 客户端发出一个WriteProperty请求A,写设备X对象Y属性Z,分配的InvokeID为0。写入成功,但此请求包或者应答包延迟了。
  • 客户端等待超时而结束服务,InvokeID 0被回收。
  • 客户端发出一个WriteProperty请求B,写设备X对象U属性V,InvokeID又分配到0。写入失败。
  • 请求A的应答包先到达,由其InvokeID匹配到请求B。客户端认为请求B写入成功,造成应用层逻辑错误。

对高速的链路层如以太网或IP, 包延时通常是可忽略的,但是对于MSTP,有很多原因将造成过长的包延时:

  1. 信号噪声造成的令牌丢失或冲突。
  2. 不适当的设备配置(波特率,最大扫描站号,最大发包数)。
  3. 过高的流量。
  4. 过慢的设备。

为了避免InvokeID冲突及提高网络性能,版本2.0及以上的BACRouter实现了10秒钟 (参考BACnet的缺省APDU_Timeout,从v4.17起此延时修改为6秒钟) 的包延时保证,在收到后不能在此延时内完全转发的包将被抛弃。

虽然此策略可能造成服务无应答,但是比起错误应答,无应答是可以通过应用层的重试机制处理。

MSTP 固定/自动/强制 波特率

更新于2020-11-20(文末添加江森DDC内容)

MSTP的波特率设置一直是个现场工程师头痛的问题,如果设备的波特率设置有误,就无法加入MSTP网络中。

大部分设备采用固定的波特率,如需修改波特率,工程师必须接触到设备并调整DIP开关。有的设备支持通过BACnet服务修改波特率,但是在这之前,设备必须要能接入到BACnet网络中。

有的厂商实现了自动波特率配置,但是也带来了更多的问题,目前市场上的自动波特率有两种类型:

  • 启动时探测:设备在启动时监听总线并探测波特率,随后一直以该波特率运行。
  • 动态探测:设备不但在启动时探测波特率,在运行中如果在一段时间内持续发生通讯错误,即认为波特率改变,重新探测波特率。

不管是哪种类型,在总线运行时改变波特率都是非常困难的。仅仅改变所有固定波特率设备的设置是无法影响总线波特率的,因为其它自动波特率设备仍然以旧的波特率运中。唯一可靠的方法是在改变所有固定波特率设备的设置后,关掉所有自动波特率设备,再启动所有自动波特率设备(不能一个接一个的重新启动自动波特率设备!因为仍在运行中的自动波特率设备将维持总线波特率)

BACRouter的新版本固件(版本>=2.0)引入了新的波特率管理机制(专利申请中)。BACRouter有三种波特率模式:固定/自动/强制。

  • 固定波特率模式与传统的固定波特率一样
  • 自动波特率模式类似于前述的动态探测。重新探测的条件是10个连续的错误帧,通常只需要几秒钟。
  • 强制波特率模式类似于自动波特率模式,区别在于其在得到令牌后,将波特率改为预设的波特率。

当总线中有一个强制模式设备时,总线的波特率将会强制运行于预设值,而其它自动模式设备将自动同步波特率。固定模式但波特率设置值不同于预设值的设备将无法出现在总线中(通过检查BACRouter的运行信息中的“最近活动设备”项将很快地把这些设备找出)。对于上述的启动时探测设备,如果其探测到的波特率不同于预设值,也无法出现在总线中(同样可以通过检查BACRouter的运行信息中的“最近活动设备”项找出),但只需将其一个接一个的重新启动即可(不需全部断电,再全部上电)。

多个强制模式的设备可以共存在总线中,但这些设备中的波特率预设值必须相同。

江森自控的FEC与IOM模块即采用动态波特率,经测试,当波特率不匹配时间到150秒左右,模块开始重新检测波特率。

在BACRouter与FEC2611及IOM3731组成的测试总线中,双方完美协作,总线波特率可由BACRouter控制在9.6k~76.8k之间动态切换,FEC2611与IOM3731会延迟2.5分钟后刷新波特率。

BACRouter版本升级记录

旧固件底层OpenWRT

5.06 2024.10.15  下载

修复一个从4.19起引入的bug:  当升级固件时,如解压速度快于浏览器的传输速度,升级将失败(报告无效固件)。因为无法有效重现,我们很长时间不能定位故障。重启浏览器并重试可能有用,但如果是通过互联网升级,可能无法起效。

BIP bug: BDT重复表项检查逻辑

WebUI bug: BIP端口冲突检查逻辑

自由协议bug: 输出对象的present_value被修改时,脚本应得到通知。

5.04 2024.04.19  下载

Modbus/自由协义 bug:  设备运行信息可能无法从后台读到。

自由协议: API趋于稳定。

5.03 2024.03.20

支持设置动态IP

Modbus模块从5.00起有一个bug: Modbus地址设置从点属性编辑窗口返回时不能保存。

5.01 2024.01.23

v5.00从旧版本升级时有一个bug阻止界面显示。

5.00 2024.01.05

增加自由协议模块以脚本支持各种RS485与TCP网关功能。API手册正在编写中

Modbus网关功能在v4.34引入一个bug,当写入映射于寄存器部分位的多态对象时将触发。

COV通知功能对多状态输入对象有一个竞态bug.

RS485 现在有两种无校验方式:无校验2停止位,无校验1停止位。通常无校验2停止位可以正常工作,不管对方的停止位怎么设定。但是对于某些诡异的Modbus设备,不遵守应答前静默3.5T的约定,如江*的TMS2000温控器,只有设为无校验1停止位才能工作。

4.35 2023.11.15  下载

网络层bug修复: 当缓存无法路由包时缓冲溢出。

4.34 2023.09.04

135-2016br-2: 接受写NULL到不可命令属性。

MSTP驱动立即向上层报告新包,而非以20ms的周期。

Modbus脚本: context参数携带点名与点描述。

Modbus支持2个寄存器的多状态点。

Modbus支持映射到寄存器部分位的模拟量。

Modbus支持自定义模拟量映射到多达24个寄存器。

Modbus映射输出对象时增加“容忍不匹配”选项,当回读数值与上次写入数值不匹配时,可靠性属性不变,并以“离线刷新间隔”重复输出。

Modbus驱动移除一些不必要的优化:将对同一个寄存器的多个写请求合并为一个;缓存模拟量从Modbus到BACnet的换算。

X2BACnet工程转换支持早期的X2BAC版本。

4.3201 2023.03.30

v4.23 引入的Modbus后台bug:

RTU/ASCII可能无法工作于低波特率下。

TCP从站如报告错误码将导致程序崩溃。

4.31 2023.03.23

WebUI: 在Modbus的从站设定页面,用户经常错点“编辑”与“复制”按钮,影响生产力。“编辑”按钮被删除。用户可点击点名或属性,弹出点编辑窗口。

4.3002 2023.03.20

一个长期的BACnet Bug: 当写属性的APDU中的优先级参数被忽略时,没有设置默认的优先级。

Modbus: 映射到保持寄存器的BV/BO,当选择写功能码时,应参考“单寄存器写”而不是“单线圈写“

Modbus: TCP从站地址范围由1~247扩展到0~255

Modbus bug 由v4.23导入: 离线设备可能增加在线设备的失败机率。

WebUI: Modbus“读测试”与”写测试”时将报告更详细的出错信息。

WebUI: Modbus参数编辑时的UI优化。

WebUI bug 由v4.25引入: Modbus “写测试“ 应不能在映射到只读Modbus地址,或BACnet对象类型为输入时启用。

WebUI: 当Modbus”写测试”写到多个寄存器时,提醒用户注意“单寄存器写“设定冲突。

WebUI: 在从站设定中启用拖放式移动点。

WebUI: Modbus多态点编辑时,启用拖放式移动状态定义。

4.29 2023.03.14

WebUI: 当导出到文件时,弹出窗口以便修改文件名。

4.28 2023.03.11

WebUI修正: Modbus 从站的”复原”按钮无法回滚”批量数据地址“所做的修改。

WebUI: Modbus从站增加”重排实例号”功能。

4.27 2023.03.09

所有包捕捉缓冲区总和限制从16M改到12M.

WebUI修下: Modbus从站的”批量换算”功能应跳过自定义类型。

WebUI: 导出的Modbus主站/从站配置应携带引用的脚本。当导入配置时,脚本也将被导入。

4.26 2023.03.06

BIP UDP 端口的最小值改为1024

许多脚本功能的Bug修正及改进:

当发生内存不足时,所有的脚本将被一个个地临时卸载,在卸载过程中回收的内存将被记录。回收内存最多的脚本将被视为存在内存泄露并被强制完全卸载,其余的脚本重新装入执行。

WebUI 增加脚本运行信息,以方便找到内存泄露。

脚本导入将跳转到编辑模式

创建与导入的脚本在经确认后,可以替换同名旧脚本的内容。

4.25 2023.03.02

我们经常接到用户反馈一些奇怪的Modbus设备,它们的寄存器无法线性地换算到BACnet模拟量的浮点数,所以我们引入了Lua脚本功能以处理这些映射。

用户可以在WebUI上新建、导入、编辑Lua脚本,感谢现代浏览器对WASM的支持,用户甚至可以在Modbus设备不在线的情况下,通过WebUI运行、调试Lua脚本,运行错误将由WebUI捕捉并展示给用户,Lua的print函数将输出到浏览器的终端。

负面影响是从此版本开始,我们不得不停止支持IE浏览器(但Edge仍然可以完美兼容)

目前Lua脚本的创建功能将生成一个映射Modbus BCD码的样例脚本

修正了v4.23引入的Modbus bug: AO对象持续报告可靠性问题。

4.24 2023.02.20  下载

从v4.23开始,我们对Modbus rs485驱动进行了抽象,以便在将来支持通用的rs485设备。当然这引入了Modbus网关串口功能一些bug(MSTP使用不同驱动,所以不受影响),这个固件修复了其中的一些:

离线设备引发程序重启

WebUI的串口Modbus设备的点位裸测试结果中的响应时间不精确。

4.23 2023.02.14

修复: 当Modbus模块将Ananlog_Output映射到多个寄存器上时的缓冲溢出

BIP 支持PPP接口以方便VPN连接

4.22 2022.11.22  下载

修复Modbus模块Bug:当一个TCP主站下定义了多于一个从站,且“连接保持时间”为0时可能被触发。

4.21 2022.11.13

WebUI 不再支持 IE10。

运行信息中的历史统计数据可以被重置。

MS/TP运行信息中用不同颜色的MAC地址表表示不同的状态。

4.20 2022.07.25

支持单口路由.

4.19 2022.05.20

Modbus网关导入CSV功能:

1. 修正从第2个点开始Modbus数据类型被忽略。

2. 状态未定义的多状态点不必被强制停用。

4.18 2022.02.07

从版本v3.00起,  我们加入了一个数据完整性检查: 如转发的NPDU的hop count为255,将被认为是错误并丢弃。用户可以从日志上看到相关信息:[WARN]npdu_decode_pci: hop count should not be 255 for relayed npdu.

但这个行为可能导致与其它路由器的兼容性问题。虽然此处的hop count不正确,但是因为BTL测试没有完整覆盖相关内容,市场上仍有一些经BTL认证的路由器有此错误。

相关的细节请查看:  https://hvac-talk.com/vbb/threads/2098761-BACRouter-from-China/page11, 非常感谢MaxBurn报告并协助我们定位问题。

解决方案是将hop count改为254并接受NPDU。用户可以从日志上看到:[WARN]npdu_decode_pci: hop count should not be 255 for relayed npdu, change to 254

4.17 2022.01.10

提供更多信息的日志

ReadPropertyMultiple: 构建大的回应包的可能的缓冲区溢出

当设备实例号被BACnet服务修改时可能造成冲突

当处理write-bdt bvll请求时,如BDT无变化,不触发配置保存动作,以延长flash寿命。

当VBUS的网络号被initialize-routing-table请求修改,如正在处理到虚拟设备的确认请求,当造成冲突。

MS/TP由4.10版引入的bug,在收到错误的帧头时可能引发时序错误。

4.16 2021.12.13

BBMD: 广播分布推送时遗忘了本地BBMD.

Modbus: 主站复制时WebUI bug.

4.15 2021.9.15

Modbus: 更方便的主站/从站复制功能.

Modbus: 支持批量修改从站的Modbus参数.

Modbus: 多状态对象可以映射于寄存器内的部分位(不必映射于整个寄存器).

4.14 2021.8.25

紧急升级功能存在一个bug导致旧的配置未被删除,如旧的配置有错误可能导致WebUI无法使用。如果旧版本固件因为配置问题无法使用,请用本固件紧急升级两次,第一次将升级固件,第二次就会删除旧的配置。

修复Modbus虚拟设备模式的bug,此bug在虚拟设备数量大于5时触发。

修复WebUI当导入的Modbus从站数量超过限制时的bug.

Modbus主站与从站的数量限制由100改为128.

修复WebUI停用“包捕捉映射”的bug.

为兼容更多的上位机系统及DDC编程软件,增加多个名称分隔符选项,修正内部对象名以避免与新增加的分隔符冲突。

4.13 2021.8.5

Modbus从站设定增加“批量地址”功能。

MS/TP扩展帧支持选项移到扩展配置模式中。

4.12 2021.7.23

从3.x开始的一个长期bug可能导致ms/tp端口停止工作。

4.11 2021.7.16

在4.10版本中MS/TP更新时序引入一个bug,由高等级编译优化引发。

4.10 2021.7.13

BACnet 协议版本号改为16

Polarity在Binary Value对象中是私有属性

MS/TP更新时序以兼容填充字节

Modbus 主站: 批量导入,批量实例号,批量点表

Modbus 从站: 导入点表

Modbus 主/从站: 复制与上下移动的UI.

4.09  2021.7.02

兼容新硬件变更.

BTL兼容性: max_info_frames与max_master在BACnet侧可写

4.08  2021.6.22

BTL 10.2.3.6 要求路由在发送拒绝包之前先尝试查找下游路由。

修复bug。此bug当VBUS被使能时可能被触发。

4.07  2021.6.13

修正4.05版引入的bug,此bug可能造成特定情况下无法进入配置界面。(请注意在http://IP/app/upgrade有一个后备升级固件的入口)

一些UI的小修正.

4.05  2021.6.7

Modbus对象名移除最顶层的”modbus_master”.

对象名分隔符”|” 改为可配置.

值对象允许与输出对象重叠.

一些界面修正

4.04  2021.6.1

大量的Modbus网关功能的更新:多状态对象,值对象,二进制文本,编组读取,批量换算,导入导出CSV点定义

转换BASgatewayLX的CSV格式配置文件

4.03  2021.4.23

Modbus网关

离线配置

3.23  2021.3.19

包捕捉到BACnet的映射模块的Bug被修复。此Bug可能导致包捕捉功能在BACnet侧启用时,后台程序崩溃重启。

修复Bug当扩展帧支持未被启用时,在ms/tp端口发出的请求中携带的max_apdu_length_accepted参数未正确设置。

WebUI的”系统设定“页面加入更多的信息,如全部/剩余内存,启动计时。

3.21  2021.2.22

MSTP从站代理的bug修复:当从站绑定失效时守护程序崩溃与重启问题。当在其它端口发送I-Am应答时的Hop count不正确问题.

APDU应答包及网络层拒绝包同样必须遵守目的网络的忙碌状态。

3.20  2021.1.26

取消创建网络端口的限制,现在只有总网络端口数量的限制。这将大大方便用户修改与切换端口的配置。

如果root密码还未被设置,在“系统设定”页内设置root密码的按钮将以红色字体提醒用户。

3.19  2021.1.20

在3.18上可能偶然地触发一个芯片的bug造成MS/TP无法启动

3.18  2021.1.18

MS/TP配置增加”扩展帧支持”选项.

网络层拒绝包应采用单播以遵守BTL测试标准。

外部设备的存活时间应加上30秒以遵守BTL测试标准。

发往广播地址的确认服务应在应用层被丢弃以遵守BTL测试标准

BBMD应丢弃相同UDP端口且单播的本地IP子网的转发包.

“同子网多个广播管理设备”逻辑在查找BDT表时遇到不同UDP端口判断出错的Bug被修正。

3.17  2021.1.13

WebUI 增加网络层设定页面,该页面可以显示路由表。

修复一个从设备代理的bug:当收到一个发往从设备的单播who-is时,服务所携带的设备id范围参数也必须被遵守,就如同广播的who-is。

3.15  2020.10.26

MS/TP加入了从JCI的FEC2611与IOM3731地址冲突中学习到的检测算法.

3.14  2020.10.23

MS/TP加入了地址冲突检测功能,冲突的地址会用红色显示在“最近活动的其它站点”中。因为MS/TP在冲突场景下的表现非常多样复杂,该检测并不准确,只能用于参考。

修复了由3.0版本引入MS/TP底层状态机潜在bug.

3.13  2020.10.5

基于测试及用户反馈,许多(可能是大部分)设备没有遵从BACnet标准中MS/TP接收有限状态机在遇到错误时的处理方式。我们私有的 “超时中止“特性在这种情况下并不能按预期工作,甚至造成性能下降。因此”超时中止”特性被移除。

MS/TP的运行信息页面增加更多的统计信息。

从3.08版本引入的WebUI在BIP的外部设备模式下的Bug被修复。

3.11  2020.7.14

修正mstp对错误包的占用时间计算错误。

修正3.08引入的mstp从站代理的bug

一些小的UI改进。

3.10  2020.7.1

因为从2.x升级到3.x,很多配置项改变。所以在3.00~3.09版中,升级固件时,升级脚本将安装新的配置文件。在这个版本中,升级功能增加一个“保留配置”的选项。如果配置文件错误,在打开WebUI时将有一个警告。

3.09  2020.6.30

修正3.08版本引入的读取mstp运行信息时的错误。

一些小的UI改进。

3.08  2020.6.28

修正: 单跳方式的广播分布在标准中只是可选功能。从版本3.00起,如果跨网广播支持被选中,BACRouter将强制其它广播管理设备(BBMD)使用单跳方式。这是不正确的行为,在此版本中得到修正。

广播分布表(BDT)的编辑方式得到改进。当提交时,广播分布表(BDT)中的表项将得到检查,排除可能错误配置。这种检查在收到BDT BVLL包时,同样执行。

如果同子网多个广播管理设备(BBMD)未被选中,当收到未记录在本地广播分布表(BDT)中的广播管理设备(BBMD)发来的转发包时,将记录并丢弃该转发包。此功能在绝大多数场合中将有助于识别BBMD的配置问题。上一版本的“报告多个广播管理设备”功能被本功能覆盖,所以取消。

下载配置的文件名设置为IP_版本号.json,例如:192.168.100.1_3.08.json

上传配置将先读入到WebUI中进行编辑,方可保存。如此可避免潜在的版本兼容问题。

3.06  2020.5.22

因为Ethernet端口现在已很少用到,缺省将其关闭,同时如果BIP与Ethernet同时被启用,将弹出警告,提醒用户注意可能的路由回环。

将默认的捕捉缓冲区大小增加为4M。

3.05  2020.5.15

包捕捉功能映射到BACnet。 每个链路层端口都有独立的”Capture buf_size”与”Capture command” 多状态值. “Capture buf_size”可以在”64K”到”16M”之间设置。 “Capture command”可以在”Stop&Clean”, “Start”, “Stop”之间设置。

此功能应国外用户需求开发,使用场景如下:路由默认开启包捕捉。当上位机发现某设备的通讯异常时,可以停止路由对应端口的包捕捉(使用“Stop”保留捕捉数据,而不是”Stop&Clean”),然后通过邮件提醒管理员,从WebUI读取当时的包捕捉数据进行分析。

3.04  2020.4.28

增强安全性,由WebUI可修改root密码。

3.03  2020.4.23

BACRouter以Initialize-Routing-Table包查询路由表的方式, 确认其它的路由器仍然存活。但是附录135-2012AL移除了路由器对Initialize-Routing-Table的强制支持。本版本增加通过Reject-Message-To-Network包确认路由存活的方式。

BIP BVLL对转发 (Forwarded) 的NPDU的包头要比其它的包头长6个字节,老版本在较验转发的NPDU包长时有个隐蒧的Bug,本版本已得以修正。

3.02  2020.3.26

UI的小修正

3.01  2020.3.17

系统设定增加下载配置与上传配置功能

3.00  2020.3.10

增加包捕捉功能:

所有端口均支持包捕捉。

因为Wireshark不支持MSTP扩展帧解析,扩展帧在下载时转为常规数据帧(幸运的是,Wireshark并不抱怨长度溢出)。

MSTP支持包间隔格式,可以在Wireshark中以5us精度显示包前的空闲时间,是时序与性能分析的利器。

支持持续化包捕捉,提供API接口,方便自动化流量记录。

MSTP移除自动地址探测功能。因为设备无法保证同一时间上线,无法完全避免地址冲突。如现场调试时,需要知道可用MAC地址及最大扫描地址,可以采用下述方式:开启侦听模式,从运行信息得到“当前最大扫描地址”及“最近活动站点”。

MSTP增加最大扫描地址实时分析功能,在运行信息中显示,如与配置值不符,将提示“不匹配”

MSTP增加侦听模式,可以在不干涉总线运行的前提下,检测总线运行情况。

MSTP的Web配置界面,提供简单模式与扩展模式选择。

MSTP的所有超时改为浮点数,方便精确定义。

MSTP从设备代理前版只支持广播的Who-Is查询,现版本增加支持单播的Who-Is查询

MSTP从设备代理前版应答I-Am采用网内广播,现版本采用单播

MSTP从设备代理功能修正前版中分析Who-Is查询的路由来源的漏洞。

BBMD增加选项在发现内网有多个BBMD时错误报警。

对2.17版提供功能的修正,增加“接受不匹配的目标地址”选项,如果启用,仅打印报警信息,如果未启用,打印错误信息并丢弃。

很多的WebUI小改进。

2.18  2019.4.16

提高了IP与以太网口的性能

在Unconfirmed COV通知中的进程0保留给未订阅的COV通知,当没找到进程0时不再报告错误。

2.17  2019.4.2

在前版中,当从单播地址接收到Original-broadcast BVLL包或从广播地址接收到Original-unicast BVLL包,认为是个错误而丢包。有客户报告江森的CCT用单播地址发送Original-broadcast BVLL包,所以此版中仅打印报警信息。

2.16  2019.2.25

从版本2.0.8起,  仅支持转发私有的网络层包,其它不认识的网络层包将被拒绝。此行为不利于支持标准的升级。本版本中所有不认识的网络层包均支持转发。

2.15  2017.10.19

重定向 URL “/” 到 “/?” 以支持Edge 浏览器 (否则将不停地要求认证)

修正MSTP标准状态机中的Bug: 令牌重复可能导致转发令牌给自身.

MSTP标准状态机中,当设备处于单主机模式下,其开始查询一个主站后,发送max_info_frames * Npoll 个帧。修改为更合理的行为:当结束查询所有主站后发送max_info_frames * Npoll 个帧.

2.14  2017.10.13

修复从2.0引入的Bug,当MSTP发送Expecting reply请求到255地址时,不必等待回应。

2.13  2017.9.19

当MSTP自动地址分配与波特率强制功能同时启用时,隐藏的bug可能(极其罕见的条件下)引发。

2.12  2017.7.10

优化路由表项保护功能: 来自下一跳的删除将跳过保护.

支持采用6.5.3中查找网络路由地址的方法1与4的设备。

2.11  2017.6.16

此次更新有助于在大型BACnet互联网络中快速建立路由表。

当BACRouter启动时, 广播一个无目标网络号的Who_Is_Router_To_Network以学习其它路由的信息.

当收到无目标网络号的Who_Is_Router_To_Network/Router_Busy_To_Network/Router_Available_To_Network, BACRouter回复的网络号最多可达1120个(对比前版本的112个).

2.10  2017.6.13

错误修下: ReadRange在读取property_list不应返回以下三个属性: object_identifier; object_name; object_type.

启动时延时1秒发送Network_Number_Is,因为如果路由器做为BIP的外部设备,此时注册流程尚未完成。

2.09  2017.6.10

保护路由表项从最后活动计起60秒,避免路由回环时的广播风暴。

2.08  2017.6.7

错误修正: 正确转发私有的网络层包.

转发Reject-Message-To-Network(原因4,包太长)时,使用单播地址.

修改后台的最大apdu重试为10,与WebUI一致。

2.07  2017.6.5

遵从BACnet Router与BBMD的设备描述.

如果没有收到Who_Is_Router_To_Network或Initializing_Routing_Table包的回应, 删除无效的路由. 此特性有助于从错误的网络配置中恢复.

在网络回环时(当配置错误时), 避免发送过多的I_Am_Router_To_Network.

减少复杂网络下的内存消耗.

2.06  2017.6.1

避免BBMD广播风暴.

广播发送转发的Reject-Message-To-Network包(只针对拒绝理由1,2,4).

抛弃含有错误路由信息的Reject-Message-To-Network包.

检查NPDU包头的源网络.(对Initializing-Routing-Table包特别处理)

2.05  2017.5.23

修正全局广播的initializing-routing-table请求未执行的错误.

修正WebUI BIP的模式选择未提交即生效的错误.

限制运行信息页面的路表项个数,以避免在大型互联网络中的请求失败。

2.04  2017.5.11

修正WebUI较验BDT时的错误.

当收到reinitialize-device服务请求时保存配置重启。

2.03  2017.5.7

BIP BBMD NAT模式支持端口号修改。

BIP BBMD NAT模式不监听本地广播地址及发送本地广播

BIP BBMD 外部设备模式不监听本地广播地址

2.02  2017.5.5

当收到Who-Is-Router-To查询时,假定源设备没有该路由(从路由表中删除)

当Initializing-Routing-Table修改了网络号,重新发送I-Am-Routr-To-Network以报告新网络号

修正v2.0引入的错误:保存BVLL Write-Broadcast-Distribution-Table修改的BDT表时出错

2.01  2017.5.3

增加后备的升级入口 http://ip/app/upgrade

更直觉的日志信息

改进网络层拒绝行为

修正发送I-Am-Routr-To-Network时的溢出(当报告的网络数量超过1476/2时)

以动态时间间隔发送I-Am-Routr-To-Network.

2.0  2017.4.19

提供选项启用路由内的设备对象。.

允许从BACnet端修改配置

支持What_is_Network_Number and Network_Number_Is 网络包

提供MSTP max_info_frames的by occupy time选项

实现新的MSTP自动/强制波特率机制.

MSTP包最大延迟保证(10 seconds).

WebUI界面更智能.

1.22  2016.10.26

将路由表项的数目由1024增加到65534(即没有限制).

1.21  2016.10.18

从设备代理: 如果对方是快速设备加快ReadProperty(Multiple)的发送速率.

BVLL回应NAK当收到BBMD相关的请求,但BBMD未使能. (附录135-2012ax-5)

BVLL回应NAK当收到Distribute-Broadcast-To-Network请求,但源设备未注册为外部设备. (附录135-2010ad-10)

1.20  2016.10.8

BIP提供选项接受发往255.255.255.255的广播报文

BIP外设设备模式的注册时间间隔的最小值从30秒减少到15秒。

1.19  2016.9.23

webui如果IP/掩码/网关/DHCP没有改动,采用快速重启

MSTP加入快速设备超时中止功能

MSTP快速设备最小超时改为0ms(实际是收发切换后1.5bits加上50us)

MSTP快速设备令牌传递超时最小值设为20ms

MSTP运行信息显示最近10秒活动的设备

1.18  2016.9.13

BIP BBMD 支持NAT,增加两个参数”接受BDT表写入“与”接受外部设备注册”

在“配置”页面显示以太网地址

1.17  2016.9.8

应某些OEM用户需求,登录认证的域名可以由用户定制。

1.16  2016.9.7

修正从站代理应答Who-is但查询到的设备并没有在该入口代理。

修正写远程BBMD的BDT表错误

许多的界面改进

1.15  2016.9.1

加入了从设备代理功能.

MSTP加入了无切换延时桢计数及带填充字节桢计数

一些界面改进。

修正无切换延时桢紧跟带填充字节桢时的解码错误

1.14  2016.8.24

这是一次大升级,比较多的修订:

MSTP增加令牌超时、回应超时配置项。

MSTP增加快速设备功能,允许指定设备使用小至1毫秒的令牌超时与回应超时。

MSTP增加运行诊断信息含地址冲突,发送冲突、令牌冲突、令牌丢失,令牌转发失败、无应答、包错误。

MSTP增强对不遵守40bit发送切换要求的设备的兼容性

MSTP修正发送扩展桢的编码错误

MSTP修正特定条件下应答测试桢的CRC错误

1.13  2016.8.16

底层api改动,对本软件无影响

1.12  2016.8.12

加入系列号

1.11  2016.8.10

固件文件名带版本号及校验字串。

左边树型菜单处显示版本号。

重启及升级固件后,自动刷新。

修复一些界面bug

BACnet MSTP的令牌转发性能

在BACnet标准中,MSTP的最高波特率为115200bps,一个token包的长度为8字节,在两个包之间至少还要有4字节的切换时间(Tturnaround = 40bits),所以理论最高令牌转发率为115200/(80 + 40) = 960次/秒。

但是实际上市场上大部分产品的底层实现,都难以达到,造成MSTP的实际带宽受限,甚至造成丢包或丢令牌。

目前我司的产品上的进行的测试,4个节点,mac address从0~3, max_master=3,网络层静默,测得令牌转发率为948次/秒,带宽利用率98.8%.

在每秒一个读属性请求(23字节),一个读属性应答(29字节)的条件下,测得令牌转发率为943次/秒。

我司的协议栈是在完全满足标准时序要求下,基本榨干了MSTP的性能。

更新,2017年2月,我们在上述配置下做了ReadProperty服务的压力测试,把4个节点的max_info_frames均设为10,2个节点请求,2个节点响应。最后的结果每秒钟完成153~154个服务。

更新,2017年3月,现在通过详细的运行信息,用户可以方便地得到令牌转发率数据。在发布新一版固件9个月之后,我们重新做了上面的测试,这次的结果是每秒956.6次的令牌转发率,99.6%的带宽利用率。