CAN/CANFD 总线负载率及计算(源码和工具)

2023-11-12

CAN BUS的总线负载率是CAN总线架构协议设计时的一个重要的指标。一般建议负载率峰值不要高于80%,平均负载率不要超过50%。当然这只是一般建议,具体根据使用场景和系统设计而定。

负载率定义

关于CAN负载率的定义和计算,很多文章写得不求甚解,用帧数量来计算负载率是非常不正确的做法。

其实总线负载率的定义其实是非常简单明了的:

总线负载率=总线每秒上传输的实际bit的总时间/1s *100%

CAN2.0的总线负载率

对于CAN2.0而言,由于波特率是固定的,所以:

总线负载率=总线每秒上传输的实际bit数量/总线波特率*100%

BusLoad=\frac{bitstransferred}{bus bit rate}*100%

原理非常简单,波特率的定义就是每秒CAN总线上可以传输多少CAN数据bit,总线负载率自然就是总线实际传输的bit数量比上总线可以承载的最大bit数了。

例如,100K的总线波特率,总线上最大承载的数据量就是100K个bit。如果总线上实际传输了50K个bit位,那么负载率就是50%。

CAN FD的总线负载率

CAN FD由于支持速率可变,总线占用时间的计算就稍微麻烦一些

CANFD-BusLoad=\frac{bits_{data-rate}\times T_{data} + bits_{normal-rate}\times T_{normal}}{T} \times100%

负载率计算

对于上面的计算公式,对于一个CAN总线而言,波特率一般都是已知的。计算负载率的关键就是通过CAN报文统计出总线上每秒传输的bit数量。那么就需要回到CAN的帧格式来计算实际发生的bit数。

1位起始位。  

11位标识符  

1位RTR  

6位控制域  

0到64位数据字段  

15位CRC  

位填充是可能的,在上面的每一个序列的5个连续位相同的水平。 最坏情况下大约是19位。  

3位分隔符,ack等。  

帧结束7位  

帧后的3位间隔域。  

如果软件需要精确计算负载率,无疑是比较麻烦的。因为对于软件层面,并感知不到除了标识符,控制域和数据域以外的其他bit,并且由于填充位的数量因数据不同而不同,软件做精确的bit位数量计算就比较耗费资源。

软件计算负载率

基于这样的情况,实际可以考虑3种方案

1. 按最少的填充位可能性来计算(忽略填充位)

        忽略填充位显然会少统计很多bit数量,导致计算出的负载率比实际的偏低,但是每帧的bit数计算方式简单。

/* eff : 扩展帧标识 */
can_frame_length = (eff ? 67 : 47) + frame->len * 8;

2. 按最多的填充位的可能性来计算

        按最多的填充位计算负载率,会导致计算出的负载率比实际的偏高,但是每帧的bit数计算方式也比较简单。

/* eff : 扩展帧标识 */
can_frame_length = (eff ? 80 : 55) + frame->len * 10;

3.依据每一帧数据,精确的计算出填充位的数量

这种方式是最精确的,但是由软件计算会比较复杂,开销较大,需要软件讲每一帧的bit按照二进制进行排列,然后按照CAN协议位填充的要求,遇到5个相同的bit就插入一个相反的填充位,也就是增加一个bit数。

static unsigned cfl_exact(struct can_frame *frame)
{
	uint8_t bitmap[16];
	unsigned start = 0, end;
	crc_t crc;
	uint16_t crc_be;
	uint8_t mask, lookfor;
	unsigned i, stuffed;
	const int8_t clz[32] = /* count of leading zeros in 5 bit numbers */
		{ 5, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	/* Prepare bitmap */
	memset(bitmap, 0, sizeof(bitmap));
	if (frame->can_id & CAN_EFF_FLAG) {
		/* bit            7      0 7      0 7      0 7      0
		 * bitmap[0-3]   |.sBBBBBB BBBBBSIE EEEEEEEE EEEEEEEE| s = SOF, B = Base ID (11 bits), S = SRR, I = IDE, E = Extended ID (18 bits)
		 * bitmap[4-7]   |ER10DLC4 00000000 11111111 22222222| R = RTR, 0 = r0, 1 = r1, DLC4 = DLC, Data bytes
		 * bitmap[8-11]  |33333333 44444444 55555555 66666666| Data bytes
		 * bitmap[12-15] |77777777 ........ ........ ........| Data bytes
		 */
		bitmap[0] = (frame->can_id & CAN_EFF_MASK) >> 23;
		bitmap[1] = ((frame->can_id >> 18) & 0x3f) << 3 |
			    3 << 1	       	     	      	| /* SRR, IDE */
			    ((frame->can_id >> 17) & 0x01);
		bitmap[2] = (frame->can_id >> 9) & 0xff;
		bitmap[3] = (frame->can_id >> 1) & 0xff;
		bitmap[4] = (frame->can_id & 0x1) << 7              |
			    (!!(frame->can_id & CAN_RTR_FLAG)) << 6 |
			    0 << 4	      		       	    | /* r1, r0 */
			    (frame->can_dlc & 0xf);
		memcpy(&bitmap[5], &frame->data, frame->can_dlc);
		start = 1;
		end = 40 + 8*frame->can_dlc;
	} else {
		/* bit           7      0 7      0 7      0 7      0
		 * bitmap[0-3]  |.....sII IIIIIIII IRE0DLC4 00000000| s = SOF, I = ID (11 bits), R = RTR, E = IDE, DLC4 = DLC
		 * bitmap[4-7]  |11111111 22222222 33333333 44444444| Data bytes
		 * bitmap[8-11] |55555555 66666666 77777777 ........| Data bytes
		 */
		bitmap[0] = (frame->can_id & CAN_SFF_MASK) >> 9;
		bitmap[1] = (frame->can_id >> 1) & 0xff;
		bitmap[2] = ((frame->can_id << 7) & 0xff) |
			    (!!(frame->can_id & CAN_RTR_FLAG)) << 6 |
			    0 << 4 | /* IDE, r0 */
			    (frame->can_dlc & 0xf);
		memcpy(&bitmap[3], &frame->data, frame->can_dlc);
		start = 5;
		end = 24 + 8 * frame->can_dlc;
	}

	/* Calc and append CRC */
	crc = calc_bitmap_crc(bitmap, start, end);
	crc_be = htons(crc << 1);
	assert(end % 8 == 0);
	memcpy(bitmap + end / 8, &crc_be, 2);
	end += 15;

	/* Count stuffed bits */
	mask 	= 0x1f;
	lookfor = 0;
	i 	= start;
	stuffed = 0;
	while (i < end) {
		unsigned change;
		unsigned bits = (bitmap[i / 8] << 8 | bitmap[i / 8 + 1]) >> (16 - 5 - i % 8);
		lookfor = lookfor ? 0 : mask; /* We alternate between looking for a series of zeros or ones */
		change = (bits & mask) ^ lookfor; /* 1 indicates a change */
		if (change) { /* No bit was stuffed here */
			i += clz[change];
			mask = 0x1f; /* Next look for 5 same bits */
		} else {
			i += (mask == 0x1f) ? 5 : 4;
			if (i <= end) {
				stuffed++;
				mask = 0x1e; /* Next look for 4 bits (5th bit is the stuffed one) */
			}
		}
	}
	return end - start + stuffed +
		3 + 		/* CRC del, ACK, ACK del */
		7 +		/* EOF */
		3;		/* IFS */
}

软件计算负载率的缺陷

对于软件统计负载率,即使采用精确计算填充位的算法,由于以下原因仍然不能真实的反应总线的负载情况。

1. 对于CRC校验错误,或者格式错误的帧,软件层面一般不会接收到,也难以统计这部分错误帧产生的总线负载

硬件统计负载率

相比软件计算负载率,对需要精确计算总线负载的场合,更好的方案是用专业的硬件来统计发生的bit数量,并计算负载率。

测量CAN BUS总线负载率的工具和软件

Linux下使用canbusload 

canbusload 是linux CAN工具canutils的其中一个程序。它可以很方便的计算并刷新当前CAN总线上的负载率信息,并且提供了上述的3种软件算法进行统计(即忽略填充位,最大计算填充位,精确计算填充位)。

ubuser@ubuser-Lenovo-Product:/$ canbusload 

Usage: canbusload [options] <CAN interface>+
  (use CTRL-C to terminate canbusload)

Options: -t (show current time on the first line)
         -c (colorize lines)
         -b (show bargraph in 5% resolution)
         -r (redraw the terminal - similar to top)
         -i (ignore bitstuffing in bandwidth calculation)
         -e (exact calculation of stuffed bits)

Up to 16 CAN interfaces with mandatory bitrate can be specified on the 
commandline in the form: <ifname>@<bitrate>

The bitrate is mandatory as it is needed to know the CAN bus bitrate to
calcultate the bus load percentage based on the received CAN frames.
Due to the bitstuffing estimation the calculated busload may exceed 100%.
For each given interface the data is presented in one line which contains:

(interface) (received CAN frames) (used bits total) (used bits for payload)

Example:

user$> canbusload can0@100000 can1@500000 can2@500000 can3@500000 -r -t -b -c

canbusload 2014-02-01 21:13:16 (worst case bitstuffing)
 can0@100000   805   74491  36656  74% |XXXXXXXXXXXXXX......|
 can1@500000   796   75140  37728  15% |XXX.................|
 can2@500000     0       0      0   0% |....................|
 can3@500000    47    4633   2424   0% |....................|

硬件工具

PEAK的PCAN PRO和PCAN FD,以及周立功的ZCANpro软件均支持总线负载率的显示。

开源的Busmaster也同样支持负载率统计,并且都支持负载率实时曲线绘制

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CAN/CANFD 总线负载率及计算(源码和工具) 的相关文章

  • STM32通信---CAN

    一 CAN是什么 xff1f CAN xff0c 全称为 Controller Area Network xff0c 即控制器局域网 xff0c 是一种多主方式的串行通讯总线 xff0c 是国际上应用最广泛的现场总线之一 二 CAN的起源
  • UART、IIC、SPI、CAN通信的区别与应用

    文章目录 1 通信的基本知识1 1 数据通信的种类1 1 1 串行通信1 1 2 并行通信1 1 3 总结 1 2 数据通信的传输方向1 2 1 单工1 2 2 半双工1 2 3 全双工1 2 4 总结 1 3 数据通信的方式1 3 1 同
  • CAN扩展帧详解

    寻址方式
  • 自动驾驶之——CAN总线简介

    自动驾驶技术之 无人驾驶中的CAN总线 CAN 是Controller AreaNetwork 的缩写 xff0c 中文名为控制器局域网络 xff0c 是ISO国际标准化的串行通信协议 xff0c 是一种用于实时应用的串行通讯协议总线 xf
  • Linux内核Socket CAN中文文档

    自己在年假中空闲之余翻译的内核中Socket CAN的文档 xff0c 原文地址在 xff1a http lxr linux no linux 43 v2 6 34 Documentation networking can txt 但是这篇
  • STM8 CAN总线的IdMask模式的讲解

    http www stmcu org article id 328212 STM8 CAN总线的IdMask模式的讲解 发布时间 xff1a 2016 08 27 来源 xff1a ST社区 标签 xff1a STM8 CAN总线 IdMa
  • 一帧CAN数据需要多长时间发送

    1 CAN通讯速率 默认 500kbit s xff1b 2 xff1a 从下图CAN数据包的完整结构可知 xff0c 一包完整的扩展帧CAN数据总共包含 128bit xff1b 3 xff1a 发送一帧扩展帧CAN数据耗时 128 50
  • Python 使用can模块(记录稿)

    直接安装 xff1a pip install python can 如果报这个错 更新一下pip pip3 install upgrade pip 或者是 pip install upgrade pip 再安装wrapt pip insta
  • CAN通信讲解(3)——错误据帧

    本文注意参考了 CAN入门书 xff0c 源于此书图片不再特殊标注 目录 3 1 总线错误的种类3 1 1 位错误3 1 2 ACK错误3 1 3 填充错误3 1 4 CRC错误3 1 5 格式错误 3 2 错误帧结构3 3 错误状态3 3
  • Linux下CAN总线速率设置,socketCAN。

    背景 xff1a 飞思卡尔Freescale的ARM9处理器i MX25系列 socketCAN对于在Linux下操作CAN总线非常的快捷方便 xff0c 其配置方法和在Linux下对网卡的配置相似 xff0c 方法如下 xff1a 1 i
  • CAN总线数据帧/标准帧/扩展帧/远程帧/错误帧的组成格式对比

    最近在研究CAN总线的驱动 xff0c 需要详细了解数据帧 标准帧 扩展帧 远程帧 错误帧这几种帧的详细组成格式 xff0c 于是收集了一下 xff0c 统一放在这里进行对比和记录 xff0c 以便日后需要时查阅 1 数据帧 标准帧 CAN
  • CAN报文格式简析

    Date xff1a 2022 5 11 Author xff1a MJQ Meta xff1a CAN CAN基础篇 CAN报文格式简析 1 Motornala和Intel格式 建议直接看图 xff0c 小白也能秒懂 xff01 注 xf
  • 蓝牙通信、串口通信、和can通信以及MCU之间的关系

    说明 xff1a 其端口和can需要设置波特率 xff1a 250 500 xff0c 和can的类型 xff0c can1 can2 串口直接和模拟量通信需要设置串口的信息 xff0c 如下图 xff1a 蓝牙和模拟量通信 xff0c 不
  • 使用STM32F103做CAN的收发通信

    下面也是搭建嵌入式系统所必须的一个部分 参考网站 xff1a https www cnblogs com craigtao p 3645148 html https blog csdn net qq 29413829 article det
  • RT-thread 中CAN总线的应用

    准备 xff1a RT thread Studio 2 2 5 CubeMX 6 6 1 rt thread驱动包 4 0 3 1 新建项目 2 打开CubeMX Settings xff0c 设置CAN 找到CAN1 xff0c 并勾选激
  • CAN学习笔记3:STM32 CAN控制器介绍

    STM32 CAN控制器 1 概述 STM32 CAN控制器 bxCAN 支持CAN 2 0A 和 CAN 2 0B Active版本协议 CAN 2 0A 只能处理标准数据帧且扩展帧的内容会识别错误 而CAN 2 0B Active 可以
  • STM32学习心得三十二:CAN通信基础知识、原理、配置及实验

    记录一下 方便以后翻阅 主要内容 1 CAN通信基础知识 2 STM32 CAN控制器简介 3 相关实验代码解读 参考资料 STM32中文参考手册 V10 第22章 控制器局域网 bxCAN 实验功能 CAN实验需要两个开发板 系统启动后
  • Canoe 安装流程

    硬件 VN5620 软件 CANoe V15 0 软件 Vector License Client 6 2 驱动 Vector Driver Setup license 购买硬件时 vector会分配 参考文档 First Steps to
  • STM32 CAN通信的学习笔记总结(从小白开始)

    知识来源于互联网 回馈于互联网 目录 1 总体概述 1 1 基本概念 1 2 通讯方式 1 3 为什么使用CAN 1 4 CAN的协议及组成 2 上帝视角看CAN的通讯过程 2 1 数据传输原理实现 2 2 通信的整个过程 2 2 1 空闲
  • CAN总线的报文分析(三)

    系列文章目录 文章目录 系列文章目录 前言 一 数据帧 最常用 1 帧起始 2 仲裁段 3 控制段 4 数据段 5 CRC段 6 ACK段 7 帧结束 二 远程帧 三 错误帧 四 过载帧 五 帧间隔 总结 前言 CAN总线上的节点发送数据都

随机推荐

  • OPC通信从入门到精通_1_OPC基础知识及简单C#程序编写(OPCDA,OPCUA简介;OPC通信数据流框架图;C#程序编写)

    文章目录 1 OPC基础知识 OPCDA OPCUA 1 1 OPC基础知识 1 2 OPC通信读写方式 2 OPC通信仿真 2 1 上位机与PLC通过ModbusTCP直接通信 2 2 OPC通信介绍及实例 2 2 1 OPC通信与Mod
  • TCP报文格式

    TCP报文格式 文章目录 TCP报文格式 TCP首部 三次握手 四次挥手 TCP首部 源端口和目的端口 各占16bit 序号 SEQ序号 给发送的每个数据包标上序号 确认号 ACK序号 是指即将接收的数据包序号 注意 这里指的是序号不是标志
  • Linux 之软中断softirq

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net huangweiqing80 article details 83274095 softirq驱动开发人员一般都不会用到 到内核代码中会用到soft
  • python requests get请求_Python接口自动化之requests请求封装

    今天距2021年253天 这是ITester软件测试小栈第114次推文 在上一篇Python接口自动化测试系列文章 Python接口自动化之Token详解及应用 介绍token基本概念 运行原理及在自动化中接口如何携带token进行访问 以
  • docker内存

    docker container 动态修改内存限制 docker update help docker update m 4096m memory swap 1 ubuntu test docker update m 4096m memor
  • FPGA中的output or inout port xxx must be connected to a structural net expression错误

    主模块的output不能加reg 只在子模块的output 加reg 关于子模块调用 有两种调用方式 第一种是位置对应 如 bcd accbcd in8 out71 ou72 out73 如上图所示 第二种是信号名对应方式 此时不必按顺序
  • 数据结构---栈&&队列

    目录 什么是数据结构 什么是算法 Algorithm 生活中的数据结构和算法 数组结构 栈结构 stack 栈结构的实现 十进制转二进制 队列结构 Queue 队列的应用 对列类的创建 击鼓传花面试题 优先级队列 优先级队列的实现 什么是数
  • C语言中排序函数的用法

    C语言中没有预置的sort函数 如果在C语言中 遇到有调用sort函数 就是自定义的一个函数 功能一般用于排序 一 可以编写自己的sort函数 如下函数为将整型数组从小到大排序 void sort int a int l a为数组地址 l为
  • TensorFlow和Caffe、MXNet、Keras等其他深度学习框架的对比

    转 http www leiphone com news 201702 T5e31Y2ZpeG1ZtaN html 雷锋网按 本文作者黄文坚 PPmoney 大数据算法总监 TensorFlow 实战 作者 本文节选自 TensorFlow
  • SQL Server日期格式的多种转换方法

    MSSQL Server的日期字段是datetime 其默认格式是yyyy mm dd hh mm ss mmm 如在查询分析器里面执行 select getdate 会得到如下结果 2006 03 30 22 09 33 763 但对于我
  • 双因素方差分析(R)

    目录 原理 双因素等重复试验的方差分析 假设前提和模型设定 离差平方和分解 检验统计量和拒绝域 例题 应用 双因素无重复试验的方差分析 假设前提和模型设定 离差平方和分解 检验统计量和拒绝域 例题 应用 原理 在单因素方差分析的基础上 双因
  • 微信小程序 WXBizDataCrypt 解密 报错

    在使用微信官方WXBizDataCrypt js解密encryptedData获取敏感数据的时候 偶尔会报错 DeprecationWarning Buffer is deprecated due to security and usabi
  • 字符串的分割、截取

    文章目录 分割 截取的简单使用 简单分割 简单截取 升级版分割 截取的使用 url分割 id截取 或者截取其他由某种规则拼接起来的串儿 结尾 分割 截取的简单使用 简单分割 老师上课的时候大概会举类似的例子把 String str a b
  • 时序数据库InfluxDB介绍

    时序数据库InfluxDB介绍 1 什么是InfluxDB 2 那么时序数据有什么特点呢 3 对于时序数据 我们总结了以下特点 4 业务方常见需求 5 时序数据库为了解决什么问题 6 InfluxDB的优势 实时数据库与时序数据库 DBen
  • Unity中的资源管理-对象池技术(1)

    本文分享Unity中的资源管理 对象池技术 1 接下来几天 作者会按照自己的理解写几篇关于Unity中的资源管理相关的文章 大概会涉及到 对象池 分为普通类和GameObject 主要是预制 的对象池 引用计数技术 Unity中的资源基本概
  • Tesseract-OCR-05-主要API功能介绍

    Tesseract 05 主要API功能介绍 tesseract本身代码是由c c 混编而成的 其中有用的简单的接口函数几乎都是在baseapi h中 从其处理过程中 不难得出 它还需要有一个image处理的类 及相关的方法 这样子 读取图
  • 程序员的酸甜苦辣—写在即将告别coding的时刻

    毕业找工作时 我曾对朋友说 程序员这个称谓 是一个荣誉 过去的一切仿佛还在眼前 然而三天后 我就要告别程序员这个职业了 将来 我或许还会偶尔写写代码自娱自乐 我还会保持着单词第一个字母大写的 职业病 程序员 这普普通通三个字 凝聚着我一年多
  • chrome 扩展开发手册(一)——准备

    chrome Extensions翻译过来就是谷歌扩展 但我们更喜欢叫它谷歌浏览器扩展或chrome扩展 chrome扩展是定制浏览体验的小型软件程序 它们使用户能够根据个人需求或偏好定制Chrome功能和行为 对网页进行样式修改 增添功能
  • C compiler cc is not found

    安裝nginx是如果运行这个命令 configure prefix opt nginx出现以下错误 configure 45 auto init cannot create Makefile Permission denied config
  • CAN/CANFD 总线负载率及计算(源码和工具)

    CAN BUS的总线负载率是CAN总线架构协议设计时的一个重要的指标 一般建议负载率峰值不要高于80 平均负载率不要超过50 当然这只是一般建议 具体根据使用场景和系统设计而定 负载率定义 关于CAN负载率的定义和计算 很多文章写得不求甚解