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帧解析函数即可)。