五分钟教会如何计算CAN总线负载率,包学包会

最近某个工作项目中需要计算CAN总线上的负载率,这个东西从字面上来理解是很简单的,就是指总线上所有节点在单位时间内发送的所有数据占整个总线理论带宽的比值,或者说,总线实际数据传输速率与理论上能达到的数据传输速率的比值。

当然,想要真正的计算出实际项目中的负载率,肯定是有一个公式可以套用的。本想偷懒一下去找现成的,但是在网上一番搜寻之后却发现,没有任何一篇文章把这个事情简单而精准的解释清楚的。算了,自己来。

开始之前先给一个简单的例子,比如在一个波特率为500Kbps的总线上,理论上每秒钟能够传输500000个BIT,而如实际上只传输了100000个BIT,那么就可以得到此刻的总线负载率为100000/500000=20%。当然,这只是一个非常粗糙的示例,真正的计算过程肯定要复杂一点。好,下面就开始实际的推导过程:

首先给出核心公式:

负载率R = 每秒钟实际上传输的所有数据的BIT总数A / 每秒钟理论上所能传输的BIT总数T

很简单的,对于指定了波特率的某个CAN总线,上述公式的分母T是恒定的。就比如上述示例中,波特率为500kbps的总线上,理论上每秒钟能够传输500000个BIT。而如果波特率为250kbps,那么就能传输250000个BIT。所以,我们只要计算上述公式中的分子A即可。

每秒钟实际上传输的所有数据的BIT总数A =
[该秒内所发送的所有ID1报文的所有BIT总数A1] +
[该秒内所发送的所有ID2报文的所有BIT总数A2] +
…… +
[该秒内所发送的所有IDn报文的所有BIT总数An]

其中:

该秒内所发送的所有ID1报文的所有BIT总数A1 = ID1的每一个报文的BIT总数Z * ID1的发送次数K

由于ID1的发送次数K是明确的,比如按照50ms的间隔发送,那就意味着一秒钟内的发送次数是20次。所以,我们只需要计算出“ID1的每一个报文的BIT总数Z”即可;

ID1的每一个报文的BIT总数Z = 实际报文数据帧的BIT总数Zg + 帧间隔的BIT总数Zy

对于标准帧和扩展帧,上述的值是不一样的,如下:

  • 对于CAN标准帧:假设数据帧长度恒定为8个字节,可以得到每一个数据帧最大长度共计108bit,分别为:帧起始(1bit)、仲裁域(12bit)、控制域(6bit)、数据域(8×8bit)、循环冗余码域(15bit)、1bit分隔符、应答域(2bit)和帧结尾(7bit);
    五分钟教会如何计算CAN总线负载率,包学包会
  • 对于CAN扩展帧:假设数据帧长度恒定为8个字节,可以得到每一个数据帧最大长度共计128bit,分别为:帧起始(1bit)、仲裁域(32bit)、控制域(6bit)、数据域(8×8bit)、循环冗余码域(15bit)、1bit分隔符、应答域(2bit)和帧结尾(7bit);
    五分钟教会如何计算CAN总线负载率,包学包会

而帧间隔的BIT总数,根据CAN协议的规定,都是3个BIT。

所以,对单个数据帧来说,完成一帧标准帧的全套发送行为总共需要108 + 3 = 111个BIT,完成一帧扩展帧的全套发送行为总共需要128 + 3 = 131个BIT。

至此,所有的元素取值都已经计算清楚,接下来我们进行整合计算:

假设总线波特率为500kbps,工作于标准帧模式,共有5个ID,每个ID按照50ms的间隔进行发送,那么此时的总线负载率计算如下:

负载率R
=(A1 + A2 + A3 + A4 + A5)/ 500000
=(A * 5)/ 500000
=(Z * K)* 5 / 500000
=(111 * 20)* 5 / 500000
= 2.22%

为此,我特地设计了一个表格,填入总线波特率、帧类型,以及各个ID(目前最多支持10个ID)的发送次数,便可自动计算出总线的理论负载率,如下:
五分钟教会如何计算CAN总线负载率,包学包会
有需要的同学,可以留言给我,我单独邮件发给大家

最后说明一下:

负载率越高,代表需要发送的数据越多,相对来说低优先级节点发生通讯延迟的概率越大。一般情况下,为保证低优先级的报文传输延迟在可接受的时间范围内,总线利用率不应超过30%,当负载率大于38%~40%时,稳定性开始衰减,超过50%后存在影响驾驶性及安全性风险,大于70%时,稳定性衰减加剧,超过98%时,网络将不堪重负。

不过,实际上30%的数据也只是一个经验数值,历史很悠久的一个经验数值。从本质上来看,限制负载率最终是要保证相对低优先级节点的通讯实时性,如果能通过网络及节点优化等手段满足每个节点的最大响应时间满足要求,负载率只是一个无关紧要的参数。12年的时候菲亚特已经可以做到70%的负载率下仍然能够保证正常通讯。