精华内容
下载资源
问答
  • 使用DBC文件解析CAN帧2.1DBC文件2.2本博客布局3.DBC文件的创建3.1创建DBC文件代码3.2使用方法4.DBC文件发送指定格式的CAN数据4.1DBC文件发送指定格式的CAN数据代码4.2使用方法5.使用DBC文件解析接收到的CAN数据5.1...

    配置环境

    使用环境:python3.6
    平台:Windows10
    IDE:PyCharm

    1.环境配置

    1.1安装CAN通讯需要的包

    pip install canlib
    

    1.2 安装kvaser_drivers以及Kvaser CanKing

    这些软件可以在官网下载https://www.kvaser.com/download/

    官网是英文的,看起来可能有点吃力,这里也给出云盘连接:
    链接:https://pan.baidu.com/s/1LDKyIlOV0Ky4d2qxryLZGQ
    提取码:vwiv

    下载下来之后的文件是这样的,三个文件依次双击安装就行了

    在这里插入图片描述
    安装完后,在开始栏可以查看到已经安装好了
    在这里插入图片描述

    2.使用DBC文件解析CAN帧

    2.1DBC文件

    DBC是Database Can的缩写,其代表的是CAN的数据库文件,在这个文件中把CAN通讯的信息定义的非常完整清楚,在Windows下其存在的格式便是dbc,如图所示:
    在这里插入图片描述
    有了DBC文件便可以对接收到的CAN帧进行解析,分析一系列CAN帧代表的真实物理含义。
    正因为如此,每一个DBC文件都对应着一种CAN帧的规则,使用CAN作为通讯手段的设备(如汽车中发动机、车灯、车载空调等等)都有对应的DBC文件。

    2.2本博客布局

    本博客将从DBC文件的创建、使用DBC文件发送指定格式的CAN数据、使用DBC文件解析接收到的CAN数据来展开。

    3.DBC文件的创建

    3.1创建DBC文件代码

    # author:Hurricane
    # date:  2021/4/16
    # File : CAN_Create_Database.py 
    # E-mail:hurri_cane@qq.com
    
    
    
    import argparse
    from collections import namedtuple
    
    from canlib import kvadblib
    
    Message = namedtuple('Message', 'name id dlc signals')
    Signal = namedtuple('Signal', 'name size scaling limits unit')
    EnumSignal = namedtuple('EnumSignal', 'name size scaling limits unit enums')
    
    _messages = [
    	Message(
    		name='EngineData',
    		id=100,
    		dlc=8,
    		signals=[
    			Signal(
    				name='PetrolLevel',
    				size=(24, 8),
    				scaling=(1, 0),
    				limits=(0, 255),
    				unit="l",
    			),
    			Signal(
    				name='EngPower',
    				size=(48, 16),
    				scaling=(0.01, 0),
    				limits=(0, 150),
    				unit="kW",
    			),
    			Signal(
    				name='EngForce',
    				size=(32, 16),
    				scaling=(1, 0),
    				limits=(0, 0),
    				unit="N",
    			),
    			EnumSignal(
    				name='IdleRunning',
    				size=(23, 1),
    				scaling=(1, 0),
    				limits=(0, 0),
    				unit="",
    				enums={'Running': 0, 'Idle': 1},
    			),
    			Signal(
    				name='EngTemp',
    				size=(16, 7),
    				scaling=(2, -50),
    				limits=(-50, 150),
    				unit="degC",
    			),
    			Signal(
    				name='EngSpeed',
    				size=(0, 16),
    				scaling=(1, 0),
    				limits=(0, 8000),
    				unit="rpm",
    			),
    		]),
    	Message(
    		name='GearBoxInfo',
    		id=1020,
    		dlc=1,
    		signals=[
    			Signal(
    				name='EcoMode',
    				size=(6, 2),
    				scaling=(1, 0),
    				limits=(0, 1),
    				unit="",
    			),
    			EnumSignal(
    				name='ShiftRequest',
    				size=(3, 1),
    				scaling=(1, 0),
    				limits=(0, 0),
    				unit="",
    				enums={'Shift_Request_On': 1, 'Shift_Request_Off': 0},
    			),
    			EnumSignal(
    				name='Gear',
    				size=(0, 3),
    				scaling=(1, 0),
    				limits=(0, 5),
    				unit="",
    				enums={
    					'Idle': 0,
    					'Gear_1': 1,
    					'Gear_2': 2,
    					'Gear_3': 3,
    					'Gear_4': 4,
    					'Gear_5': 5,
    				},
    			),
    		]),
    ]
    
    
    def create_database(name, filename):
    	db = kvadblib.Dbc(name=name)
    
    	for _msg in _messages:
    		message = db.new_message(
    			name=_msg.name,
    			id=_msg.id,
    			dlc=_msg.dlc,
    		)
    
    		for _sig in _msg.signals:
    			if isinstance(_sig, EnumSignal):
    				_type = kvadblib.SignalType.ENUM_UNSIGNED
    				_enums = _sig.enums
    			else:
    				_type = kvadblib.SignalType.UNSIGNED
    				_enums = {}
    			message.new_signal(
    				name=_sig.name,
    				type=_type,
    				byte_order=kvadblib.SignalByteOrder.INTEL,
    				mode=kvadblib.SignalMultiplexMode.MUX_INDEPENDENT,
    				size=kvadblib.ValueSize(*_sig.size),
    				scaling=kvadblib.ValueScaling(*_sig.scaling),
    				limits=kvadblib.ValueLimits(*_sig.limits),
    				unit=_sig.unit,
    				enums=_enums,
    			)
    
    	db.write_file(filename)
    	db.close()
    
    
    if __name__ == '__main__':
    	parser = argparse.ArgumentParser(
    		description="Create a database from scratch.")
    	parser.add_argument('--filename', default=r'..\engine_example.dbc', help=(
    		"The filename to save the database to."))
    	parser.add_argument('-n', '--name', default='Engine example', help=(
    		"The name of the database (not the filename, the internal name."))
    	args = parser.parse_args()
    
    	create_database(args.name, args.filename)
    
    
    

    3.2使用方法

    代码中if __name__ == '__main__':下:

    parser.add_argument('--filename', default=r'..\engine_example.dbc', help=(
    		"The filename to save the database to."))
    

    指定的filename为创建的DBC文件的路径以及文件名,本代码中便是将DBC文件存在代码所在目录的上层目录中,以engine_example.dbc文件名保存

    代码中_messages列表
    在这里插入图片描述
    便是定义CAN帧解析的规则,可以定义:

    • CAN帧的id

    • CAN帧的数据长度

    • CAN帧的解析single规则
      等等…

      创建方式如下:

    在这里插入图片描述

    4.DBC文件发送指定格式的CAN数据

    4.1DBC文件发送指定格式的CAN数据代码

    # author:Hurricane
    # date:  2021/4/12
    # File : CAN_Random_Send.py 
    # E-mail:hurri_cane@qq.com
    
    import argparse
    import time
    import random
    
    from canlib import canlib, kvadblib
    
    
    bitrates = {
        '1M': canlib.canBITRATE_1M,
        '500K': canlib.canBITRATE_500K,
        '250K': canlib.canBITRATE_250K,
        '125K': canlib.canBITRATE_125K,
        '100K': canlib.canBITRATE_100K,
        '62K': canlib.canBITRATE_62K,
        '50K': canlib.canBITRATE_50K,
        '83K': canlib.canBITRATE_83K,
        '10K': canlib.canBITRATE_10K,
    }
    
    
    # 随机在dbc结构中抽取一个结构
    def set_random_framebox_signal(db, framebox, signals):
        sig = random.choice(signals)
        value = get_random_value(db, sig)
        framebox.signal(sig.name).phys = value
    
    # 随机在抽取到的结构帧的数值范围中产生一个值
    def get_random_value(db, sig):
        limits = sig.limits
        value = random.uniform(limits.min, limits.max)
    
        # round value depending on type...
        if (
                sig.type is kvadblib.SignalType.UNSIGNED or
                sig.type is kvadblib.SignalType.SIGNED
        ):
            # ...remove decimals if the signal was of type unsigned
            value = int(round(value))
        else:
            # ...otherwise, round to get only one decimal
            value = round(value, 1)
    
        return value
    
    
    def ping_loop(channel_number, db_name, num_messages, quantity, interval, bitrate, seed=0):
        db = kvadblib.Dbc(filename=db_name)
    
        ch = canlib.openChannel(channel_number, canlib.canOPEN_ACCEPT_VIRTUAL)
        ch.setBusOutputControl(canlib.canDRIVER_NORMAL)
        ch.setBusParams(bitrate)
        ch.busOn()
    
        random.seed(seed)
    
        if num_messages == -1:
            # used_messages为dbc文件定义的所有帧结构
            used_messages = list(db)
        else:
            used_messages = random.sample(list(db), num_messages)
    
        print()
        print("Randomly selecting signals from the following messages:")
        print(used_messages)
        print("Seed used was " + repr(seed))
        print()
    
        while True:
            # Create an empty framebox each time, ignoring previously set signal
            # values.
            framebox = kvadblib.FrameBox(db)
    
            # Add all messages to the framebox, as we may use send any signal from
            # any of them.
            for msg in db:
                framebox.add_message(msg.name)
    
            # Make a list of all signals (which framebox has found in all messages
            # we gave it), so that set_random_framebox_signal() can pick a random
            # one.
            signals = [bsig.signal for bsig in framebox.signals()]
    
            # Set some random signals to random values
            for i in range(quantity):
                set_random_framebox_signal(db, framebox, signals)
    
            # Send all messages/frames
            for frame in framebox.frames():
                print('Sending frame', frame)
                ch.writeWait(frame, timeout=5000)
    
            time.sleep(interval)
    
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(
            description="Send random CAN message based on a database.")
        parser.add_argument('channel', type=int, default=0, nargs='?', help=(
            "The channel to send messages on."))
        parser.add_argument('--bitrate', '-b', default='500k', help=(
            "Bitrate, one of " + ', '.join(bitrates.keys())))
        parser.add_argument('--db', default="../Mobileye.dbc", help=(
            "The database file to base messages on."))
        parser.add_argument('-Q', '--quantity', type=int, default=5, help=(
            "The number of signals to send each tick."))
        parser.add_argument('-I', '--interval', type=float, default=0.2, help=(
            "The time, in seconds, between ticks."))
        parser.add_argument('-n', '--num-messages', type=int, default=-1, help=(
            "The number of message from the database to use, or -1 to use all."))
        parser.add_argument('-s', '--seed', nargs='?', default='0', help=(
            "The seed used for choosing messages. If possible, will be converted to an int. If no argument is given, a random seed will be used."))
        args = parser.parse_args()
    
        if args.seed is None:
            seed = None
        else:
            try:
                seed = int(args.seed)
            except ValueError:
                seed = args.seed
    
        ping_loop(
            channel_number=args.channel,
            db_name=args.db,
            num_messages=args.num_messages,
            quantity=args.quantity,
            interval=args.interval,
            bitrate=bitrates[args.bitrate.upper()],
            seed=args.seed,
        )
    
    

    4.2使用方法

    这份代码的功能为:
    以DBC文件规定的数据格式,随机发送一些数据帧出去

    代码中if __name__ == '__main__':下:

        parser.add_argument('--db', default="../Mobileye.dbc", help=(
            "The database file to base messages on."))
    

    指定的filename为读取的DBC文件的路径,本代码中读取的DBC文件存在代码所在目录的上层目录中,以Mobileye.dbc文件名存在

    PS:这里面的DBC文件也可以改为3.1创建DBC文件代码中生成的engine_example.dbc文件

    此处附上两个DBC文件的云盘链接

    链接:https://pan.baidu.com/s/1JAT2o2fPzto8555qU-lVKg
    提取码:49bv

    为了测试发送数据是否成功,采用上篇博客2.2.1使用Kvaser Can King接收数据中的方法。链接如下:
    https://blog.csdn.net/ShakalakaPHD/article/details/115767739

    运行4.1代码:
    在这里插入图片描述

    可以看到Kvaser Can King接收到各式各样的数据,但是其中的具含义我们并不清楚,这边涉及到第5节,使用DBC文件解析接收到的CAN帧。

    5.使用DBC文件解析接收到的CAN数据

    5.1使用DBC文件解析接收到的CAN数据代码

    # author:Hurricane
    # date:  2021/4/16
    # File : CAN_Using_Database.py
    # E-mail:hurri_cane@qq.com
    
    import argparse
    
    from canlib import canlib, kvadblib
    
    
    bitrates = {
        '1M': canlib.canBITRATE_1M,
        '500K': canlib.canBITRATE_500K,
        '250K': canlib.canBITRATE_250K,
        '125K': canlib.canBITRATE_125K,
        '100K': canlib.canBITRATE_100K,
        '62K': canlib.canBITRATE_62K,
        '50K': canlib.canBITRATE_50K,
        '83K': canlib.canBITRATE_83K,
        '10K': canlib.canBITRATE_10K,
    }
    
    
    def printframe(db, frame):
        try:
            bmsg = db.interpret(frame)
        except kvadblib.KvdNoMessage:
            print("<<< No message found for frame with id %s >>>" % frame.id)
            return
    
        msg = bmsg._message
    
        # form = '═^' + str(width)
        # print(format(" %s " % msg.name, form))
    
        print('┏', msg.name)
    
        if msg.comment:
            print('┃', '"%s"' % msg.comment)
    
        for bsig in bmsg:
            print('┃', bsig.name + ':', bsig.value, bsig.unit)
    
        print('┗')
    
    
    def monitor_channel(channel_number, db_name, bitrate, ticktime):
        db = kvadblib.Dbc(filename=db_name)
    
        ch = canlib.openChannel(channel_number, canlib.canOPEN_ACCEPT_VIRTUAL)
        ch.setBusOutputControl(canlib.canDRIVER_NORMAL)
        ch.setBusParams(bitrate)
        ch.busOn()
    
        timeout = 0.5
        tick_countup = 0
        if ticktime <= 0:
            ticktime = None
        elif ticktime < timeout:
            timeout = ticktime
    
        print("Listening...")
        while True:
            try:
                frame = ch.read(timeout=int(timeout * 1000))
                printframe(db, frame)
            except canlib.CanNoMsg:
                if ticktime is not None:
                    tick_countup += timeout
                    while tick_countup > ticktime:
                        print("tick")
                        tick_countup -= ticktime
            except KeyboardInterrupt:
                print("Stop.")
                break
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(
            description="Listen on a CAN channel and print all signals received, as specified by a database.")
        parser.add_argument('channel', type=int, default=1, nargs='?', help=(
            "The channel to listen on."))
        parser.add_argument('--db', default="../Mobileye.dbc", help=(
            "The database file to look up messages and signals in."))
        parser.add_argument('--bitrate', '-b', default='500k', help=(
            "Bitrate, one of " + ', '.join(bitrates.keys())))
        parser.add_argument('--ticktime', '-t', type=float, default=0, help=(
            "If greater than zero, display 'tick' every this many seconds"))
        args = parser.parse_args()
    
        monitor_channel(args.channel, args.db, bitrates[args.bitrate.upper()], args.ticktime)
    
    

    5.2使用方法

    代码中if __name__ == '__main__':下:

        parser.add_argument('--db', default="../Mobileye.dbc", help=(
            "The database file to look up messages and signals in."))
    

    指定的filename为读取的DBC文件的路径,本代码中读取的DBC文件存在代码所在目录的上层目录中,以Mobileye.dbc文件名存在

    PS:这里面的DBC文件也可以改为3.1创建DBC文件代码中生成的engine_example.dbc文件

    为了测试解析数据是否有效,采用此博客中4.DBC文件发送指定格式的CAN数据节下的随机发送数据的代码发送数据。

    运行4.1节代码后,再运行5.1节代码来解析数据:

    在这里插入图片描述
    可以看到相较于Kvaser Can King接收到各式各样的数据,使用DBC文件解析后的数据都已准换为了真实的物理含义:
    在这里插入图片描述

    6.参考文献

    Python Canlib Documentation
    file:///D:/Program%20Files%20(x86)/kvaserCAN/canlib/python/pycanlib/docs/index.html

    7.结束语

    如果本文对你有帮助的话还请点赞、收藏一键带走哦,你的支持是我最大的动力!(づ。◕ᴗᴗ◕。)づ
    在这里插入图片描述

    展开全文
  • SAP DBC 使用简介

    2009-12-22 11:42:13
    SAP DBC 使用简介 BDC Program (Batch Data Communication Program) 是ABAP/4 用來載入資料異動SAP 資料庫的方法,先將要輸入的資料存在BDC Table中,使用CALL TRANSACTION 指令呼叫R/3輸入畫面,將輸入所需資料項自...
  • DBC文件的阅读方法

    2020-06-11 15:52:26
    第一个文件就是apollo官方可以通过工具直接生成protocol文件的,第二个文件主要是说明如何使用这个协议的,第三个文件是第一个文件的延展,具体到每个位或字节代表什么。但是可能部分厂家偷懒就只有第一个和第二个...

    问题由来

    最近为apollo适配新的线控的底盘,部分线控底盘的供应商会给三个文件:DBC文件,协议说明书和协议的详细文件(一般都是excel文件)。第一个文件就是apollo官方可以通过工具直接生成protocol文件的,第二个文件主要是说明如何使用这个协议的,第三个文件是第一个文件的延展,具体到每个位或字节代表什么。但是可能部分厂家偷懒就只有第一个和第二个文件。这个时候为了去写线控驱动就必须去读DBC 文件。

    为什么需要DBC文件

    当前汽车中的通信主要是用can总线通信(目前汽车以太网正在兴起)。dbc数据库文件是用来描述CAN网络节点间数据通讯的一种文件,包含了CAN总线协议中协议数据及其所代表的具体意义。它可以用来监测与分析CAN网络上的报文数据,也可以用来模拟某个CAN节点。由此可见,阅读DBC文件成了该领域所必须的一项技能。

    文件解析

    首先看一段DBC文件内容

    VERSION ""
    
    
    NS_ : 
    	NS_DESC_
    	CM_
    	BA_DEF_
    	BA_
    	VAL_
    	CAT_DEF_
    	CAT_
    	FILTER
    	BA_DEF_DEF_
    	EV_DATA_
    	ENVVAR_DATA_
    	SGTYPE_
    	SGTYPE_VAL_
    	BA_DEF_SGTYPE_
    	BA_SGTYPE_
    	SIG_TYPE_REF_
    	VAL_TABLE_
    	SIG_GROUP_
    	SIG_VALTYPE_
    	SIGTYPE_VALTYPE_
    	BO_TX_BU_
    	BA_DEF_REL_
    	BA_REL_
    	BA_DEF_DEF_REL_
    	BU_SG_REL_
    	BU_EV_REL_
    	BU_BO_REL_
    	SG_MUL_VAL_
    
    BS_:
    
    BU_: DCU IDS
    
    
    BO_ 256 IDS_DCU_MSG100: 8 IDS
     SG_ IDS_DCU_AutoCtrlEna : 0|1@0+ (1,0) [0|1] "-"  DCU
     SG_ IDS_DCU_ModeCtrl_CTROLL : 51|4@0+ (1,0) [0|15] "-"  DCU
     SG_ IDS_DCU_ModeCtrl_CHECKSUM : 63|8@0+ (1,0) [0|255] "-"  DCU
    
    版本信息

    版本信息可以省略,不用管。

    波特率定义
        格式如下:
                        BS_:[baudrate:BTR1,BTR2];
        其中BS_为关键字,用于定义CAN网络的波特率;[ ]内容表示为可选部分,可以省略(如下图例子中即把该部分省略了);但关键字”BS_:”必须存在,省略则会出错。这个文件中是默认的,给的说明书里说是500k,是否默认就是500k呢?简单查了下资料没有发现相关定义。有点不解。
    
    网络节点的定义
        格式如下:
    
     BU_:Nodename1 Nodename2 Nodename3 ……
    
        其中BU_为关键字,表示网络节点,格式中的Nodename1、Nodename2表示定义的网络节点名字,由用户自己定义;但需保证节点命名的唯一性。
    
        如示例中的BU_: DCU IDS :表示定义了DCU,IDS这两个网络节点。
    
    报文帧的定义
        格式如下:
                        BO_ MessageId(10进制数表示) MessageName: MessageSize Transmitter
    
        (1)、BO_为关键字,表示报文;
        (2)、MessageId为定义的报文ID,是以10进制数表示的;如例子中的996,代表报文ID为0x3E4;
        (3)、MessageName表示该报文的名字,命名规则和C语言变量相同;
        (4)、MessageSize表示该报文数据域字节数,为无符号整型数据;
        (5)、Transmitter表示发送该报文的网络节点;如果该报文没有指定发送节点,则该值需设置为” Vector__XXX”。
    
        如示例中的`BO_ 256 IDS_DCU_MSG100: 8 IDS ` :表示定义了一条由IDS这个节点发送,数据域长度为8字节,ID为256,名字命名为IDS_DCU_MSG100的报文。
    
    信号的定义
        格式如下:
                        SG_ SignalName : StartBit|SignalSize@ByteOrder ValueType (Factor,Offset) [Min|Max] Unit Receiver
    
        (1)、SG_为关键字,表示信号;
        (2)、SignalName、 StartBit、 SignalSize分别表示该信号的名字、起始位、信号长度;
        (3)、ByteOrder表示信号的字节顺序:0代表Motorola格式,1代表Inter格式;
        (4)、 ValueType 表示该信号的数值类型:+表示无符号数,-表示有符号数;
        (5)、Factor表示因子,Offset表示偏移量;这两个值于该信号的原始值与物理值之间的转换。
        转换如下:物理值=原始值*因子+偏移量;
        (6)、Min|Max表示该信号的最小值和最大值,即指定了该信号值的范围;这两个值为double类型;
        (7)、Unit表示该信号的单位,为字符串类型;
        (8)、Receiver表示该信号的接收节点;若该信号没有指定的接收节点,则必须设置为” Vector__XXX”。
    
        如示例中的`SG_ IDS_DCU_AutoCtrlEna : 0|1@0+ (1,0) [0|1] "-"  DCU` 
    

    表示定义了一个命名为IDS_DCU_AutoCtrlEna的信号,其起始位是第0位,信号长度1个位;信号是Motorola格式,数值类型为无符号类型数;因子为1,偏移量为0;信号取值范围为0到1;信号单位为字符串”-”(缺省);该信号接收节点为DCU这个节点。

    注解部分
        格式如下:
                        CM_ Object MessageId/NodeName “Comment”
    
        (1)、 CM_为关键字,表示注解信息;
        (2)、 Object表示进行注解的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”;
        (3)、 MessageId/NodeName 表示进行注解的对象,若前面的对象类型是信号或者报文,则这里的值应为报文的ID(10进制数表示);若前面的对象类型为节点,则这里的值应为节点的名字;
        (4)、 Comment表示进行注解的文本信息;
    
        如示例中的 CM_ SG_ 996 HUD_HeightLv “Control hud height level”;
    

    表示对ID为996(0x3E4)这条报文下的名为”HUD_HeightLv ”的信号进行注解说明,说明的内容为"Control hud height level"。

        又如	`在这里插入代码片`CM_ BU_ HUD “Head Up Display";表示对HUD这个节点进行注解说明,说明的内容为" Head Up Display "。
    
    属性定义部分
        格式如下:
                        BA_DEF_ Object AttributeName ValueType Min Max;
                        BA_DEF_DEF_ AttributeName DefaultValue;
    
        (1)、 BA_DEF_为关键字,表示属性定义;
        (2)、 Object表示属性定义的对象类型,可以是节点“BU_”、报文“BO_”、消息”SG_”、网络节点” ”(用空格表示)等;
        (3)、 AttributeName表示进行定义的属性名字;
        (4)、 ValueType表示属性值的类型,可以是整型、字符串、浮点型、枚举类型等;
        (5)、Min/Max表示属性值的上下最值,即指定了取值范围(字符串类型没有此项)。
        (6)、 BA_DEF_DEF_为关键字,表示定义属性的初始值;
        (7)、 DefaultValue表示该属性的初始值。
    
        如示例中的 BA_DEF_ SG_ “MyTry” INT 0 11;
                             BA_DEF_DEF_ “MyTry” 0;
        表示对定义了一个针对信号类型的属性,属性名为”MyTry”,属性值是整型数据,取值范围在0到11之间,初始值为0。
    
    数值表部分
        格式如下:
                        VAL_ MessageId SignalName N “DefineN” …… 0 “Define0”;
    
        (1)、VAL_为关键字,表示数值表定义;
        (2)、 MessageId表示该信号所属的报文ID(10进制数表示);
        (3)、 SignalName表示信号名;
        (4)、 N “DefineN” …… 0 “Define0”表示定义的数值表内容,即该信号的有效值分别用什么符号表示 。
    
        如示例中的 VAL_ 996 HUD_OffSt 1 “Active” 0 “Not Active”;
        表示对ID为996(0x3E4)的这条报文下的,一个命名为”HUD_OffSt”的信号,进行其数值表的定义;用”Active”取代1;用”Not Active”取代0。
    
    展开全文
  • 合并两个DBC文件的方法工具步骤实例配置库及canconvert的其他使用参考 工具 首先准备好合并文件的工具 1.利用python的pip安装canmatrix库。 语句: pip install canmatrix 2.安装完成后会在pip.exe的附近找到can...

    工具

    首先准备好合并文件的工具

    1.利用python的pip安装canmatrix库。
    语句:

    pip install canmatrix
    

    2.安装完成后会在pip.exe的附近找到canconvert.exe
    利用该脚本即可完成合并。

    (根据提示用pip安装需要的其他库)

    接下来跟大家讲讲具体步骤,很简单!

    步骤

    直接在命令窗中敲出语句:

    canconvert --merge=second.dbc source.dbc target.dbc
    

    很多人会出现
    FileNotFoundError: [Errno 2] No such file or directory: 'C'

    笔者找了很多方法,结果发现只需要将second.dbc文件的绝对路径中的**”磁盘字母以及冒号“**删掉,即可。

    实例

    接下来我将Q1合并到Q2上,生成的新文件为Z。
    注意此处示例这三个dbc文件都在桌面。

    语句:

    canconvert --merge=\Users\lenovo\Desktop\Q1.dbc C:\Users\lenovo\Desktop\Q2.dbc C:\Users\lenovo\Desktop\Z.dbc
    

    配置库及canconvert的其他使用参考

    笔者也是参考了很多优秀大佬的例子才成功的,故有此篇经验分享。
    [1]: https://canmatrix.readthedocs.io/en/latest/installation.html
    [2]: https://blog.csdn.net/u010808702/article/details/104249739?utm_medium=distribute.pc_relevant_download.none-task-blog-BlogCommendFromBaidu-2.nonecase&dist_request_id=b8d2e3dd-6add-488a-9d34-8e24b2432e27&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-BlogCommendFromBaidu-2.nonecas
    [3]: https://blog.csdn.net/xiaodouhao123456/article/details/104916870

    展开全文
  • 本文使用两种方法介绍 Spring Boot WebFlux 使用 R2DBC 连接 MySQL: 使用配置 Java 类 使用配置文件:application.yml 相关技术点:WebFlux、R2DBC 等技术请自行了解。 Spring Boot WebFlux 使用 R2DBC 技术连接 ...

    本文使用两种方法介绍 Spring Boot WebFlux 使用 R2DBC 连接 MySQL:

    • 使用配置 Java 类
    • 使用配置文件:application.yml

    相关技术点:WebFlux、R2DBC 等技术请自行了解。

    Spring Boot WebFlux 使用 R2DBC 技术连接 MySQL,首先需要在 WebFlux 项目的基础上导入以下两个依赖:

    <dependency>
        <groupId>dev.miku</groupId>
        <artifactId>r2dbc-mysql</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-r2dbc</artifactId>
    </dependency>
    

    方法一:使用 Java 配置文件

    在 Spring Boot WebFlux 项目中创建目录 config,添加以下两个配置 Java 类即可。

    ConnectionFactoryConfiguration.java 配置类,用来配置 MySQL 的连接信息。如下:

    package com.codergeshu.webfluxr2dbc.config;
    
    import dev.miku.r2dbc.mysql.MySqlConnectionConfiguration;
    import dev.miku.r2dbc.mysql.MySqlConnectionFactory;
    import io.r2dbc.spi.ConnectionFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @Date: 2021/2/23 10:28
     * @author: Eric
     */
    
    @Configuration
    public class ConnectionFactoryConfiguration {
        @Bean
        public ConnectionFactory connectionFactory() {
            return MySqlConnectionFactory.from(MySqlConnectionConfiguration.builder()
                    .host("127.0.0.1")         // 主机地址
                    .port(3306)                // 端口
                    .username("root")          // 用户名
                    .password("123456")        // 密码
                    .database("webflux_demo")  // 连接的数据库名称
                    .build());
        }
    }
    

    R2dbcConfiguration.java 配置类,用来启用 R2DBC 技术连接 MySQL。代码如下:

    package com.codergeshu.webfluxr2dbc.config;
    
    import io.r2dbc.spi.ConnectionFactory;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration;
    import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
    
    /**
     * @Date: 2021/1/26 11:29
     * @author: Eric
     */
    
    @Configuration
    @EnableR2dbcRepositories
    public class R2dbcConfiguration extends AbstractR2dbcConfiguration {
    
        private final ConnectionFactory connectionFactory;
    
        public R2dbcConfiguration(@Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
            this.connectionFactory = connectionFactory;
        }
    
        @Override
        public ConnectionFactory connectionFactory() {
            return this.connectionFactory;
        }
    }
    

    至此使用配置类方式就完成了使用 R2DBC 连接 MySQL,之后就可以使用 ReactiveCrudRepository 进行相关数据库操作了。

    方法二:使用 application.yml配置文件

    除了使用上述两个配置 Java 类外,我们还可以使用 application.yml 文件进行 R2DBC 连接 MySQL 的配置,内容如下:

    spring:
      r2dbc:
        url: r2dbc:mysql://127.0.0.1:3306/webflux_demo?serverTimezone=GMT&characterEncoding=UTF-8
        username: root
        password: 123456
        name: r2dbc
        pool:
          validation-query: SELECT 1
          enabled: true
    

    其配置信息类似于 ConnectionFactoryConfiguration.javaR2dbcConfiguration.java 的结合体。

    总结

    以上两种方法都能够使 WebFlux 项目使用 R2DBC 连接到 MySQL,选择其中一种方法即可,推荐选择 application.yml 配置文件,毕竟比较清晰且容易管理。

    作者信息

    大家好,我是 CoderGeshu,一个热爱生活的程序员,如果这篇文章对您有所帮助,还请大家给点个赞哦 👍👍👍

    另外,欢迎大家关注本人同名公众号:CoderGeshu,一个致力于分享编程技术知识的公众号!!

    一个人可以走的很快,而一群人可以走的很远……

    展开全文
  • 在window命令行中输入(还有其他安装方法,需要的另行了解) pip install canmatrix 安装好后,会在python\scripts\目录下生成canconvert和cancompare 2个程序文件,一个用来转换格式,一个用来比较两个DBC文件有...
  • 使用DBCView编辑DBC文件过程(一)

    千次阅读 2020-02-06 23:48:54
    这里写自定义目录标题1、工具下载2、DBCView使用2.1准备工作--获得免费...这里把DBCView的使用方法介绍一下 1、工具下载 网上很多提供下载的地方,都版本很低,这里提供最新版: DBCView的下载地址: 百度网盘:https...
  • 深入理解h2和r2dbc-h2

    万次阅读 热门讨论 2020-11-20 09:51:49
    本文将会介绍R2DBC的H2实现r2dbc-h2的使用方法和要注意的事项。一起来看看吧。
  • 交互的理智方法 介绍 sane-dbc解决了 Java 编程语言中 RDBMS 交互方面的问题。 虽然 JVM 生态系统中存在许多库,它们以优雅、扎实和高效的方式处理这个问题,但据我们所知,目前广泛使用的Java替代品在某种程度上...
  • 使用python 将DBC,arxml转换为excel文件

    千次阅读 2019-08-02 10:45:33
    工作中需要用到很多DBC,ARXML,FIBEX 文件,里面的signal message 很多,想要用python 来比较或转换。方法如下: 1.下载python,我装的是python3.7,安装的时候记得勾选 添加环境变量 详细如下...
  • React型关系数据库连接服务提供者接口(R2DBC SPI... 借助React式流,R2DBC使您能够从经典的“每个连接一个线程”模型转变为更强大且可扩展的方法。 提供一个开放的规范。 R2DBC是一个开放规范,它为驱动程序供应商实
  • 根据DBC文件生产C文件

    2020-07-15 10:32:47
    使用方法DBC2C.exe [DBC文件] [节点名称] 例如:DBC2C.exe Test.dbc MCU 附件里面已经有Demo文件和已经生成的C文件
  • dbc文件转excel

    2018-05-24 20:43:36
    汽车can总线下的dbc解析文件,用spy或者canoe什么的看起来太麻烦,系统的人就是想要看excel,么就搞了个dbc转excel工具,用python写的...具体使用方法:https://blog.csdn.net/hhlenergystory/article/details/80443454
  • 您可以将SqlQueries接口的实现传递给SqlQueries migrate()方法。 如果使用Spring Boot,只需定义一个SqlQueries类型的bean。 示例 。 产品特点 基于约定的文件名,例如V3__insert_to_customers__split,non...
  • 如果您通过标准课程VM使用Jupyter / IPython,请参阅来获取.ipynb文件。 如何下载实验室的.dbc文件-不要被欺骗! 确保下载原始存档。 如果下载位置错误,Github会很乐意为您提供扩展名为.dbc的文件,该文件只是...
  • PCAN-Explorer5 基本使用方法,其中包括了PCAN-Explorer5的CAN网络的接入、硬件通讯、基于ID的报文过滤、导入并使用DBC文件,trace的基本使用,宏的使用和说明
  • 文章目录PCAN-Explorer5 基本使用方法前言:F1 键的妙用1.查看插件类型2.与硬件通讯2.1 在 Tools 中选择创建一个 net2.2 连接到一个 net2.3 接收和发送报文2.4 导入 dbc 文件2.5 查看信号在 dbc 文件中的定义3.过滤...
  • 本文主要介绍JDBC批量Insert深度优化(有事务)的方法。 环境: MySQL 5.1 RedHat Linux AS 5 JavaSE 1.5 DbConnectionBroker 微型数据库连接池 测试的方案: 执行10万次Insert语句,使用不同方式。 A组:...
  • DBC和EXCEL相互转换

    千次阅读 2020-02-10 16:07:22
    最近发现Dbc与excel互转的需求比较广泛,本人之前查阅相关资料,发现了一种快速有效的方法,借此在家办公的时机整理成文档,供大家参考使用,若在使用过程中有问题也可在dbcview微信交流群交流,作者会及时给予解答...
  • VBA实现Excel转DBC

    千次阅读 2019-05-08 15:25:34
    使用方法 公众号回复VBA获取。 参考《Template》格式要求,输入DBC的信息,点击“Excel=>DBC”转化。 在CANdb++中检查输出结果。 注意:本工具非常简易,未对输入做详细检查,因此不建议用在商业用途。 ...
  • 负责对数据库执行行动查询命令二、连接各数据库的驱动程序 连接各数据库可以使用驱动程序,也可以使用数据源,不过我建议大家使用驱动程序,因为使用驱动程序非常方便、简单,而使用数据源比较麻烦。ODBC链接适合...
  • Linux下can总线dbc载入通信详解

    千次阅读 2018-08-23 10:52:15
    Can总线dbc报文解析程序 can总线dbc载入通信程序Git源代码:...该程序使用方法为:在程序所在目录下,命令行启动: ./dbc_load_0 can设备号 dbc文件名字 如上图所示,运行完成后程序...
  • R2DBC加入Reactive基金会

    2020-11-13 11:36:12
    R2DBC加入Reactive基金会 Reactive基金会是一个为加速构建下一代网络应用技术而建立的领导者社区,...反应式编程使用消息驱动的方法来实现当今网络云原生应用所需的弹性、可扩展性和响应性,与它们的基础架构无关。

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 164
精华内容 65
关键字:

dbc使用方法