CAN总线仲裁机制--对于多个节点同时发送相同ID的报文

最近在学习CAN总线,原先一直不太明白,若有A,B  2个节点同一时刻一起向总线上发送数据,CAN总线是怎么仲裁的,来让A,B其中一个节点退出,保证高优先级的节点优先传输,今天又在网上查了一些资料,总算搞明白了一些。

    在CAN总线上,若同一个时刻,既有节点向总线上发送隐形电平(1),也有节点发送显性电平(0),那么此时总线上表现出来的为显性(0)。

    当总线空闲时,有多个节点同时需要发送报文,那么每个节点的发送器将会对发送位的电平和被监控的总线电平做比较,如果电平相同,那么该节点可以继续发送,如果发送的为一“隐性”电平(1),但是监控到一“显性”电平(0),那么该节点失去仲裁,必须退出发送状态,只到下一次总线空闲的时候在参与总线的仲裁竞争。

     由以上也可以看出,当有多个节点同时争夺总线的控制权,ID最小的那个节点将会胜出,所以在CAN总线上,节点的ID越小,优先级越高。

     先列举2种特殊情况,根据仲裁来判断优先级。

     1.  若在同一时刻,标准格式的报文与扩展格式的报文同时抢占总线,且它们的基础ID相同,则发标准格式的报文节点就会PK成功。这是因为扩展格式在基本ID后,紧接着是SRR位,与IDE位,且这两位都是隐性位。而在标准格式中,这两位分别对应的位为RTR与r1,其中RTR既可以为隐性位,也可以为显性位,,但是r1必须为显性位。由仲裁规则可以此时标准帧必定胜出。

    2.  同理,如果在同一时刻,具有相同格式,且具有相同ID的数据帧与远程帧争夺总线控制权,那么数据帧必定胜出。因为RTR显性表示数据帧,隐性表示远程帧。

今天又发现了一个问题,前几天也是在21IC的论坛上看见有这样一条帖子,上面说如果有2个节点具有相同的ID,同时向总线上发送不同的数据帧,那么这两个节点将会继续仲裁数据场,只到有一方退出。开始我也是这样认为的,但是下午在看到CAN-bus规范V2.0上,关于应答场(ACK)部分的时候,想到了, 如果真是如上所述,就会出现一种比较奇怪的现象:

    即如果总线上,只有A,B  2个节点,当前只有A节点发送报文,B节点再接收,按照以上的观点,那么将会发生什么呢?在应答场(ACK)应答间隙(ACK SLOT)的时候,A节点将会发送一个“隐性”位(1),但是同时,B节点却会发送一个“显性位”(0)来以示应答(这里假设B节点正确接收到有效的报文),那么此时总线上表现出来就是“显性”(0)了。但是A却是发送的是“隐性”(1)啊,那么按照上述说法,此时A节点就要退出总线了,也就不在发送应答界定符(ACK DELIMITER)(显性1),了,此时总线上就会一直保持显性(0)状态,只到位错误的发生。

因此,以上说法是不成立的,其实由CAN-bus规范V2.0的P8页上有如下语句:

Arbitration
Whenever the bus is free, any unit may start to transmit a message. If 2 or more units
start transmitting messages at the same time, the bus access conflict is resolved by
bitwise arbitration using the IDENTIFIER
. The mechanism of arbitration guarantees that
neither information nor time is lost. If a DATA and a REMOTE with the
same IDENTIFIER are initiated at the same time, the DATA prevails over the
REMOTE . During arbitration every transmitter compares the level of the bit
transmitted with the level that is monitored on the bus. If these levels are equal the unit
may continue to send. When a ’recessive’ level is sent and a ’dominant’ level is
monitored (see Bus Values), the unit has lost arbitration and must withdraw without
sending one more bit.

    由以上红色部分可知,参与逐位仲裁的位只有仲裁场!!!

    那么如果有2个节点具有相同的仲裁场,但是他们的数据场不同,将会发生什么呢?我感觉可能在数据场之间可能会产生位错误(Bit Error),接收完CRC序列后,可能会发生一个应答错误,或者一个CRC错误。

### CAN总线同一时间多帧报文的存在可能性 在CAN(Controller Area Network)总线上,确实可能存在多个节点几乎同时尝试发送消息的情况。然而,由于CAN总线采用的是基于优先级的仲裁机制来处理这种情况,因此不会真正意义上存在“同一时刻”的多帧报文冲突。 当两个或更多节点试图在同一时刻传输数据时,具有较高优先级的消息将会成功获得总线控制权并完成其完整的传输过程[^1]。这种高优先级是由标识符(Identifier)决定的,在标准CAN协议中为11位,在扩展CAN中则可达29位长度。较低数值的ID意味着更高的优先级。如果发生碰撞,则通过逐位比较这些ID来进行裁决;拥有更小二进制值的一方将继续发送而另一方将停止当前的数据包传送,并等待下一个空闲时段重新发起请求。 对于那些未能赢得竞争的设备来说,它们会在检测到总线再次处于闲置状态之后立刻准备重试发送自己的信息。这一特性使得即使有多个节点想要立即通信也不会造成实际意义上的并发问题——即不存在真正的“同时”有多条不同内容的信息存在于总线上面的情形[^3]。 尽管如此,从应用层面观察可能会觉得某些时间段内似乎有很多不同的数据被快速连续地传递着,这是因为一旦某个节点完成了它的发送动作并且释放了总线使用权后,其他早已准备好要发言的成员就可以紧接着利用这段间隙迅速将自己的信号推出去。这样的现象虽然看起来像是瞬间出现了大量独立的消息片段,但实际上还是遵循上述提到的竞争解决原则有序进行着。 ```python # Python伪代码展示如何模拟简单的CAN总线抢占逻辑 class CanNode: def __init__(self, id): self.id = id def send_message(self, bus_state): if not bus_state or (bus_state and self.is_higher_priority(bus_state)): print(f"Node {self.id} sends message.") return True else: print(f"Node {self.id} waits to resend.") return False def is_higher_priority(self, current_id_on_bus): return int(self.id, 2) < int(current_id_on_bus, 2) node_1 = CanNode('000') # Higher priority node node_2 = CanNode('001') print(node_1.send_message(None)) # Node with ID '000' starts sending first. print(node_2.send_message('000')) # Lower priority node must wait. ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值