CAN通信矩阵与dbc报文分析
前言
(最近需要用Python解析dbc文件转通信矩阵表格,写脚本的过程中遇见了一些问题记录一下)
我们可以通过python的cantool工具解析直接得到通信矩阵的绝大部分数据,但在通信矩阵中还存在一些这样的表述,并不能直接通过cantool取值:
我们可以用的只有cantool给我们的信号的start和length,如何利用这两个数据计算StartByte起始字节和StartBit起始位呢?这需要一定的算法,我们后面就会讲到。
CAN数据矩阵简介
CAN数据矩阵通常分为两种格式,即Intel格式和Motorola格式。
Intel格式也即小端,MSB存放在高字节单元,反映到矩阵图中就是以起始位为原点,自上而下填充。图中:
- LSB —对应→ 上面dbc文件的信号截图中,start这个属性
- MSB —对应→ 通信矩阵表格中,StartBit起始位这列数据
- MSB所在的行 —对应→ 通信矩阵表格中,StartByte起始字节这列数据
Motorola格式也即大端,MSB存放在低字节单元,反映到矩阵图中就是以起始位为原点,自下而上填充。图中:
- MSB —对应→ 上面dbc文件的信号截图中,start这个属性
- LSB —对应→ 通信矩阵表格中,StartBit起始位这列数据
- LSB所在的行 —对应→ 通信矩阵表格中,StartByte起始字节这列数据
CAN矩阵核心图实例
当以Motorola格式读取下面表格时,若start值(MSB,即黄色格)为143,length长度为16,那么需要先向右读取完Byte17这一行后,剩下长度为8,继续从Byte18向右读取8个格,刚好到144(LSB,即红色格),即需要填在通信矩阵表格中StartBit列的那个值。
intel格式计算代码
算法:小端序(即信号截图中的byte_order=‘small_endian’)
输入:cantool解析dbc报文中的start 和 length
输出:通信矩阵模板中的起始位、起始字节
def cal_intel_LSB(signal_start,signal_length):
sgl_start_byte=signal_start//8
pad_len=(sgl_start_byte+1)*8-signal_start
if signal_length>pad_len:
sgl_start_byte -= 1
rest_len=signal_length-(pad_len)
while rest_len>8:
rest_len-=8
sgl_start_byte-=1
startbit=sgl_start_byte*8+rest_len-1
else:
startbit=signal_start+(signal_length-1)
startbyte=sgl_start_byte
return startbyte,startbit
Motorola格式计算代码
算法:big_end 小端序(即信号截图中的byte_order=‘big_endian’)
输入:cantool解析dbc报文中的start 和 length
输出:通信矩阵模板中的起始位、起始字节
def cal_motor_LSB(signal_ start,signal_length):
sgl_start_byte=signal_start//8
pad_len=signal_start-sgl_start_byte*8+1
if signal_length>pad_len:
rest_len=signal_length-(pad_len)
while rest_len>=8:
rest_len-=8
sgl_start_byte+=1
startbit=sgl_start_byte*8-rest_len
else:
startbit=signal_start-(signal_length-1)
startbyte=sgl_start_byte
return startbyte,startbit