小聊一下excel生成dbc

无聊逛51
发布于 2023-11-9 13:55
浏览
0收藏

Motorola、Intel格式

讲这2个格式首先说一下大小端格式。

大端模式:

低地址中存放的是字数据的低字节,高地址存放的是字数据的高字节。例:

(16位宽的数0x1234在小端模式CPU内存中的存放方式(假设从地址0x4000开始存放))

内存地址

0x4000

0x4001

存放内容

0x34

0x12

大端模式:

字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。例:

内存地址

0x4000

0x4001

存放内容

0x12

0x34

在dbc中,

Motorola格式:

Motorola格式跟大端格式一样,低地址代表高字节,高地址代表低字节。与Intel不一样,Motorola格式有2种表达方式,一种是Motorola_LSB,另一种是Motorola_MSB,但实际上它们代表的数据结构是一样的,只是表达方式不一样而已,其中Motorola_LSB的起始位是从低字节开始的,而

Motorola_MSB的起始位是从高字节开始的。

以某段报文为例:

小聊一下excel生成dbc-鸿蒙开发者社区

使用db++查看layout:

小聊一下excel生成dbc-鸿蒙开发者社区

可以看到文本阅读和db++中看到的startbit是不一样的。db++的sb是lsb,而文本中显示的是msb。

从图中可以看到:motorola格式的msb为高字节的最高位。

Intel格式:

  Intel格式跟小端格式一样,

低地址代表低字节,高地址代表高字节

例:

小聊一下excel生成dbc-鸿蒙开发者社区

小聊一下excel生成dbc-鸿蒙开发者社区

物理值、总线值转换

公式如下:

physical_value = raw_value * factor + offset

raw_value =(physical_value - offset)/ factor

例子:

小聊一下excel生成dbc-鸿蒙开发者社区

以车速信号为例:

假设实际车速为50km/h,那么根据公式

(50-0)/0.00390625=12800=0x3200,那么0x3200就是填充在报文中的总线值。

dbc文件详解

小聊一下excel生成dbc-鸿蒙开发者社区

含上图所示的几种信息,接下来咱们逐一解释下。

  1. VERSION、BS_分别表示版本和波特率信息,都可以忽略不填;
  2. BU_定义总线上的节点名称;
  3. BO_ MessageId(10进制数表示) MessageName: MessageSize TransmitterBO_表示报文关键字,需要描述报文的ID、名字、长度和发送方;
  4. SG_ SignalName : StartBit|SignalSize@ByteOrder ValueType (Factor,Offset) [Min|Max] Unit ReceiverSG_为信号关键字,需要描述信号的名字、起始位、长度、字节顺序(motorola为0,Intel为1)、数值类型(+表示无符号,-表示有符号)、精度、偏移量、最值、单位、接收方;
  5. CM_ Object MessageId/NodeName “Comment”CM_为注释信息,可以为信号、报文添加解释信息,这些在db++文件中和导入到CAN设备后都可以显示出来;
  6. BA_DEF_ Object AttributeName ValueType Min Max;BA_DEF_DEF_ AttributeName DefaultValue;​用来做属性定义,一般只有主机厂才会生成特别详细的dbc文件内容;​​

小工具分享

其实写这篇文章的初衷是有同事想要帮忙制作dbc文件,于是便写了一个

先来个生成过程的打印信息吧:

小聊一下excel生成dbc-鸿蒙开发者社区

脚本的具体功能:

首先在config.xlsx中写入信号列表.xlsx中报文、信号的属性的位置信息(列号),如下图:

小聊一下excel生成dbc-鸿蒙开发者社区

然后执行py脚本即可生成dbc文件。没有py环境的可以在dist文件夹下找到同名的exe文件双击执行。

附个视频吧:

小聊一下excel生成dbc-鸿蒙开发者社区

py 源码

from openpyxl import load_workbook
from collections import OrderedDict
import xlrd
from telnetlib import NOP
import os,sys

class Xls_Info_cl:
    def __init__(self):
        #there configs are important.
        self.ByteOrder = "Motorola_lsb"
        # there configs are necessary.
        self.FileName = 'Platform_CANCMX_V0.4.0_FVCM_2022_05_30.xlsx'
        self.Sheet = 'Signal Matrix'
        self.Start_row = 2
        self.MsgID_column = 'B'
        self.Msg_Name_column = 'A'
        self.Msg_Lenth_column = 'E'
        self.Sig_Name_column = 'G'
        self.StartBit_column = 'L'
        self.Size_column = 'M'
        self.ValueType_column = 'N'
        self.Sig_Factor_column = 'O'
        self.Sig_Offset_column = 'P'
        self.Min_column = 'Q'
        self.Max_column = 'R'
        self.Unit_column = 'Y'
        self.Value_Description_column = 'Z'


        # there config is not necessary
        self.Self_Node_colume = 'AA'
        self.Self_Msg_Period_colume = 'D'
        self.Sig_Multiplexortype = 'F'





# 获取当前工作目录的绝对路径
script_dir = os.path.dirname(sys.argv[0])

#获取表格内容
file_path = os.path.join(script_dir,'config_ini.xlsx')
workbook_object = load_workbook(filename=file_path)
sheet = workbook_object['config']
Xls_Info = Xls_Info_cl()

Xls_Info.ByteOrder = sheet['B3'].value
Xls_Info.FileName = sheet['B4'].value
Xls_Info.Sheet = sheet['B5'].value
Xls_Info.Start_row = sheet['B6'].value
Xls_Info.MsgID_column = sheet['B7'].value
Xls_Info.Msg_Name_column = sheet['B8'].value
Xls_Info.Msg_Lenth_column = sheet['B9'].value
Xls_Info.Sig_Name_column = sheet['B10'].value
Xls_Info.StartBit_column = sheet['B11'].value
Xls_Info.Size_column = sheet['B12'].value
Xls_Info.Sig_Factor_column = sheet['B13'].value
Xls_Info.Sig_Offset_column = sheet['B14'].value
Xls_Info.Max_column = sheet['B15'].value
Xls_Info.Min_column = sheet['B16'].value
Xls_Info.Unit_column = sheet['B17'].value
Xls_Info.ValueType_column = sheet['B18'].value
Xls_Info.Self_Node_colume = sheet['B19'].value
Xls_Info.Self_Msg_Period_colume = sheet['B20'].value
Xls_Info.Sig_Multiplexortype = sheet['B21'].value



file_path = os.path.join(script_dir,Xls_Info.FileName)

#加载Excel
if '.xlsx' in Xls_Info.FileName:
    workbook_object = load_workbook(filename=file_path)
else:
    workbook_object = xlrd.open_workbook(filename=(file_path))
#获取表单名称
names= workbook_object.sheetnames  #获取表单的名称返回list
# 获取表单
sheet = workbook_object[Xls_Info.Sheet]

def Get_CellValue(column,row):
    if column != 'FF' or column != None:
        code = sheet[column + str(row)].value
    else:
        code = None
    if type(code) == str:

        code = code.replace('0X','').replace('0X','')
    elif type(code) == int or type(code) == float:
        code = str(code)
    else:
        code = None
    return code

dbc_code = ''
MSg_Comment = ''
Sig_Comment = ''
dbc_txt = ''
last = ''
dbc_canfd = False

for i in range(((int)(Xls_Info.Start_row) + 1),sheet.max_row+1):
    if(None != Get_CellValue(Xls_Info.Msg_Name_column,i)):
        #eg:BO_ 389 ESCDAFuncSts: 8 Vector__XXX
        if None != Get_CellValue(Xls_Info.Msg_Name_column,i) and last != Get_CellValue(Xls_Info.Msg_Name_column,i):
            last = Get_CellValue(Xls_Info.Msg_Name_column,i)
            if None != Get_CellValue(Xls_Info.Self_Node_colume,i) and (('S' in Get_CellValue(Xls_Info.Self_Node_colume,i)) or ('T' in Get_CellValue(Xls_Info.Self_Node_colume,i))\
                or ('s' in Get_CellValue(Xls_Info.Self_Node_colume,i)) or ('t' in Get_CellValue(Xls_Info.Self_Node_colume,i))):
                send_node = Get_CellValue(Xls_Info.Self_Node_colume,Xls_Info.Start_row)
                receive_node = 'Vector__XXX'
            else:
                send_node = 'Vector__XXX'
                receive_node = Get_CellValue(Xls_Info.Self_Node_colume,Xls_Info.Start_row)

            MSG_ID = Get_CellValue(Xls_Info.MsgID_column,i)
            MSG_ID = int(MSG_ID,16)

            if Get_CellValue(Xls_Info.Msg_Lenth_column,i) != None:
                MsgLenth = int(Get_CellValue(Xls_Info.Msg_Lenth_column,i))
            else:
                #default value is 8
                MsgLenth = 8
            dbc_code += '\nBO_ ' + str(MSG_ID) + ' ' + Get_CellValue(Xls_Info.Msg_Name_column,i)\
                + ': ' + str(MsgLenth) + ' ' + send_node + '\n'

            if MsgLenth > 8:
                dbc_canfd = True

            if Get_CellValue(Xls_Info.Self_Msg_Period_colume,i) != None:
                MSg_Comment += 'BA_ "GenMsgSendType" BO_ ' + str(MSG_ID) + ' 0;\n'
                MSg_Comment += 'BA_ "GenMsgCycleTime" BO_ ' + str(MSG_ID) + ' ' + Get_CellValue(Xls_Info.Self_Msg_Period_colume,i) + ';\n'

    if None != Get_CellValue(Xls_Info.Sig_Name_column,i):
        #start bit is msb in db++,but is lsb in candb++!
        if Xls_Info.ByteOrder == 'Motorola_lsb':
            """ if 'TrGearRatio' == Get_CellValue(Xls_Info.Sig_Name_column,i):
                NOP """
            startByte = int(Get_CellValue(Xls_Info.StartBit_column,i))//8
            Bit_CAN_Use = 8 - int(Get_CellValue(Xls_Info.StartBit_column,i))%8
            Ramain_Bit = int(Get_CellValue(Xls_Info.Size_column,i))
            for bitnum in range(int(Get_CellValue(Xls_Info.Size_column,i))):
                if Bit_CAN_Use > 0:
                    #use byte in start bit  first
                    Bit_CAN_Use -= 1
                    Ramain_Bit -= 1
                else:
                    #use last byte in sb
                    Bit_CAN_Use = 8
                    if startByte > 0:
                        startByte -= 1
                    Bit_CAN_Use -= 1
                    Ramain_Bit -= 1    
                if Ramain_Bit == 0:
                    startbit = startByte*8 + (8-Bit_CAN_Use) - 1
        else:
            startbit = int(Get_CellValue(Xls_Info.StartBit_column,i))

        # SG_ BrkPdlPosInfo_RllCnt : 51|4@0+ (1,0) [0|15] ""  FVCM
        if Xls_Info.ValueType_column != 'FF' and Xls_Info.ValueType_column != None and 'u' not in Get_CellValue(Xls_Info.ValueType_column,i)\
            and 'U' not in Get_CellValue(Xls_Info.ValueType_column,i):
            ValueType = '-'
        else:
            ValueType = '+'
        if Xls_Info.Unit_column != 'FF' and Xls_Info.Unit_column != None and None != Get_CellValue(Xls_Info.Unit_column,i):
            Unit = sheet[Xls_Info.Unit_column+str(i)].value.replace(' ','')
        else:
            Unit = ''

        if Xls_Info.Sig_Multiplexortype != 'FF' and Xls_Info.Sig_Multiplexortype != None and None != Get_CellValue(Xls_Info.Sig_Multiplexortype,i):
            if 'M' in Get_CellValue(Xls_Info.Sig_Multiplexortype,i) or 'm' in Get_CellValue(Xls_Info.Sig_Multiplexortype,i):
                Multi_code = ' m'
            else:
                Multi_code = ' m' + Get_CellValue(Xls_Info.Sig_Multiplexortype,i)
        else:
            Multi_code = ''

        dbc_code +=' SG_ ' + Get_CellValue(Xls_Info.Sig_Name_column,i) + Multi_code +' : ' + str(startbit) +\
            '|' + Get_CellValue(Xls_Info.Size_column,i) + '@0' + ValueType + '(' + Get_CellValue(Xls_Info.Sig_Factor_column,i) + ',' +\
                Get_CellValue(Xls_Info.Sig_Offset_column,i) +  ') [' + Get_CellValue(Xls_Info.Min_column,i) + '|' +\
                    Get_CellValue(Xls_Info.Max_column,i) + '] \"' + Unit + '\" ' + receive_node + '\n'       

        # Sig Comment Gen ,Different manufacturers have different formats, to do. 
        """ if Xls_Info.Value_Description_column != 'FF' and Xls_Info.Value_Description_column != '' and None != sheet[Xls_Info.Value_Description_column+str(i)].value:
            Sig_Comment += 'VAL_ ' + str(MSG_ID) + ' ' + sheet[Xls_Info.Sig_Name_column+str(i)].value.replace(' ','') + ' ' +\
                sheet[Xls_Info.Value_Description_column+str(i)].value.replace(' ','').replace('0X','').replace('0x','').replace('\n','" ').replace(':',' "') + '" ;\n' """

dbc_txt +='VERSION ""\n\
\n\
\n\
NS_ : \n\
  NS_DESC_\n\
  CM_\n\
  BA_DEF_\n\
  BA_\n\
  VAL_\n\
  CAT_DEF_\n\
  CAT_\n\
  FILTER\n\
  BA_DEF_DEF_\n\
  EV_DATA_\n\
  ENVVAR_DATA_\n\
  SGTYPE_\n\
  SGTYPE_VAL_\n\
  BA_DEF_SGTYPE_\n\
  BA_SGTYPE_\n\
  SIG_TYPE_REF_\n\
  VAL_TABLE_\n\
  SIG_GROUP_\n\
  SIG_VALTYPE_\n\
  SIGTYPE_VALTYPE_\n\
  BO_TX_BU_\n\
  BA_DEF_REL_\n\
  BA_REL_\n\
  BA_DEF_DEF_REL_\n\
  BU_SG_REL_\n\
  BU_EV_REL_\n\
  BU_BO_REL_\n\
  SG_MUL_VAL_\n\
\n\
BS_:\n\
\n\
BU_: Vector__XXX '

dbc_txt += Get_CellValue(Xls_Info.Self_Node_colume,Xls_Info.Start_row) + '\n\n'

dbc_txt += dbc_code
dbc_txt += '\n\nBA_DEF_ BO_  "GenMsgCycleTime" FLOAT 0 300000;\n\
BA_DEF_ BO_  "GenMsgSendType" ENUM  "cyclic","spontaneous","immediate";\n\
BA_DEF_  "BaudRate" FLOAT 0 2000000;\n\
BA_DEF_  "BusType" STRING ;\n\
BA_DEF_DEF_  "GenMsgCycleTime" 0;\n\
BA_DEF_DEF_  "GenMsgSendType" "cyclic";\n'

if dbc_canfd == True:
    dbc_txt += 'BA_ "BusType" "CAN FD";\n\
BA_ "BaudRate" 2000000;\n'
else:
    dbc_txt += 'BA_DEF_DEF_  "BaudRate" 500000;\n\
BA_DEF_DEF_  "BusType" "CAN";"'

dbc_txt += MSg_Comment +'\n'
#dbc_txt += Sig_Comment
print(dbc_txt)
file = open(script_dir+"\\inputfilename.dbc", "w")
file.write(dbc_txt)
file.close()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.

文章转载自公众号:汽车与基础软件

分类
已于2023-11-9 13:55:10修改
收藏
回复
举报


回复
    相关推荐