我对CANopen中的心跳协议有一个奇怪的发现。也许其他人已经看到了这样的东西,也许它应该像这样工作......无论如何,这就是它的内容:
在 CANopen 中有两种基于超时的生命保护机制:第一种是节点保护,我不再赘述,因为它被认为是老生常谈了。
另一种叫做心跳。这很简单:网络上的任何参与者都会发送一条常规消息,说明其节点 ID 和状态。频率由对象 0x1017sub0 定义,称为 heartbeat-producer-time。如果设置为零,则不发送心跳。
然后任何其他参与者都可以定义它想要在网络上找到的节点数量以及两个连续心跳消息之间可能存在的最长时间。此信息作为 32 位条目存储在对象 0x1016sub1..n 中,用于该特定节点想要监听的任意数量的节点。
这些条目由节点 ID(第 22 到 16 位)和提到的心跳之间可能经过的最大时间组成,称为心跳消费者时间(在第 15..0 位中)。同样,如果该条目为零,则将被忽略。
正如您可能已经收集到的,网络主机(节点 ID 1)和从机(节点 ID 2 到 127)之间没有区别。
到目前为止的理论,现在解决我的问题:
我将网络中的一个从节点配置为主节点的心跳消费者,因此对象 0x1016sub1 中有一个条目,如下所示:0x000107D0。这意味着至少两秒钟后预计会收到来自 master 的心跳消息。
我观察到这在两个示例中有效。如果我发送主心跳一段时间然后停止,节点要么返回到预操作模式,要么发送适当的紧急消息。
如果我不发送任何主心跳消息,我希望在我启动节点(将其发送到操作模式)之后,节点最多需要两秒钟才能返回到预操作模式或发送适当的紧急消息或什至两者兼而有之。但是在我尝试的两个示例中,什么也没发生。如果我从不发送任何心跳,则节点永远不会期待一个并且只是继续运行。
这两个例子彼此非常不同。我不确定他们是否使用相同的 CANopen-stack 库。
有解释吗?