中文  |  English
所在位置:市场活动 > 客户案例与技术文章

LIN总线帧结构及各场干扰

一、LIN总线帧结构



一个完整的LIN总线报文帧“Message Frame”包含报头“Header”和响应“Response”,主任务发送报头,从任务用响应来补充报头形成完整的报文。    

图片1.png

截取自LIN Specification Package Revision 2.1


其中帧头包括间隔场、同步段以及标识符场,应答包括数据段和校验和场。每个字节之间存在字节间隔(Inter-byte Space);在报头与响应之间存在响应间隔(Response Space);两帧LIN报文之间存在帧间间隔(Inter-frame Space)。下面将详细介绍每个段的具体内容格式。

1.间隔场

间隔场由间隔信号和间隔界定符组成。间隔场表示一帧报文的起始,由主节点发出。间隔信号至少由13个显性位组成,间隔界定符至少由1个隐形位组成。间隔场是唯一一个不符合字节场格式的场,从节点需要检测到至少连续11个显性位才认为是间隔信号。

图片2.png

截取自LIN Specification Package Revision 2.1



2.同步场

同步场顾名思义它的作用是确保所有从节点使用与主节点相同的波特率发送和接收数据,以下降沿为判断标志,同步段采用一个固定的字节结构0X55。从节点通过接收主节点发出的同步段,计算出主节点位速率,根据计算结果对自身的位速率重新作调整。计算公式如下:1位时间 =(第7位的下降沿时刻 - 起始位的下降沿时刻)/ 8

图片3.png

截取自LIN Specification Package Revision 2.1


3.标识符场

标识符场由两部分组成,受保护 ID 段的前 6 位叫作帧 ID(Frame ID),加上两个奇偶校验位后称作受保护 ID段。

图片4.png


截取自LIN Specification Package Revision 2.1



帧ID的范围在0x00~0x3F之间,共64个。帧ID标识了帧的类别和目的地。从任务对于帧头作出的反应(接收/发送/忽略应答部分)都是依据帧ID判断的。如果帧ID传输错误,将会导致信号无法正确到达目的地,因此引入奇偶校验位。校验公式如下,其中“⊕”代表“异或”运算,“¬”代表“取非”运算。

P0 = ID0 ⊕ ID1 ⊕ ID2 ⊕ ID4

P1 = ¬ (ID1 ⊕ ID3 ⊕ ID4 ⊕ ID5)

4.数据场

数据场用于存储节点发送的数据,数据场长度1到8个字节,采用低字节先发,低位先发策略,如果某一信号长度超过1个字节,采用低位在前的方式发送。

图片5.png

截取自LIN Specification Package Revision 2.1


5.校验和场

检验和场用于校验接收到的数据是否正确。校验分为经典校验(Classic Checksum)和增强校验(Enhance Checksum)。经典校验仅校验数据场,适用于诊断帧和与 LIN1.x 从机节点通信;增强校验校验标识符场和数据场,适用于与 LIN2.x 从机节点通信(诊断帧除外)。采用标准型校验和还是增强型校验和由主机节点管理,发布节点和各收听节点根据帧ID来判断采用哪种校验和。

图片6.png

截取自LIN Specification Package Revision 2.1



二、LIN总线帧结构干扰



LIN帧的不同场格式需要按照协议进行开发,为了测试样件是否不响应错误的帧结构,就需要对LIN帧中各个场分别进行干扰以达到所需要的测试目的。实现干扰的方式有很多,本文通过CAPL自带函数来进行相应的干扰,下面将对CAPL函数linSendHeaderError()、linInvertRespBit()、linInvertHeaderBit()进行介绍。

1.linSendHeaderError()

该函数用于干扰报文头,包含三个参数,一个是syncByte,用于设置同步场位;一个是idWithParity,用于设置标识符场;最后一个是StopAfterError,该位置1表示如果报头中一旦有某个场出现错误,则终止之后报头场的发送。具体参数如图所示。

图片7.png

截取自Vector Browser Helper


下面通过一个干扰ID为0x33的报文PID场中奇偶校验位的实例,来帮助大家进一步深入理解该函数。


// Force an error in header of LIN frame with ID=0x33 by setting wrong protected ID

on key 'h'

{

   byte linID, protectedID, corParity, errParity, errPID;

   // calculate protected ID with wrong parity bits

   linID = 0x33; // use frame ID=0x33

   protectedID = linGetProtectedID(linID); // get protected ID

   corParity = (protectedID & 0xC0) >> 6; // extract parity (0xC=0=11000000)

   errParity = (corParity ^ 0x2) & 0x3; // calculate wrong parity using XOR

   errPID = linID | (errParity << 6); // calculate PID with wrong parity

   linSendHeaderError(0x55, errPID, 0);

}


给大家大致解释一下脚本的实现逻辑,首先通过linGetProtectedID()可以获取该报文正确的PID值,然后通过corParity = (protectedID & 0xC0) >> 6提取出奇偶校验位,与0x2异或干扰校验位,最后通过errPID = linID | (errParity << 6)得出一个干扰过奇偶校验位的PID值并赋值给自己先前声明的errPID即得到了一个带有错误奇偶校验位的PID值,通过函数linSendHeaderError(0x55,errPID,0)发送错误PID值的LIN报头,即实现了对PID场的干扰。

2.linInvertRespBit()

该函数用于干扰响应,主要关注的参数如下,byteIndex用来指定干扰数据场第几字节(如果该参数值设置为报文长度,则干扰的是校验位长度);bitIndex用来指定干扰相对应第几位;level值为0的话,则把相应位从隐形干扰成显性,如果为1则反之从显性干扰成隐性;numberOfExecutions这个参数用来定义干扰的个数。具体参数如图所示。

图片8.png

截取自Vector Browser Helper


下面通过下面的示例,来帮助大家进一步深入理解该函数。

on key 'i'

{

...

// Invert first bit of byte field 8 for LIN frame with ID=0x33

linInvertRespBit(0x33, 7, 0);

...

// Invert bit 7 of checksum byte field for LIN frame with ID=0x33

linInvertRespBit(0x33, 8, 6);

...

// Invert stop bit of byte field 8 for LIN frame with ID=0x33

linInvertRespBit(0x33, 7, 8);

...

}

第一个函数是干扰第8个比特,由于bitIndex是0,所以干扰的是该比特的第一个位,其中第二个函数如果byteIndex的长度和DLC长度一样,则说明干扰的是该报文的checksum位。

3.linInvertHeaderBit()

该函数用于干扰报头,主要关注的参数如下,byteIndex用来指定干扰数据场类型,如果为-1,则是干扰间隔场,如果为0干扰同步场,如果为1干扰PID场;bitIndex用来指定干扰相对应第几位,如果为8则是干扰stopbit;level值为0的话,则把相应位从隐形干扰成显性,如果为1则反之从显性干扰成隐性;numberOfExecutions这个参数用来定义干扰的个数;disturbAfterHeaderID这个参数用来指定在该ID之后进行干扰,这个参数需要搭配waitForHeaders使用,如果设置waitForHeaders为0,disturbAfterHeaderID为5,则是等收到ID为5的报文后,在下一个报头直接进行干扰。具体参数如图所示。

图片9.png

截取自Vector Browser Helper



三、小结


通过上述的介绍,大家应该对基于CAPL对LIN报文各场干扰有了一定的了解了。通过发送干扰的报头或者对从节点的响应进行干扰,然后再发送正常帧,即可通过该正常帧的数据,对ResponseError位是否能正确置位进行测试了。

注:图中部分图片来自于Vector。