基于Python的对 汽车电子ECU的通信矩阵数据库文件(.dbc)的解析

基于Python的对 汽车电子ECU的通信矩阵数据库文件(.dbc)的解析

  • DBC文件简介
  • 想要实现的目的
  • 解析出signals 和message

DBC文件简介

.dbc文件顾名思义是database file:
google的解释是:A DBC file is a database created with Visual FoxPro, a database development system. It contains a database saved in the Database Container (DBC) format.
用在汽车电子中,就是一种描述CAN通信列表的文件

首先你要清楚DBC的数据格式,我们才能解析并提取关心的数据
DBC文件的数据格式 .
下面的链接是我最早写在电子发烧友论坛中的博客,附有源码
包含源码 .

想要实现的目的

基于vector的产品开发,自然会用到capl脚本,在写脚本中,自然会用到大量的signals,messages,有大量的代码的区别往往只有一个signal或者message ,为了提高写代码的效率和复用性,我想通过python提取出dbc文件中的signals和message然后批量生成capl脚本

解析出signals 和message

1,这是解析文件的全部代码

import re
import copy
node = []
allDatas = []
siganlList = []
SignalsName = []
messageName = []
def readFile():
    global node,allDatas,siganlList,SignalsName,messageName
    ''' 得到dbc文件的绝对路径'''
    filePath = find_file()
    if filePath:
        print(filePath)
        f = open(filePath, "r")  # 设置文件对象
    else:
        print("读取文件失败!")
        return 0
    """
    NodesPattern:节点
    MessagePattern:消息
    SignalPattern:信号
    """
    NodesPattern = re.compile(r"BU_: (.*)", re.S)
    MessagePattern = re.compile(r"BO_ (.*?) (.*?): (.*?) (.*)", re.S)
    SignalPattern = re.compile('''SG_ (.*?) : (.*?)\|(.*?)@.*? \((.*?),(.*?)\) \[(.*?)\|(.*?)\] "(.*?)" (.*)''', re.S)
    DefaultValue = '''BA_ "GenSig(.*?)" SG_ (\d+) signalname (\d+);'''

    line = f.readline()
    allDatas=[]
    while line:
        """ 匹配出节点 """
        NodesSearched = re.search(NodesPattern, line.strip())
        if NodesSearched:
            node = NodesSearched.group(1).split(" ")
            #print(node)
        """ 匹配出消息 """
        MessageSearched = re.search(MessagePattern, line.strip())
        if MessageSearched:
            siganlList.clear()
            """如果匹配到了message,则获取到message的相关参数 
             比如匹配到了NM_Message_ESC_409,则会解析出改message的一些参数构成list对象['1033', 'NM_Message_ESC_409', '8', 'ESC']
             这四个参数分别是 messgage ID ;message name ; messgae dataLenth ,message sender
             而且把这个list对象 加在了 siganlList 索引0的位置
            """
            Message = list(MessageSearched.groups())
            siganlList.append(Message)
            """ 只 要 message的名字 messageName 列表中"""
            messageName.append(Message[1])
            """读取下一行"""
            line = f.readline()
            """因为有些message并没有定义signal,所以 下一行还是message"""
            MessageSearched = re.search(MessagePattern, line.strip())
            SignalSearched = re.search(SignalPattern, line.strip())
            """下一行如果不是message的内容 就一定是signal的内容了"""
            if not MessageSearched:
                while SignalSearched:
                    """获取信号的参数追加到siganlList"""
                    signal = list(SignalSearched.groups())
                    siganlList.append(signal)
                    """只获取 signal name"""
                    SignalsName.append(signal[0])

                    # 再次解析信号,直到这个message下的信号全部解析完毕
                    line = f.readline()
                    SignalSearched = re.search(SignalPattern, line.strip())
           # print(siganlList)
            c = copy.deepcopy(siganlList)
            allDatas.append(c)
        else:
            line = f.readline()
            MessageSearched = re.search(MessagePattern, line.strip())
    f.close()  # 将文件关闭
    return 1
def find_file():
    import os
    path = os.path.abspath('.')
    dirs = os.listdir(path)                    # 获取指定路径下的文件
    for i in dirs:
        if os.path.splitext(i)[1] == ".dbc":
            return  os.path.join(path,i)
if __name__ == '__main__':

    readFile()
    print(node)
    print(len(node))
    print(messageName)
    print(len(messageName))
    print(SignalsName)
    print(len(SignalsName))
    print(allDatas)
    print(len(allDatas))

下面的图片是用notepad++ 打开的dbc文件:代码中通过是通过正则表达式 进行解析 node,signal,message的

基于Python的对 汽车电子ECU的通信矩阵数据库文件(.dbc)的解析_第1张图片

你可能感兴趣的:(汽车电子)