每天我都会刷十分钟小姐姐的健身视频,你看,自律其实没那么难——《自律:从入门到退圈》
在“细说DBC(一)”中曾列了两份表来讲报文信号的属性,其中大部分的属性配合说明应该很容易理解,作为补充,本篇就来聊一聊余下部分中值得一说的属性。
一、ByteOrder与Startbit 我们知道计算机存储数据是以字节(Byte)为单位的,将某个字节存入某个地址或从某个地址读出某个字节,对于单字节数据,这种处理方式简单直白没有问题,但当处理多字节数据时就会遇到问题:这些字节要按照怎样的顺序存入或读出地址空间呢?假设我们有一个uint32型的无符号四字节数据0x12345678U,还有一段为该数据开辟的地址空间,可以很容易找到两种解决方案:方案A:从数据的最高字节开始依次放入地址空间,最高字节放在最低地址;方案B:与方案A相反,从数据的最低字节开始依次放入地址空间,最高字节放在最高地址;实际上方案A就是常说的Motorola格式(Big-Endian),方案B就是Intel格式(Little-Endian)。由于两种格式的字节顺序是反过来的,用Motorola格式存储的数据绝不可用Intel格式来解析,反之亦然。现在,我们将数据0x12345678U换成DBC里的信号,地址空间换成DBC里报文的数据字节位置,自然就得到了信号的两种字节序(ByteOrder)形式。在确定了ByteOrder后,信号在报文中的位置由Startbit指定,在讲Startbit之前,需要了解下DBC对报文字节bit位的编排方式:bit位按照从右到左、从上到下的方式编号,Byte0的bit位是7~0,Byte1的bit位是15~8,其他字节依此类推,此为第一种方式,然后,我们将上图水平镜像翻转一下: 就得到了bit位的第二种编排方式,以上两种方式是可以在Message的Layout下显现的,另外还有一种方式,将第一种进行垂直镜像翻转(Byte位置不变): 这第三种方式在Layout下是看不到的,但是会体现在Startbit的显示上(见下面的Motorola Backward)。 下面来看Startbit,根据ByteOrder不同,Startbit总共有六种显示形式,其中Motorola有四种,Intel有两种。假设有一条总长(DLC)为4字节的报文,包含一个长度12bit的信号,我们来看下这6种形式有什么区别:1. Motorola Forward LSB: 首先Motorola格式决定了信号的高4bit位在前(Byte1),低8bit位在后(Byte2),然后Forward可理解为从前向后(正向)找到lsb所在的位置即为信号的起始位,这里为Bit16。 2. Motorola Forward MSB: 和上一种唯一的区别是用信号msb所在位置(Bit11)作为起始位。 3. Motorola Backward: Backward可理解为从后往前(反向)找到lsb所在位置(bit8)作为信号的起始位,注意这里使用bit位编排的第三种方式。 4. Motorola Sequential: Sequential可理解为正序查找,这种比较符合我们计数习惯,从上到下、从左到右(bit位编排第二种方式)计数找到msb所在位置(bit12)作为信号的起始位。 5. Intel Standard: Intel和Motorola格式相反,信号的低4bit在前(Byte1),高8bit在后(Byte2),Standard格式下使用lsb位置(bit12)作为信号的起始位。 6. Intel Sequential: Intel的Sequential和Motorola一样,也是从上到下、从左到右数位置,以lsb的位置(bit11)作为信号的起始位。 以上六种形式可以通过CANdb工具进行切换,点击Options菜单下的Settings选项,在弹出的设置对话框中可以选择Motorola和Intel的具体显示形式:例如,选择Motorola forward MSB时,报文中信号的Startbit如下: 选择Motorola forward LSB时,信号的Startbit如下(注意前后两图的区别): 这里还有一个Bitindex选项,对应的功能就是要不要反转Byte中的Bit位顺序,在报文的Layout界面也有这个选项,不勾选的话对应前面所讲字节bit位编排的第一种方式: 勾选的话则对应第二种方式: 通过Inverted选项可以从Layout界面下观察Motorola Sequential和Intel Sequential两种Startbit显示形式,看起来比较直观,遗憾的是对应Motorola Backward的第三种编排方式从Layout下是看不到的。 注意:Startbit在DBC文件里的存储采用的是固定形式,Motorola采用forward MSB形式来存储,而Intel采用Standard形式来存储,你在Settings下对起始位显示形式的修改只影响图形界面下的显示(感兴趣的话,可以以文本方式打开DBC文件,观察修改前后存储的Startbit是否会有变化)。二、信号公式 直接上公式: Physical value = Raw value * Factor+ Offset 这里Factor和Offset为信号的属性,Raw value为总线值,即该信号在总线上传输时的值,Physical value为物理值,通常带有单位,表示具体的物理含义。下面以一个水温信号为例来说明公式相关的注意事项: 图中Factor为1,Offset为-40,为了计算Physical value,还需要知道Raw value,但是找遍DBC也看不到哪里有定义“Raw value”这一项,Raw value在哪里呢?实际上,信号的Length决定了Raw value(总线值),更确切的说是总线值的最大范围,这里Length为8bit,也就隐含了该信号可取值范围为0~255,现在,将1,-40,0~255代入上面的公式,便得到了Physical value=-40~215℃,而此范围正好对应了图中的Minimum和Maximum值。现在我们知道水温的最小值是-40℃,最大值是215℃,并且-40℃时从总线上看该信号值为0,215℃时从总线上看该信号值为255,假设我们发现最大温度只能达到200℃,将Maximum改为200,那么当总线值达到240时根据公式即会达到最大温度,但240并没有达到总线值的最大值,实际应用中,根据需要可以刚好使用信号的整个取值范围,或者只使用其一部分取值范围。通常信号的Value Type都使用Unsigned类型,所以在表示能取负值的物理数据时,会使用负的Offset,这样可以将负值映射到非负(≥0)区间上,便于处理。 另一个需要注意的地方是,报文信号的接收方和发送方对公式的处理是相反的,对于接收方,将收到的信号Raw value直接应用公式计算出Physical value进行使用,对于发送方,则是根据Physical value逆向应用公式计算出Raw value并发送到总线上。三、Multiplexing/Group 1. Signal Group 通常一条报文里的各个信号在收发的时候是相互独立的,比如下面的示意图中ECU_A与ECU_B之间的通信(注意图示及描述只是简易说明,并不和AUTOSAR的通信实现对应):
ECU_A中Module1~3分别按照自身的调度周期产生Signal1~3三个信号并将其放入各自的Buffer缓存,报文发送调度模块再将Buffer中的值放入底层硬件寄存器发送到总线上,ECU_B作为接收节点处理流程正好相反:总线上的信号先到底层硬件寄存器,然后报文接收调度模块将值从寄存器拷贝到Buffer(更常用的方式是使用接收中断处理,在中断中拷贝数据至Buffer),最后Module4~6从Buffer中取出信号值使用。 现在将时间轴放大到某个时刻t,此时ECU_A的Module1更新了Buffer1,紧接着Module2更新了Buffer2,又过了一段时间Δt后,Module3的调度还没到,但是报文发送的调度该执行了,于是Buffer1~3的内容被拷贝至底层寄存器发送到了总线上,因此,总线报文中三个信号的值并不是同一时刻的,那如果想要同一时刻三个信号的值呢?例如,三个信号分别表示物体在空间中的位置坐标x,y,z,我们肯定不希望x,y更新了,z却还是之前的值,这里就可以使用Signal Group。Group的概念很好理解,就是将同一条报文里的多个信号打包成一组,犹如一个信号。如果将上面的Signal1~3打包成组的话,等价于将三个信号组合成一个更大的信号,这样每次更新都会同时更新三个信号。注意Signal Group只能从Mdoule之下保证同时性,对于Module自身调度、计算、刷新各个原始值存在的时差,信号组是无法消除的。要新建信号组,在Messages下右击报文选择New Signal Group: 建好信号组后,将目标信号直接拖拽至组名下即可添加组信号,添加好后在Multiplexing/Group列会显示组名: 2. Signal Multiplexing 信号复用简单来讲就是一条报文里传输的信号不是固定的,可以动态变化,通过设置一个信号作为复用选择器(Multiplexor),可以控制切换报文里的其它信号:上图中信号S0为Multiplexor,根据S0取值不同,报文里包含的信号也会不同,S0=0时,后跟信号S1、S2和S3,S0=1时,后跟信号变成了S4和S5。那么如何在DBC里配置信号复用呢,还以上图为例,在信号S0上右击选择Edit mapped Signal打开编辑窗口(也可以直接双击S0信号),Multiplexortype项设置为Multiplexor Signal,表示S0为选择器:将S1的Multiplexortype设置为Multiplexed Signal,Multiplex Value设置为0,表示S1为被选择的信号,且当选择器为0时有效: 同理,将S2、S3的Multiplex Value也设为0,S4、S5的Multiplex Value设为1,S6的Multiplex Value设为2。全部设置好后,打开报文的Layout界面,通过Multiplexor Signal可以切换不同的信号布局: 另外,我们还可以设置多个Multiplexor: 注意:设置多个Multiplexor需要打开Extended Signal Multiplexing功能(位于Settings窗口下的Edit选项卡),并且该功能当前只支持少数几种特定的DBC文件: 四、报文信号的发送方式 报文的发送方式从本质上可以归为两种:周期型和事件型,但由于事件型的触发方式各不相同,再加上事件型和周期型又可以混合使用,导致实际的发送行为多种多样,下表列出了不同报文发送类型和信号发送类型组合起来时报文的行为表现,每种方式下方标明了相关属性参数同时给予图示方便理解。 | | | | | | | | | | | | | | | | | Cyclic or OnWriteWithRepetition | | | | | | | | | | | | | | Cyclic or OnChangeWithRepetition | | | | | | | | | | | | | | Cyclic or IfActiveWithRepetition | | | | | | | | | | | | | | |
| | |
|