E2E(End-to-End)保护存在于安全性较高的信号,在信号传递的过程中,受软硬件的影响,发送端和接收端的数据可能不一致,此时E2E的作用就体现出来,系统可以快速检测出E2E异常,以便做出相应的异常处理。
本文以常用的Profile1为例,介绍相关的定义的和使用
E2E的依赖:E2E会调用CRC中的函数,例如Crc_CalculateCRC8
E2E_E_INPUTERR_NULL(0x13):至少有一个指针参数是NULL指针
E2E_E_INPUTERR_WRONG(0x17):至少有一个输入参数错误,例如超出范围
E2E_E_INTERR(0x19):发生了内部库错误(例如,程序流监控检测到的错误,违反了不变式或后置条件)
E2E_E_WRONGSTATE(0x1A):函数在错误的状态下执行
本章定义了对调用方可见的E2E库定义的数据类型。
下面显示的一些属性定义了数据偏移量。偏移量的定义规则如下:
CounterOffset:Counter的位偏移。CounterOffset应为4的倍数。在变体1A、1B和1C中,CounterOffset为8。
CRCOffset:CRC的位偏移量。偏移量应为8的倍数。在变体1A、1B和1C中,CRCOffset为0。
DataID:两字节,根据具体要求来定,每个Group的Data Id都可能不一样。
DataIDNibbleOffset:DataID的高字节的low nibble位偏移量。只有当DataIDMode = E2E_P01_DATAID_NIBBLE时,E2E库才会使用该参数(否则会被E2E Library忽略)
DataIDMode:Data ID的使用方式,包括both bytes, alternating, or low byte 等,在后面介绍
DataLength:数据的长度,以位为单位。该值应为8的倍数。DataLength包含Checksum和Counter
MaxDeltaCounterInit:两个连续接收到的有效数据的两个计数器值之间的初始最大允许间隙。例如,如果接收方获得计数器为1的数据,并且MaxDeltaCounterInit为1,那么在下一次接收时,接收方可以接受值为2和3的计数器,但不能接受值为4的计数器。
MaxNoNewOrRepeatedData:在正常通信条件下,接收方不希望超过的丢失或重复数据的最大数量。也就是允许counter不变时的次数
SyncCounterInit:在检测到接收到的计数器的意外行为后,必须用有效计数器(即在允许的锁定范围内的计数器)接收的验证计数器一致性所需的数据数。这个相当于是一个debounce,在故障确认后,需要连续检测SyncCounterInit配置的值后status才会变为正常状态
E2E_P01_DATAID_BOTH:两个字节包含在CRC(双字节ID配置)中,这在E2E变体1A中使用。
E2E_P01_DATAID_ALT:包括两个字节字节中的一个,根据Counter的奇偶性(交替ID配置)交替高字节和低字节。对于偶数Counter,使用低字节。对于奇数Counter,使用高字节。这在E2E变型1B中使用。
E2E_P01_DATAID_LOW:只包含低字节,从不使用高字节。这适用于特定系统中的id为8位的情况
E2E_P01_DATAID_NIBBLE:低字节包含在隐式CRC计算中,高字节的低字节与数据一起传输(即显式包含),不使用高字节的高字节。这适用于最多12位的id。这在E2E型1C中使用。也就是说data id的高字节的低四位是包含在data中的
LastValidCounter:最近收到的计数器值。如果尚未接收到数据,则该值为0x0。每次接收后,计数器都会使用接收到的值进行更新
MaxDeltaCounter:当前Counter最大差值
WaitForFirstData:如果为true,则表示在接收器初始化或重新初始化后尚未收到正确的数据(具有正确的data ID和CRC)
NewDataAvailable:向端到端库表示有新的数据可供库检查。此属性由E2E Library调用方设置,而不是由E2E Library。
LostData:自收到最后一个有效数据(消息)以来丢失的数据(消息)数。只有当Status等于E2E_P01STATUS_OK或E2E_P01STATUS_OKSOMELOST时,才会设置该属性。对于Status的其他值,LostData的值是undefined。E2E_P01CheckStatusType Status数据校验结果,由Check函数确定
Status:数据验证的结果,由Check函数确定
SyncCounter:在检测到接收到的计数器的意外行为后,必须用有效计数器(即在允许的锁定范围内的计数器)接收的验证计数器一致性所需的数据数。也就是故障出现后,重新接收到有效数据的计数。当SyncCounter超过SyncCounterInit后,E2E接收的数据才会变为有效
NoNewOrRepeatedDataCounter:连续接收周期的数量,其中(1)没有新数据,或(2)数据重复。
E2E_P01STATUS_OK:CRC校验通过,计数器相对于最近收到的状态为_INITIAL、_OK或_OKSOMELOST的数据加1.这意味着自最后一次正确的数据接收以来没有数据丢失
E2E_P01STATUS_NONEWDATA:错误:Check函数已被调用,但根据通信介质,自上次调用以来没有新的数据不可用.因此,没有执行数据的E2E检查。
E2E_P01STATUS_WRONGCRC:错误:根据通信介质已经接收到数据,但是
1.CRC不正确(适用于所有E2E配置文件1)或
2.数据ID高字节的low nibble错误(仅适用于E2E_P01DataIDMode = E2E_P01_DATAID_NIBBLE的E2E Profile1)
E2E_P01STATUS_SYNC:NOT VALID:在检测到计数器的意外行为后,新数据已被接收。数据有一个正确的CRC和一个在预期范围内的计数器,相对于最近收到的数据,但是计数器的确定的连续性检查还没有完成
E2E_P01STATUS_INITIAL:初始化:根据通信介质已经接收到新的数据,CRC是正确的,但这是接收方初始化或重新初始化后的第一个数据,因此计数器还不能验证
E2E_P01STATUS_REPEATED:错误:根据通信介质已经接收到新的数据,CRC是正确的,但是计数器与最近收到的状态为_INITIAL, _OK或_OKSOMELOST的数据相同。
E2E_P01STATUS_OKSOMELOST:OK:根据通信介质已经接收到新数据,CRC是正确的,计数器相对于最近收到的状态为_INITIAL, _OK或_OKSOMELOST的数据增加DeltaCounter (1 < DeltaCounter = MaxDeltaCounter)。这意味着自最后一次正确/初始接收以来,序列中的一些数据可能已经丢失,但这在配置的公差范围内。
E2E_P01STATUS_WRONGSEQUENCE:错误:根据通信介质已经接收到新的数据,CRC是正确的,但是计数器Delta (DeltaCounter > MaxDeltaCounter)相对于最近收到的状态为_INITIAL, _OK或_OKSOMELOST的数据太大。这意味着自最后一次正确/初始接收以来,序列中可能丢失了太多数据。
输入参数:ConfigPtr:E2E_P01的配置参数
输入输出参数:
StatePtr:当前E2E_P01通信状态
DataPtr:要发送的数据指针,经过E2E计算的
E2E_P01Protect函数主要用来根据输入的DATA和DATA ID等计算Counter和CRC
输入参数:Config:E2E_P01的配置参数
Data :需要E2E校验的数据
输入输出参数:State:当前E2E_P01的通信状态
E2E_P01Check主要用来根据输入的DATA和DATA ID等校验数据是否正常
将Profile 1的check status映射为通用check status,供E2E状态机检查功能使用。
Autosar官方文档上的图很好的解释了Config参数中的Counter相关配置项
发送主要分三步
第一步,将Counter写入数据
第二步,计算发送数据的CRC
第三步,增加Counter
/* Increase of the counter in data with respect to the configured offset */
E2E_Prv_P01WriteCounter(ConfigPtr, StatePtr, DataPtr);
/* Calculate CRC over data using CRC-8-SAE J1850 (standard version of the CRC AUTOSAR library and
write CRC into the specified region of data */
DataPtr[ConfigPtr->CRCOffset / 8U] = E2E_Prv_P01CalcCRC8(ConfigPtr, StatePtr->Counter, DataPtr);
/* Increments the sender status counter for the next message to send */
if (StatePtr->Counter < E2E_P01_MAXCOUNTER)
{
StatePtr->Counter++;
}
else
{
/* Max counter value already reached reset counter */
StatePtr->Counter = 0U;
}
E2E_Prv_P01CalcCRC8分四步:
第一步,计算DATA ID的CRC
第二步,计算Checksum前的数据的CRC(前提是Checksum的偏移要大于等于8)
第三步,计算Checksum后的数据的CRC
第四步,将结果与0xff异或得到最终CRC
使用示例:
E2E_P01ConfigType E2E_Profile01_Config_Test = {
8, //CounterOffset
0, //CRCOffset
0x11, //DataID
0, //DataIDNibbleOffset
E2E_P01_DATAID_BOTH, //DataIDMode
32, //DataLength
7, //MaxDeltaCounterInit
0, //MaxNoNewOrRepeatedData
0 //SyncCounterInit
};
E2E_P01CheckStateType E2E_P01CheckStateType_Test;
uint8 TestE2E_Data[8] = {0x00,0x02,0x44,0x33};
E2E_P01Protect(&E2E_Profile01_Config_Test,&E2E_P01CheckStateType_Test,TestE2E_Data);
第一步:增加MaxDeltaCounter
第二步:读取数据中的Counter
第三步:读取数据中的CRC
第四步:计算接收数据的CRC(以接收的Counter计算)
若校验不通过,则返回E2E_P01STATUS_WRONGCRC
否则进入校验Counter的函数
使用示例:
E2E_P01ConfigType E2E_Profile01_Config_Test = {
8, //CounterOffset
0, //CRCOffset
0x11, //DataID
0, //DataIDNibbleOffset
E2E_P01_DATAID_BOTH, //DataIDMode
32, //DataLength
7, //MaxDeltaCounterInit
0, //MaxNoNewOrRepeatedData
0 //SyncCounterInit
};
E2E_P01CheckStateType E2E_P01CheckStateType_Test;
E2E_P01Check(&E2E_Profile01_Config_Test,&E2E_P01CheckStateType_Test,TestE2E_Data);
发送和接收方使用同一套校验算法,为保证校验通过,对校验数据的位置排列也需要是固定的。
关于校验数据的排列,需要看OEM具体的定义,一般来说,可以有两种方式:
E2E作为功能安全实现的载体,可以很好的保护数据,对于安全要求高的数据传输,建议都加上E2E保护。