E2E 端到端保护
一、E2E介绍
E2E通过一些机制,使sw-c发送终端和sw-c接收终端的数据保持一致,保证信息的完整性。
E2E可适用于各种总线通信,例如CAN、CAN FD、LIN、FlexRay总线通信中。
二、E2E算法
E2E策略的整体思路是CRC校验和计数器。E2E有很多算法,是autosar提供的,可以直接用,如E2E_P01,E2E_P02,E2E_P04,E2E_P05,E2E_P06。以E2E_P01进行算法说明。
发送方采用保护函数E2E_P01Protect,接收方采用校验函数E2E_P01Check。
发送方:选择算法E2E_P01,把需要保护的原始数据,DataID(16bit)、Counter通过算法计算出crc值,加上计数器的值(计数器每发送一次值就增加),形成E2E的报头,即4个bit的Counter,1个字节的CRC以及需要被保护的原数据,一起打包发送给接收方。
注:
1.当 E2E_P01DataIDMode = E2E_P01_DATAID_NIBBLE 时的DataID 信息在数据中位置由用户定义。
2.Data ID 有四种模式:E2E_P01_DATAID_BOTH、E2E_P01_DATAID_ALT、E2E_P01_DATAID_LOW、E2E_P01_DATAID_NIBBLE。
-
当 E2E_P01DataIDMode = E2E_P01_DATAID_BOTH 时,DataID 的长度为 16Bits。DataID 两个字节均参与 Crc 的计算,但是不参与数据传输;
-
E2E_P01DataIDMode = E2E_P01_DATAID_ALT 时,DataID 的长度为 16Bits。当 Counter 为偶数时,DataID 的低字节参与 Crc 的计算,但不参与数据传输, 而当 Counter 为奇数时,DataID 的高字节参与Crc 的计算,不参与数据传输;
-
当 E2E_P01DataIDMode = E2E_P01_DATAID_LOW 时,DataID 的高字节不使用,应置为 0x00,此时相当于可用 Data ID 长度为 8Bits。DataID 的低字节参与 Crc 的计算,但不参与数据传输;
-
当 E2E_P01DataIDMode = E2E_P01_DATAID_NIBBLE 时,DataID 高字节的高半字节不使用,应置为 0x00,此时相当于可用 DataID 的长度为 12Bits,且此时 Data ID 高字节的低半字节不仅参与 Crc 计算,还与数据一起传输,位置由 DataIDNibbleOffset 决定。
以上参考E2E技术手册。
接收方:接收方接收到发送方发送 数据后,使用同样的Crc 算法计算 Crc 值(一把钥匙配一把锁嘛)校验 Crc 是否一致,并校验计数器信息(计数器每接收一次值就增加),一致说明发送端和接收端的数据保持一致,信息完整。
三、代码说明
参考autosarE2E技术手册api。
例:原始数据:
uint8 Data[8] = { 0x00, 0x20, 0x55, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };
//DataID参数模式
typedef enum
{
E2E_P01_DATAID_BOTH = 0u,
E2E_P01_DATAID_ALT = 1u,
E2E_P01_DATAID_LOW = 2u,
E2E_P01_DATAID_NIBBLE = 3u
} E2E_P01DataIDMode;
//发送端数据类型定义
typedef struct
{
uint16 CounterOffset; /*!< Bit offset of Counter */
uint16 CRCOffset; /*!< Bit offset of CRC */
uint16 DataID; /*!< Unique identifier for protection against masquerading */
uint16 DataIDNibbleOffset; /*!< Bit offset of the high byte of Data ID */
E2E_P01DataIDMode DataIDMode; /*!< Inclusion mode of DataID in CRC computation */
uint16 DataLength; /*!< Length of data, in bits */
uint8 MaxDeltaCounterInit; /*!< Initial maximum allowed gap between two counter values of two consecutively received valid Data */
uint8 MaxNoNewOrRepeatedData; /*!< Maximum amount of missing or repeated Data */
uint8 SyncCounterInit; /*!< Number of Data required for validating the consistency of the counter
after detection of an unexpected behavior of a received counter */
} E2E_P01ConfigType;
//发送端计数器类型定义
typedef struct
{
uint8 Counter; /*!< Counter to be used for protecting the next Data */
} E2E_P01ProtectStateType;
//E2E_P01CheckStatusType
typedef enum
{
E2E_P01STATUS_OK = 0x00u,
E2E_P01STATUS_NONEWDATA = 0x01u,
E2E_P01STATUS_WRONGCRC = 0x02u,
E2E_P01STATUS_SYNC = 0x03u,
E2E_P01STATUS_INITIAL = 0x04u,
E2E_P01STATUS_REPEATED = 0x08u,
E2E_P01STATUS_OKSOMELOST = 0x20u,
E2E_P01STATUS_WRONGSEQUENCE = 0x40u
} E2E_P01CheckStatusType;
//接收端校验结果类型定义
typedef struct
{
uint8 LastValidCounter; /*!< Counter value most recently received */
uint8 MaxDeltaCounter; /*!< Maximum allowed difference between two counter values of consecutively received valid messages */
boolean WaitForFirstData; /*!< If true means that no correct Data has been received yet */
boolean NewDataAvailable; /*!< Indicates that new Data is available for E2E to be checked */
uint8 LostData; /*!< Number of Data lost since reception of last valid one */
E2E_P01CheckStatusType Status; /*!< Result of the verification of the Data */
uint8 SyncCounter; /*!< Number of Data required for validating the consistency of the counter after detection of an unexpected behavior of a received counter */
uint8 NoNewOrRepeatedDataCounter; /*!< Amount of consecutive reception cycles in which there was either no or repeated Data */
} E2E_P01CheckStateType;
//发送端数据配置
E2E_P01ConfigType ConfigData1={
8, /* Counter位于数据(MSB)第2字节低半字节。 */
0, /* Crc位于数据(MSB)第1字节。 */
0x12,/* 数据ID。 */
12, /* DataID高字节低半字节位于数据(MSB) 第2字节高半字节。 */
E2E_P01_DATAID_BOTH, /* DataID两字节均参与Crc计算。 */
64, /* 数据长度为8个字节。 */
2, /* 连续两个接收有效Counter的最大允许差值。 */
3, /* 接收端的最大丢失或重复次数。 */
2 /* 同步状态下Counter的初始值。 */
};
//接收端数据配置
E2E_P01ConfigType ConfigData2 = {
8, /* Counter位于数据(MSB)第2字节低半字节。 */
0, /* Crc位于数据(MSB)第1字节。 */
0x12, /* 数据ID。 */
12, /* DataID高字节低半字节位于数据(MSB)第2字节高半字节。 */
E2E_P01_DATAID_BOTH, /* DataID两个字节均参与Crc计算。 */
64, /* 数据长度为8个字节。 */
1, /* 连续两个接收有效Counter的最大差值。 */
3, /* 接收端的最大丢失或重复次数。 */
2 /* 同步状态下Counter的初始值。 */
};
//发送端初始化配置
E2E_P01ProtectStateType StateStatus1 = {1};
//接收端初始化配置
E2E_P01CheckStateType StateStatus2 = {
10, /* 上次接收的Counter值。 */
3, /* 两个连续接收有效Counter的最大允许差值。 */
FALSE, /* 非等待接收第一帧有效数据。 */
TRUE, /* 检测到新的有效数据。 */
0, /* 丢失的数据个数。 */
E2E_P01STATUS_OK, /* 数据校验成功。 */
0, /* 同步状态下Counter的初始值。 */
1 /* 检测到无数据或重复数据的次数。 */
};
//接收端校验配置
E2E_P01CheckStateType StateStatus3 = {
0, /* 上次接收的Counter值。 */
1, /* 两个连续接收有效Counter的最大差值不超过1。 */
FALSE, /* 非等待接收第一帧有效数据。 */
TRUE, /* 检测到新的有效数据。 */
0, /* 丢失的数据个数。 */
E2E_P01STATUS_NONEWDATA, /* 数据校验的结果。 */
0, /* 同步状态下Counter的初始值。 */
0 /* 检测到无数据或重复数据的次数。 */
};
四、应用
Std_ReturnType retVal;
Std_ReturnType retVal1;
1.初始化
retVal = E2E_P01ProtectInit (&StateStatus1);
retVal1 = E2E_P01CheckInit(&StateStatus2);
/* 通信状态Counter为1。 */
2. 初始化数据保护状态,调用形式如下:
retVal = E2E_P01Protect (&ConfigData1, &StateStatus1, &Data[0]);
3.数据传输:
for(i=0;i<8;i++)
{
Data1[i]=Data[i];
} /* 通信状态。 */
4. 按P01方式进行数据校验,调用形式如下:
retVal1 = E2E_P01Check (&ConfigData2, &StateStatus3, &Data1[0]);
返回E2E_P01STATUS_OK 校验通过
over