Can总线dbc文件解析代码

  • Post author:
  • Post category:其他


1.使用python写的解析Can总线的dbc文件,代码上附带有注释,先将如下代码把存到parseCan_dbc_motorola_intel_ok.py文件,然后按照如下的说明使用即可


# coding: utf-8

# In[22]:


import shutil
import sys
import os
import re


class Signal:

    def __init__(self):
        self.name = "" #信号名
        self.sbit = -1  #信号起始bit
        self.len = -1  #信号总长度
        self.align = 0 #数据对其模式: 0--Motorola, 1--Intel
        self.sign = 0  # 0--无符号数据,1--有符号数据
        self.mul = -1  #scale
        self.offset = -1
        self.unit = ""      #单位
        self.max = -1
        self.min = -1
        self.receivers = [] #接收处理此信号的节点,同样可以不指明,写为Vector__XXX
        self.values = []    #信号可取的值的列表


class Message:

    def __init__(self):
        self.id = -1     #消息ID
        self.len = -1    #消息报文长度,帧字节数
        self.name = ""   #消息名字
        self.emitter = ""#发出该消息的网络节点,标识为Vector__XXX时未指明具体节点 
        self.period = -1
        self.type = ""   
        self.signals = []#消息中的信号

    def has_receiver(self, rec):
        for signal in self.signals:
            for receiver in signal.receivers:
                if rec == receiver:
                    return True

        return False

def msb_calc_lsb(signallength, signalmsb):
    lsb = signalmsb - signallength + 1
    return lsb

def lsb_calc_msb(signallength, signallsb):
    msb = signallsb + signallength - 1
    return msb

def AnalysisDbcFile(dbcName,createFileName,createCodeType):
    hfileName = "candb_messages.h"
    cfileName = "candb_messages.c"
    if createFileName:
        hfileName = createFileName + ".h"
        cfileName = createFileName + ".c"
    else:
        pass
    
    with open(hfileName, 'w',encoding='utf-8') as h:
        h.write("#ifndef _CANDB_MESSAGES_\n"
                        "#define _CANDB_MESSAGES_\n"
                        "\n")
        
        h.write("#include <stdio.h>\n"
                "#include <stdint.h>\n\n")
        
        h.write("#define ALIGN_MODE_MOTOROLA  0\n"
                "#define ALIGN_MODE_INTEL     1\n\n"
                "#define UNIT_MAX_LEN         12\n"
                "\n")
        h.write("typedef struct\n"
                "{\n"
                "    uint32_t msgId;\n"
                "    uint8_t alignMode;\n"
                "    uint8_t sign;\n"
                "    uint8_t sbit;\n"
                "    uint8_t bitLen;\n"
                "    double scale;\n"
                "    double offset;\n"
                "    char unit[UNIT_MAX_LEN];\n"
                "    double minVal;\n"
                "    double maxVal;\n"
                "}CanSig;\n\n")

        with open(cfileName, 'w',encoding='utf-8') as c:
            c.write("#include <math.h>\n"
                    "#include \"candb_messages.h\"\n"
                    "\n"
                    "\n") 
            
            c.write("const double CAN_EPS = 1e-6;\n\n")
            if createCodeType == 0:
                c.write("PhyCan physicsData = {0};\n\n")
            
            with open(dbcName, 'r',encoding='utf-8',errors='ignore') as f:

                foundMessages = []
                text = f.read()
                mm = re.findall(r"(BO_\s+[0-9]{1,4}\s+[0-9a-zA-Z_]+:\s+[0-9]\s+[0-9a-zA-Z_]+\n(.+\n)+)", text)
#                 mm = [re.sub(r"(BO_)|(SG_)|(\+)|(\-)|\(|\)|\[|\]|:", "", x[0]) for x in mm]
                mm = [re.sub(r"(BO_)|(SG_)|\(|\)|\[|\]|:", "", x[0]) for x in mm]
#                 print(mm)
                mm = [re.sub(r"\+ ", ",0 ", x) for x in mm]
                mm = [re.sub(r"\- ", ",1 ", x) for x in mm]
                mm = [re.sub(r"@|,|\|", " ", x).strip() for x in mm]

#                 mm = re.findall(r"(BO_\s+[0-9]{1,4}\s+[0-9a-zA-Z_]+:\s+[0-9]\s+[0-9a-zA-Z_]+\n(.+\n)+)", text)
#                 mm = [re.sub(r"(BO_)|(SG_)|(\+)|(\-)|\(|\)|\[|\]|:", "", x[0]) for x in mm]
#                 mm = [re.sub(r"@|,|\|", " ", x).strip() for x in mm]
            
#                 print(mm)

                for message in mm:
                    msg = Message()
                    foundMessages.append(msg)
                    nn = re.findall(r"\".*?\"", message)
                    lines = message.split("\n")
                    msgLine = lines[0].split()  #处理消息一行,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等

                    msg.id = msgLine[0]
                    msg.name = msgLine[1]
                    msg.len = int(msgLine[2])
                    msg.emitter = msgLine[3]
#                     print(msg.id)
#                     print(msg.name)
#                     print(msg.len)
#                     print(msg.emitter)

                    h.write("\n//!" + msg.name + " "+ msg.id + "\n")

                    h.write("typedef struct\n"
                           "{\n")
                    c.write(msg.name + "_t" +  " " + msg.name + " =\n"
                           "{\n") 
                    count = 0;
                    for signalLine in [x.split() for x in lines[1:]]:#第0行为消息描述行,第1行开始为Can信号
                        sgnl = Signal()
                        msg.signals.append(sgnl)
                        sgnl.msgId = msg.id
                        sgnl.name = signalLine[0]
#                         print(signalLine[1])
                        sgnl.sbit = int(signalLine[1])
                        sgnl.len = int(signalLine[2])
                        sgnl.align = int(signalLine[3])
                        sgnl.sign = int(signalLine[4])
                        sgnl.mul = float(signalLine[5])
                        sgnl.offset = float(signalLine[6])
                        sgnl.min = float(signalLine[7])
                        sgnl.max = float(signalLine[8])
#                         sgnl.max = int(float(signalLine[8]))
                        sgnl.unit = str(signalLine[9])#.replace(r"\"", "")
                        sgnl.receivers = signalLine[10:]
                        sgnl.unit = nn[count]
                        count = count + 1
                
#                         if sgnl.align == 0: #motorola
#                             if sgnl.sbit >= 56:
#                                 sgnl.sbit = sgnl.sbit - 56 #0-7
#                             elif sgnl.sbit >= 48:
#                                 sgnl.sbit = sgnl.sbit - 40 #8-15
#                             elif sgnl.sbit >= 40:
#                                 sgnl.sbit = sgnl.sbit - 24 #16-23
#                             elif sgnl.sbit >= 32:
#                                 sgnl.sbit = sgnl.sbit - 8 #24-31
#                             elif sgnl.sbit >= 24:
#                                 sgnl.sbit = sgnl.sbit + 8 #32-39
#                             elif sgnl.sbit >= 16:
#                                 sgnl.sbit = sgnl.sbit + 24 #40-47
#                             elif sgnl.sbit >= 8:
#                                 sgnl.sbit = sgnl.sbit + 40 #48-55
#                             else:
#                                 sgnl.sbit = sgnl.sbit + 56 #56-63   

#                         print(nn)
#                         print(sgnl.name)
#                         print(sgnl.sbit)
#                         print(sgnl.len)
#                         print(sgnl.mul)
#                         print(sgnl.offset)
#                         print(sgnl.min)
#                         print(sgnl.max)
#                         print(sgnl.unit)
#                         print(sgnl.receivers)

                        h.write("    CanSig " + sgnl.name + ";\n")
                                
                        signalPattern = "VAL_ "+msg.id+" "+sgnl.name+".+"
                        match = re.search(signalPattern, text)
                        if match:
                            words = re.findall(r"\d+\s+\".+?\"", match.group())#match.group()返回整个匹配的字符串
#                             words = [x.replace("\"", "").strip() for x in words]
                            sgnl.values = words

                        for comment in sgnl.values:
                            if comment == sgnl.values[0]:
                                c.write("// " + comment)
                            else:
                                c.write( "," + comment)
                        c.write("\n")   

                        c.write("    ." + sgnl.name + " =\n"
                            "    {\n"
                            "        .msgId     = " + str(msg.id) + ",\n"
                            "        .alignMode = " + str(sgnl.align) + ",\n"
                            "        .sign = " + str(sgnl.sign) + ",\n"
                            "        .sbit       = " + str(sgnl.sbit) + ",\n"
                            "        .bitLen    = " + str(sgnl.len) + ",\n"
                            "        .scale     = " + str(sgnl.mul) + ",\n"
                            "        .offset    = " + str(sgnl.offset) + ",\n"
                            "        .unit      = " + sgnl.unit + ",\n"
                            "        .minVal    = " + str(sgnl.min) + ",\n"
                            "        .maxVal    = " + str(sgnl.max) + "\n"
                            "    },\n\n"
                           )
                    
                    h.write("}" + msg.name + "_t;\n" 
                            "extern " + msg.name + "_t" +  " " + msg.name + ";\n")
                    c.write("};\n\n") 
                    
                    #信号的取值列表提取
                    for signalLine in [x.split() for x in lines[1:]]:#第0行为消息描述行,第1行开始为Can信号
                        sgnl = Signal()
                        sgnl.name = signalLine[0]

                        signalPattern = "VAL_ " + msg.id + " " + sgnl.name + ".+"
                        match = re.search(signalPattern, text)

                        if match:
                            words = re.findall(r"\d+\s+\".+?\"", match.group())#match.group()返回整个匹配的字符串
                            sgnl.values = words
                            keyValPair = re.findall(r"(\d+)\s+(\".+?\")", match.group()) 
                            
                            if keyValPair:
                                h.write("typedef enum\n"
                                        "{\n")
                                numNum = 0
                                for keyVal in keyValPair:
                                    h.write("    " + sgnl.name + "_" + str(numNum) + " = " + keyVal[0] + ",// " + keyVal[1] + "\n")
                                    numNum = numNum + 1
                                h.write("}" + sgnl.name + "_e;\n")

        h.write("\n\n#endif\n")  
        
    print("AnalysisDbc successfull!\n")
    return 

def CreateCanSignalAnalysisFunction(dbcName,createFileName): 
    hfileName = "candb_messages.h"
    cfileName = "candb_messages.c"
    if createFileName:
        hfileName = createFileName + ".h"
        cfileName = createFileName + ".c"
    else:
        pass
    
    with open(hfileName, 'a+',encoding='utf-8') as h:
        with open(cfileName, 'a+',encoding='utf-8') as c:

            with open(dbcName, 'r',encoding='utf-8',errors='ignore') as f:#,encoding='latin-1'
                foundMessages = []
                text = f.read()
                mm = re.findall(r"(BO_\s+[0-9]{1,4}\s+[0-9a-zA-Z_]+:\s+[0-9]\s+[0-9a-zA-Z_]+\n(.+\n)+)", text)
                mm = [re.sub(r"(BO_)|(SG_)|\(|\)|\[|\]|:", "", x[0]) for x in mm]
                mm = [re.sub(r"\+ ", ",0 ", x) for x in mm]
                mm = [re.sub(r"\- ", ",1 ", x) for x in mm]
                mm = [re.sub(r"@|,|\|", " ", x).strip() for x in mm]
#                 print(mm)
            
                h.write("\n//! Physical values struct\n") 
                h.write("typedef struct\n"
                       "{\n") 
                for message in mm:
                    msg = Message()
                    foundMessages.append(msg)
                    nn = re.findall(r"\".*?\"", message)
                    lines = message.split("\n")
                    msgLine = lines[0].split()  #处理消息一行,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等

                    msg.id = msgLine[0]
                    msg.name = msgLine[1]
                    msg.len = int(msgLine[2])
                    msg.emitter = msgLine[3]
                    
    #                 print(msg.id)
                    print(msg.name)
    #                 print(msg.len)
    #                 print(msg.emitter)
                    
                    h.write("\n// " + msg.name + " "+ msg.id + "\n") 
                    
                    for signalLine in [x.split() for x in lines[1:]]:#第0行为消息描述行,第1行开始为Can信号
                        sgnl = Signal()
                        sgnl.msgId = msg.id
                        sgnl.name = signalLine[0]
                        sgnl.sbit = int(signalLine[1])
                        sgnl.len = int(signalLine[2])
                        sgnl.align = int(signalLine[3])
                        sgnl.sign = int(signalLine[4])
                        sgnl.mul = float(signalLine[5])
                        sgnl.offset = float(signalLine[6])
                        sgnl.min = int(float(signalLine[7]))
                        sgnl.max = int(float(signalLine[8]))
                        
                        if sgnl.align == 0: #motorola
                            if sgnl.sbit >= 56:
                                sgnl.sbit = sgnl.sbit - 56 #0-7
                            elif sgnl.sbit >= 48:
                                sgnl.sbit = sgnl.sbit - 40 #8-15
                            elif sgnl.sbit >= 40:
                                sgnl.sbit = sgnl.sbit - 24 #16-23
                            elif sgnl.sbit >= 32:
                                sgnl.sbit = sgnl.sbit - 8 #24-31
                            elif sgnl.sbit >= 24:
                                sgnl.sbit = sgnl.sbit + 8 #32-39
                            elif sgnl.sbit >= 16:
                                sgnl.sbit = sgnl.sbit + 24 #40-47
                            elif sgnl.sbit >= 8:
                                sgnl.sbit = sgnl.sbit + 40 #48-55
                            else:
                                sgnl.sbit = sgnl.sbit + 56 #56-63 
                            
                        h.write("    double phy_" + sgnl.name + ";\n")
        
                        c.write("double " + "Parse_" + msg.name + "_" + sgnl.name + "(const uint8_t msgLen, const uint8_t data[8])\n"
                                "{\n")
                        c.write("    double tmpVal = 0;\n"
                                "    int64_t  temp = 0;\n")
                
#                         signalLsb = 0
#                         signalMsb = 0
                        if sgnl.align == 1:
                            c.write("    uint64_t tmpData = ((uint64_t)data[0]\n"
                               "                       | ((uint64_t)data[1]<<8)\n"
                               "                       | ((uint64_t)data[2]<<16)\n"
                               "                       | ((uint64_t)data[3]<<24)\n"
                               "                       | ((uint64_t)data[4]<<32)\n"
                               "                       | ((uint64_t)data[5]<<40)\n"
                               "                       | ((uint64_t)data[6]<<48)\n"
                               "                       | ((uint64_t)data[7]<<56));\n")
                            signalLsb = sgnl.sbit
                            signalMsb = lsb_calc_msb(sgnl.len, sgnl.sbit)
                        else:
                            c.write("    uint64_t tmpData = ((uint64_t)data[7]\n"
                                   "                       | ((uint64_t)data[6]<<8)\n"
                                   "                       | ((uint64_t)data[5]<<16)\n"
                                   "                       | ((uint64_t)data[4]<<24)\n"
                                   "                       | ((uint64_t)data[3]<<32)\n"
                                   "                       | ((uint64_t)data[2]<<40)\n"
                                   "                       | ((uint64_t)data[1]<<48)\n"
                                   "                       | ((uint64_t)data[0]<<56));\n")

                            signalLsb = msb_calc_lsb(sgnl.len, sgnl.sbit)
                            signalMsb = sgnl.sbit
                            
#                       test print        
                        printSignal = "lsb:" + str(signalLsb) + " msb:" + str(signalMsb) + " len:" + str(sgnl.len)
                        print(printSignal)
#                       End test print  

                        sgAlign = msg.name + "." + sgnl.name + ".alignMode"
                        sgSign = msg.name + "." + sgnl.name + ".sign"
                        sgBitlen = msg.name + "." + sgnl.name + ".bitLen"
                        sgScale = msg.name + "." + sgnl.name + ".scale"
                        sgOffset = msg.name + "." + sgnl.name + ".offset"
                        sgMin = msg.name + "." + sgnl.name + ".minVal"
                        sgMax = msg.name + "." + sgnl.name + ".maxVal"

                        if sgnl.align == 1:
                            sgMsb = "(" + msg.name + "." + sgnl.name + ".sbit + " + msg.name + "." + sgnl.name + ".bitLen - 1)"
                            c.write("    uint8_t tmpMsb = " + sgMsb + ";\n")
                        else:
                            sgMsb = msg.name + "." + sgnl.name + ".sbit"
                            c.write("    uint8_t tmpMsb = " + sgMsb + ";\n"
                                    "    if(tmpMsb >= 56)\n"
                                    "    {\n"
                                    "        tmpMsb -= 56;//0-7\n"
                                    "    }\n"
                                    "    else if(tmpMsb >= 48)\n"
                                    "    {\n"
                                    "        tmpMsb -= 40;//8-15\n"
                                    "    }\n"
                                    "    else if(tmpMsb >= 40)\n"
                                    "    {\n"
                                    "        tmpMsb -= 24;//16-23\n"
                                    "    }\n"
                                    "    else if(tmpMsb >= 32)\n"
                                    "    {\n"
                                    "        tmpMsb -= 8;//24-31\n"
                                    "    }\n"
                                    "    else if(tmpMsb >= 24)\n"
                                    "    {\n"
                                    "        tmpMsb += 8;//32-39\n"
                                    "    }\n"
                                    "    else if(tmpMsb >= 16)\n"
                                    "    {\n"
                                    "        tmpMsb += 24;//40-47\n"
                                    "    }\n"
                                    "    else if(tmpMsb >= 8)\n"
                                    "    {\n"
                                    "        tmpMsb += 40;//48-55\n"
                                    "    }\n"
                                    "    else\n"
                                    "    {\n"
                                    "        tmpMsb += 56;//56-63 \n"
                                    "    }\n")
                        
                        
                        c.write("    tmpData = tmpData << (63 - tmpMsb);\n")
                        c.write("    tmpData = tmpData >> (63 - tmpMsb);\n")
                        c.write("    tmpData = tmpData >> (tmpMsb - " + sgBitlen + " + 1);\n")
                    
                        c.write("    if(" + sgSign + ")\n"
                                "    {\n"
                                "        if(tmpData >> (" + sgBitlen + " - 1))\n"
                                "        {\n"
                                "            for(uint8_t i = 63; i >= " + sgBitlen + "; i--)\n"
                                "            {\n"
                                "                tmpData = tmpData | ((uint64_t)0x01 << i);\n"
                                "            }\n"
                                "        }\n"
                                "        temp = (int64_t)tmpData;\n"
                                "        tmpVal = (double)(temp * " + sgScale + " + " + sgOffset + ");\n"
                                "    }\n"
                                "    else\n"
                                "    {\n"
                                "        tmpVal = (double)(tmpData * " + sgScale + " + " + sgOffset + ");\n"
                                "    }\n"
                               )
                        
                        c.write("    if((tmpVal + CAN_EPS) < " + sgMin + ")\n"
                                "    {\n"
                                "        tmpVal = " + sgMin + ";\n"
                                "    }\n")
                
                        c.write("    if(tmpVal > " + sgMax + " + CAN_EPS)\n"
                                "    {\n"
                                "        tmpVal = " + sgMax + ";\n"
                                "    }\n")
                    
                        c.write("    return tmpVal;\n")
                        c.write("}\n\n")
                        
                h.write("}PhyCan;\n")

        h.write("\n//! Physical values struct variable \n") 
        h.write("extern PhyCan physicsData;\n")
        h.write("\n//! The function AnalysisCanFrameMessage will be used by the user\n") 
        h.write("extern int32_t AnalysisCanFrameMessage(const uint32_t msgId, const uint8_t msgLen, const uint8_t data[8]);\n")  
        
        h.write("\n\n#endif\n")  
        
    print("CreateCanSignalAnalysisFunction successfull!\n")
    
    return     

def CreateAnalysisCanFrameMessageFunction(dbcName,createFileName): 
    hfileName = "candb_messages.h"
    cfileName = "candb_messages.c"
    if createFileName:
        hfileName = createFileName + ".h"
        cfileName = createFileName + ".c"
    else:
        pass
    
    with open(cfileName, 'a+',encoding='utf-8') as c:
        with open(dbcName, 'r',encoding='utf-8',errors='ignore') as f:#,encoding='latin-1'
            foundMessages = []
            text = f.read()
            mm = re.findall(r"(BO_\s+[0-9]{1,4}\s+[0-9a-zA-Z_]+:\s+[0-9]\s+[0-9a-zA-Z_]+\n(.+\n)+)", text)
            mm = [re.sub(r"(BO_)|(SG_)|\(|\)|\[|\]|:", "", x[0]) for x in mm]
            mm = [re.sub(r"\+ ", ",0 ", x) for x in mm]
            mm = [re.sub(r"\- ", ",1 ", x) for x in mm]
            mm = [re.sub(r"@|,|\|", " ", x).strip() for x in mm]

            c.write("int32_t AnalysisCanFrameMessage(const uint32_t msgId, const uint8_t msgLen, const uint8_t data[8])\n"
                    "{\n"
                    "    int32_t ret = 0;\n\n"
                    "    switch(msgId)\n"
                    "    {\n"
                   )
            for message in mm:
                msg = Message()
                foundMessages.append(msg)
                nn = re.findall(r"\".*?\"", message)
                lines = message.split("\n")
                msgLine = lines[0].split()  #处理消息一行,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等

                msg.id = msgLine[0]
                msg.name = msgLine[1]
                msg.len = int(msgLine[2])
                msg.emitter = msgLine[3]

                c.write("        case " + str(msg.id) + ": // " + msg.name + "\n") 

                for signalLine in [x.split() for x in lines[1:]]:#第0行为消息描述行,第1行开始为Can信号
                    sgnl = Signal()
                    sgnl.msgId = msg.id
                    sgnl.name = signalLine[0]

                    c.write("            physicsData.phy_" + sgnl.name + " = Parse_" + msg.name + "_" + sgnl.name + "(msgLen, data);\n")
                c.write("            break;\n")

            c.write('        default:\n'
                    '             ret = -1;\n'
                    '             printf("Error:Unknow msgId!\\n");\n'
                    '             break;\n')
            c.write("    }\n\n" 
                    "    return ret;\n"
                    "}\n") 
                
    print("CreateAnalysisCanFrameMessageFunction successfull!\n")                
                
    return

def RemoveFileEndline(fileName):
    openFile=open(fileName,'r',encoding='utf-8')
    writeFile=open('Temp','w',encoding='utf-8')

    line=openFile.readline()
    while line:
#         print(line)
        if line == "#endif\n":
            print(line)
            pass
        else:
            writeFile.write(line)
        line=openFile.readline()
        
    openFile.close()
    writeFile.close()
    os.remove(fileName)
    os.rename('Temp',fileName)     
    
    print("RemoveFileEndline ok!\n")
    
    return 


#以上是解析相关的函数
#以下是编码打包相关的函数
def CreateCanSignalPackgeFunction(dbcName,createFileName): 
    hfileName = "candb_messages.h"
    cfileName = "candb_messages.c"
    if createFileName:
        hfileName = createFileName + ".h"
        cfileName = createFileName + ".c"
    else:
        pass
    
    with open(hfileName, 'a+',encoding='utf-8') as h:
        with open(cfileName, 'a+',encoding='utf-8') as c:

            with open(dbcName, 'r',encoding='utf-8',errors='ignore') as f:#,encoding='latin-1'
                foundMessages = []
                text = f.read()
                mm = re.findall(r"(BO_\s+[0-9]{1,4}\s+[0-9a-zA-Z_]+:\s+[0-9]\s+[0-9a-zA-Z_]+\n(.+\n)+)", text)
                mm = [re.sub(r"(BO_)|(SG_)|\(|\)|\[|\]|:", "", x[0]) for x in mm]
                mm = [re.sub(r"\+ ", ",0 ", x) for x in mm]
                mm = [re.sub(r"\- ", ",1 ", x) for x in mm]
                mm = [re.sub(r"@|,|\|", " ", x).strip() for x in mm]

            
#                 h.write("\n//! Physical values struct\n") 
#                 h.write("typedef struct\n"
#                        "{\n") 
                for message in mm:
                    msg = Message()
                    foundMessages.append(msg)
                    nn = re.findall(r"\".*?\"", message)
                    lines = message.split("\n")
                    msgLine = lines[0].split()  #处理消息一行,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等

                    msg.id = msgLine[0]
                    msg.name = msgLine[1]
                    msg.len = int(msgLine[2])
                    msg.emitter = msgLine[3]
                    
    #                 print(msg.id)
                    print(msg.name)
    #                 print(msg.len)
    #                 print(msg.emitter)
                    
                    h.write("\n// " + msg.name + " "+ msg.id + "\n") 
                    hFuncName = "extern uint64_t Packge_" + msg.name + "("
                    cFuncName = "uint64_t Packge_" + msg.name + "("
                    hLen = len(hFuncName)
                    cLen = len(cFuncName)
                    h.write(hFuncName)
                    c.write(cFuncName)
                    signalNumber = 0;
                    for signalLine in [x.split() for x in lines[1:]]:
                        sgnl = Signal()
                        sgnl.name = signalLine[0]
                        sgnl.len = int(signalLine[2])
                        sgnl.sign = int(signalLine[4])
                        
                        signalNumber = signalNumber + 1
                        if signalNumber > 1:
                            h.write(",\n")
                            c.write(",\n")
                            for x in range(hLen):
                                h.write(" ")
                            for x in range(cLen):
                                c.write(" ")
                            
                        if sgnl.len <= 8:
                            if sgnl.sign == 1:
                                h.write("const int8_t " + sgnl.name)
                                c.write("const int8_t " + sgnl.name)
                            else:
                                h.write("const uint8_t " + sgnl.name)
                                c.write("const uint8_t " + sgnl.name)
                        elif sgnl.len <= 16: 
                            if sgnl.sign == 1:
                                h.write("const int16_t " + sgnl.name)
                                c.write("const int16_t " + sgnl.name)
                            else:
                                h.write("const uint16_t " + sgnl.name)
                                c.write("const uint16_t " + sgnl.name)
                        elif sgnl.len <= 32:
                            if sgnl.sign == 1:
                                h.write("const int32_t " + sgnl.name)
                                c.write("const int32_t " + sgnl.name)
                            else:
                                h.write("const uint32_t " + sgnl.name)
                                c.write("const uint32_t " + sgnl.name)
                        else:# sgnl.len <= 64:
                            if sgnl.sign == 1:
                                h.write("const int64_t " + sgnl.name)
                                c.write("const int64_t " + sgnl.name)
                            else:
                                h.write("const uint64_t " + sgnl.name)
                                c.write("const uint64_t " + sgnl.name)      
                    h.write(");\n")   
                    c.write(")\n"
                            "{\n"
                            "    uint64_t tmpVal = 0;\n"
                            "    uint64_t tmpData = 0;\n"
                            "    uint8_t* pos = NULL;\n")
                    
                    for signalLine in [x.split() for x in lines[1:]]:
                        sgnl = Signal()
                        sgnl.msgId = msg.id
                        sgnl.name = signalLine[0]
                        sgnl.sbit = int(signalLine[1])
                        sgnl.len = int(signalLine[2])
                        sgnl.align = int(signalLine[3])
                        sgnl.sign = int(signalLine[4])
                        sgnl.mul = float(signalLine[5])
                        sgnl.offset = float(signalLine[6])
                        sgnl.min = int(float(signalLine[7]))
                        sgnl.max = int(float(signalLine[8]))
                        
                        if sgnl.align == 0: #motorola
                            if sgnl.sbit >= 56:
                                sgnl.sbit = sgnl.sbit - 56 #0-7
                            elif sgnl.sbit >= 48:
                                sgnl.sbit = sgnl.sbit - 40 #8-15
                            elif sgnl.sbit >= 40:
                                sgnl.sbit = sgnl.sbit - 24 #16-23
                            elif sgnl.sbit >= 32:
                                sgnl.sbit = sgnl.sbit - 8 #24-31
                            elif sgnl.sbit >= 24:
                                sgnl.sbit = sgnl.sbit + 8 #32-39
                            elif sgnl.sbit >= 16:
                                sgnl.sbit = sgnl.sbit + 24 #40-47
                            elif sgnl.sbit >= 8:
                                sgnl.sbit = sgnl.sbit + 40 #48-55
                            else:
                                sgnl.sbit = sgnl.sbit + 56 #56-63 
                        
                        if sgnl.align == 1:
                            signalLsb = sgnl.sbit
                            signalMsb = lsb_calc_msb(sgnl.len, sgnl.sbit)
                        else:
                            signalLsb = msb_calc_lsb(sgnl.len, sgnl.sbit)
                            signalMsb = sgnl.sbit
                            
                        printSignal = "lsb:" + str(signalLsb) + " msb:" + str(signalMsb) + " len:" + str(sgnl.len)
                        print(printSignal)
                        
                        sgAlign = msg.name + "." + sgnl.name + ".alignMode"
                        sgSign = msg.name + "." + sgnl.name + ".sign"
                        sgBitlen = msg.name + "." + sgnl.name + ".bitLen"
                        sgScale = msg.name + "." + sgnl.name + ".scale"
                        sgOffset = msg.name + "." + sgnl.name + ".offset"
                        sgMin = msg.name + "." + sgnl.name + ".minVal"
                        sgMax = msg.name + "." + sgnl.name + ".maxVal"
                        
                        c.write("    tmpData = (uint64_t)" + sgnl.name + ";\n")
                        c.write("    if(" + sgSign + ")\n"
                                "    {"
                                "        if(" + sgnl.name + " >> (" + sgBitlen + " - 1))\n"#负数
                                "        {\n"
                                "            for(uint8_t i = 63; i >= " + sgBitlen + "; i--)\n"
                                "            {\n"
                                "                tmpData = tmpData & (~((uint64_t)0x01 << i));\n"
                                "            }\n"
                                "        }\n"
                                "    }\n")
                        
                        c.write("    tmpData = tmpData << " + str(signalLsb) + ";\n")
                        c.write("    tmpVal = tmpVal | tmpData;\n")
                        
                    c.write("    if(0 == " + sgAlign + ")\n"
                            "    {"
                            "        tmpData = tmpVal;\n"
                            "        pos = (uint8_t*)&tmpData;\n"
                            "        tmpVal = (uint64_t)pos[7]\n"
                            "                 |((uint64_t)pos[6]<<8)\n"
                            "                 |((uint64_t)pos[5]<<16)\n"
                            "                 |((uint64_t)pos[4]<<24)\n"
                            "                 |((uint64_t)pos[3]<<32)\n"
                            "                 |((uint64_t)pos[2]<<40)\n"
                            "                 |((uint64_t)pos[1]<<48)\n"
                            "                 |((uint64_t)pos[0]<<56);\n"
                            "    }\n")
                    c.write("    return tmpVal;\n")    
                    c.write("}\n\n") 
        
        h.write("\n\n#endif\n")  
        
    print("CreateCanSignalPackgeFunction successfull!\n")
    
    return     


if __name__ == '__main__':
    dbcFile = "./CN210S.dbc"    #Motorola
#     dbcFile = "./CVTC_SK81.dbc" #Intel
#     dbcFile = "./ex1.dbc" #Intel

    createFile = "candb_messages"
    headFilePathName = "./" + createFile + ".h"
    
    createFileType = 0 # 0--产生can消息解析;1--产生can消息组包函数
    AnalysisDbcFile(dbcFile,createFile,createFileType)  
    RemoveFileEndline(headFilePathName)
    CreateCanSignalAnalysisFunction(dbcFile,createFile)
    CreateAnalysisCanFrameMessageFunction(dbcFile,createFile)
    
# 以下打包赋值部分  
#     createFileType = 1 # 0--产生can消息解析;1--产生can消息组包函数
#     AnalysisDbcFile(dbcFile,createFile,createFileType)  
#     RemoveFileEndline(headFilePathName)                            
#     CreateCanSignalPackgeFunction(dbcFile,createFile)
                                
#     my_file = 'canDemoTest//candb_messages.c'
#     if os.path.exists(my_file):
#         os.remove(my_file)
#     my_file = 'canDemoTest//candb_messages.h'
#     if os.path.exists(my_file):
#         os.remove(my_file)
#     shutil.move('./candb_messages.c', 'canDemoTest')
#     shutil.move('./candb_messages.h', 'canDemoTest')
    
    pass

使用说明:

1.parseCan_dbc_motorola_intel_ok.py是可以直接通过python3来运行的;

parseCan_dbc_motorola_intel_ok.ipynb是使用Jupyter Notebook可以来运行的。

2.直接修改parseCan_motorola_intel_ok.py文件中的main函数dbcFile指向(dbc文件)。

执行: python3 parseCan_motorola_intel_ok.py

则会生成candb_messages.c和candb_messages.h文件。

3.将candb_messages.c和candb_messages.h文件拷贝到canDemoTest目录下。

4.修改canDemoTest目录下的main.c,如果第2步dbc文件选择的CN210S.dbc或者CVTC_SK81.dbc,则将在main.c打开以下几个宏:

①.#define _ANALYS_CN210S_DBC_    这个宏,表示生成CN210S.dbc文件对应的can信号解析相关的函数;

②.#define _ANALYS_CVTC_SK81_DBC_ 这个宏,表示生成CVTC_SK81.dbc文件对应的can信号解析相关的函数;

③.#define _PACKGE_CN210S_        这个宏,表示生成CN210S.dbc文件对应的can信号组包相关的函数;

④.#define _PACKGE_CVTC_SK81_DBC_ 这个宏,表示生成CVTC_SK81.dbc文件对应的can信号组包相关的函数;

5.运行cmake和make编译,然后运行看看打印

6.注意:CN210S.dbc是Motolola格式的dbc文件,CVTC_SK81.dbc是Intel格式的dbc文件。

7.生成的candb_messages.c和candb_messages.h文件中,用户只需要关注physicsData变量(最终的物理变量)和AnalysisCanFrameMessage函数(Can帧解析函数即可)。



版权声明:本文为chengyongkang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。