diff --git a/TSCP/src/MSCP/PFM/PFM_InputOutput.c b/TSCP/src/MSCP/PFM/PFM_InputOutput.c index ceaf884..19df851 100644 --- a/TSCP/src/MSCP/PFM/PFM_InputOutput.c +++ b/TSCP/src/MSCP/PFM/PFM_InputOutput.c @@ -89,6 +89,11 @@ static CM_INT32 s_2oo2OutputCheckFrame_Pack(OUT CM_UINT8 buf[], IN CM_UINT32 Buf static CM_INT32 s_2x2OutputCheckFrame_Pack(OUT CM_UINT8 *buf, IN CM_UINT32 BufSize); /* 输入阶段的2x2同步 */ static void s_input_2x2sync(void); + +/** + * @brief 输出阶段的2取校验 + */ +static void s_output_2oo2check(IN CM_UINT8* check_2oo2_Buf, IN CM_UINT32 check_2oo2_Len); /** * @brief 输入阶段的2x2同步 */ @@ -698,18 +703,8 @@ void PFM_OutputProc(void) /*- 是否开启了2oo2功能 */ if (0x55u == g_PFM_Cfg.M_2oo2_Enable) { - /*- 2oo2交换输出校验帧 */ - ret = SFM_2oo2_Exchange_Currency(check_2oo2_Buf, check_2oo2_Len, buf_peer, (CM_UINT32)check_2oo2_Len, ENUM_2oo2_OUTPUT_CHECK); - - /*- 检查2oo2双机的输出校验帧是否一致 */ - CM_RE_ASSERT(check_2oo2_Len == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_1); - ret = CM_Memcmp(check_2oo2_Buf, buf_peer, (CM_SIZE_T)check_2oo2_Len); - if(0 != ret) - { - MSCP_LOG_DATALEN(check_2oo2_Buf,check_2oo2_Len,"Ouput check_2oo2_Buf"); - MSCP_LOG_DATALEN(buf_peer,check_2oo2_Len,"Ouput buf_peer"); - CM_RE_ASSERT(0, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_2); - } + /* 2取校验 */ + (void)s_output_2oo2check(check_2oo2_Buf, (CM_UINT32)check_2oo2_Len); } else { @@ -723,6 +718,8 @@ void PFM_OutputProc(void) if (0x55u == g_PFM_Cfg.M_2x2_Enable) { /*- 输出阶段2x2处理 */ + ret = SFM_2oo2_Exchange_Currency(check_2x2_Buf, check_2x2_Len, &check_2x2_Buf[check_2x2_Len], sizeof(check_2x2_Buf) - check_2x2_Len, ENUM_2oo2_OUTPUT_EX); + check_2x2_Len += ret; SFM_2x2_OutputProc(check_2x2_Buf, check_2x2_Len); } else @@ -809,7 +806,6 @@ void PFM_OutputProc(void) void PFM_EndProc(void) { /*- 变量初始化 */ - CM_UINT32 crc = 0u; /* crc值 */ CM_UINT8 mybuf[8] = { 0u }; /* 本机2oo2缓冲区 */ CM_UINT8 peerbuf[8] = { 0u };/* 邻机2oo2缓冲区 */ CM_INT32 len = 0; /* 长度 */ @@ -823,7 +819,7 @@ void PFM_EndProc(void) { /*- 生成跟随数据的特征信息 */ CM_LongToChar((CM_UINT32)g_TxAppFollow_len, mybuf); - (void)CM_Memcpy(mybuf + 4, 4, g_TxAppFollow, 4); + CM_Memcpy(&mybuf[4u], 4u, g_TxAppFollow, 4u); /*- 2oo2交换特征信息 */ len = SFM_2oo2_Exchange_Currency(mybuf, 8, peerbuf, 8u, ENUM_2oo2_OUTPUT_CHECK); /*- 2oo2严格比较特征信息 */ @@ -831,6 +827,7 @@ void PFM_EndProc(void) if(0 == CM_Memcmp(mybuf, peerbuf, (CM_SIZE_T)8)) { /*- 无处理 */ + CM_Memcpy(&g_TxAppFollow[4u], 4u, &peerbuf[4u], 4u); } else { @@ -1918,5 +1915,41 @@ void PFM_CISendAppData(CM_UINT8* pData, CM_UINT32 dataLen) } } +/** + * @brief 输出阶段的2取校验 + */ +static void s_output_2oo2check(IN CM_UINT8* check_2oo2_Buf, IN CM_UINT32 check_2oo2_Len) +{ + CM_INT32 ret = 0, i = 0; + CM_UINT8 buf_peer[500] = {0u}; + /*- 2oo2交换输出校验帧 */ + CM_ASSERT(NULL != check_2oo2_Buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_1); + ret = SFM_2oo2_Exchange_Currency(check_2oo2_Buf, check_2oo2_Len, buf_peer, (CM_UINT32)check_2oo2_Len, ENUM_2oo2_OUTPUT_CHECK); + /*- 检查2oo2双机的输出校验帧是否一致 */ + CM_RE_ASSERT(check_2oo2_Len == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_2); + ret = CM_Memcmp(check_2oo2_Buf, buf_peer, (CM_SIZE_T)check_2oo2_Len); + if(0 != ret) + { + MSCP_LOG_DATALEN(check_2oo2_Buf,check_2oo2_Len,"Ouput check_2oo2_Buf"); + MSCP_LOG_DATALEN(buf_peer,check_2oo2_Len,"Ouput buf_peer"); + for (i = 1; i <= g_2x2oo2_data_num; i++) + { + if ((CM_UINT32)CM_TRUE == g_2x2oo2_tx[g_2x2oo2_base][i].b_2oo2_Enable) + { + ret = CM_Memcmp(check_2oo2_Buf + 4 + (i - 1) * 8, buf_peer + 4 + (i - 1) * 8, 8); + if(ret != 0) + { + MSCP_LOG_MSG("2oo2 output compare err, INDEX = %d, len = %d\n", i, (CM_SIZE_T)g_2x2oo2_tx[g_2x2oo2_base][i].buf_len); + MSCP_LOG_BIN(g_2x2oo2_tx[g_2x2oo2_base][i].p_buf, (CM_SIZE_T)g_2x2oo2_tx[g_2x2oo2_base][i].buf_len); + } + } + else + { + /*二取标志未使能*/ + } + } + CM_RE_ASSERT(0, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_3); + } +} diff --git a/TSCP/src/MSCP/SFM/SFM_2x2.c b/TSCP/src/MSCP/SFM/SFM_2x2.c index 98ac872..a0f987b 100644 --- a/TSCP/src/MSCP/SFM/SFM_2x2.c +++ b/TSCP/src/MSCP/SFM/SFM_2x2.c @@ -33,6 +33,9 @@ #include "stdarg.h" #include "SFM_Area.h" +#define BASE_FOLLOW_DATA_LEN (21u) /*平台跟随数据长度*/ +#define BASE_FOLLOW_ALL_LEN (21u+4u) /*平台跟随数据总长度*/ + /*通信中断时间和同步超时时间可以相同,此时优先执行通信中断切系*/ CM_INT32 g_2x2oo2_base = 0; /**< 2x2oo2双缓冲区的平台索引 */ @@ -66,7 +69,7 @@ static CM_UINT8 g_TxBaseFollow[SFM_FOLLOW_BUFF_SIZE]; /**< 发送的平台跟随 static CM_INT32 g_RxAppFollow_len = 0; /**< 收到的应用跟随数据长度 */ static CM_UINT8 g_RxAppFollow[MSCP_FOLLOW_BUFF_SIZE*2]; /**< 收到的应用跟随数据报文 */ static CM_INT32 g_RxAppFollowCrc_len = 0; /**< 收到的应用跟随数据长度 */ -static CM_UINT8 g_RxAppFollowCrc[8]; /**< 收到的应用跟随数据报文 */ +static CM_UINT8 g_RxAppFollowCrc[12]; /**< 收到的应用跟随数据报文 */ CM_INT32 g_TxAppFollow_len = 0; /**< 发送的应用跟随数据长度 */ CM_UINT8 g_TxAppFollow[MSCP_FOLLOW_BUFF_SIZE*2]; /**< 发送的应用跟随数据报文 */ @@ -116,6 +119,22 @@ static void s_Area_Transition(void); * @return ENUM_CM_TRUE-停止 ENUM_CM_FALSE-未停止 * */ static ENUM_CM_RETURN s_isPulseStopped(CM_UINT8 index); +/** + * @brief 输入阶段,主系发送平台跟随数据前的2oo2比较 + */ +static void s_2x2_BaseFollow_2oo2Check_Send(void); +/** + * @brief 输入阶段,非主系进行相关CRC校验后跟随 + */ +static void s_2x2_BaseFollow_Sync(void); +/** + * @brief 周期末阶段,备系接收主系应用跟随CRC后的比较逻辑 + */ +static void s_2x2_AppFollow_SyncCheck(void); +/** + * @brief 输出阶段,备系接收主系输出数据CRC后的比较逻辑 + */ +static void s_2x2_Output_SyncCheck(IN const CM_UINT8 *CheckBuf, CM_INT32 CheckLen); /** * 统一置切系标志 */ @@ -2351,7 +2370,7 @@ static void s_2x2_Recv(void) if (ENUM_CM_TRUE == ret) { /*- 更新跟随报文状态 */ - CM_RE_ASSERT(8 <= g_RxBaseFollow_len, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_4); + CM_RE_ASSERT(BASE_FOLLOW_ALL_LEN + 8u <= g_RxBaseFollow_len, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_4); s_2x2_Ctrl.RxBaseFollowSysCyc = msgCyc; MSCP_LOG_MSG("2x2 RxBaseFollowCyc = %d,rcvlen = %d,Time:%d us\r\n", msgCyc,g_RxBaseFollow_len,NOW_USED_TIME); } @@ -2418,7 +2437,7 @@ static void s_2x2_Recv(void) if (ENUM_CM_TRUE == ret) { /*- 更新跟随报文状态 */ - CM_RE_ASSERT(8 == g_RxAppFollowCrc_len, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_18); + CM_RE_ASSERT(12 == g_RxAppFollowCrc_len, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_18); s_2x2_Ctrl.RxAppFollowSysCyc = msgCyc; MSCP_LOG_MSG("2x2 RxAppFollowCrcCyc = %d,rcvlen = %d,Time:%d us\r\n", msgCyc,g_RxAppFollowCrc_len,NOW_USED_TIME); } @@ -2607,46 +2626,37 @@ void SFM_2x2_InputProc(void) CM_INT32 ret = 0; /* 临时变量 */ CM_UINT32 sysCyc = SFM_2x2_GetSysCount(); /* 系统周期号 */ CM_UINT32 areaCyc = SFM_Area_GetSysCount(); /* 区域周期号*/ - CM_UINT32 len_prtcl = 0u; /* 协议跟随数据长度 */ - CM_UINT32 len_sfprtcl = 0u; /* 协议跟随数据长度 */ - CM_UINT32 len_pfm = 0u; /* 平台跟随数据长度 */ - CM_UINT32 offset = 0u; /* 解包时使用offset*/ CM_UINT64 sTick = 0u; /* 起始Tick */ CM_UINT64 delta_Tick = 0u; /* Tickze增量 */ CM_UINT64 curTick = 0u; /* 当前Tick */ CM_UINT32 len = 0u; /* 临时变量 */ /*######################## 发送跟随数据(主系)########################*/ PFM_CFC_Check(33); - /*- 本系是否为主 */ - if ((ENUM_2x2_MASTER == s_2x2_Ctrl.LocalState)) + /*- 填写适配层(-1)跟随数据 */ + len = SFM_GetPrtclFollowData(g_TxBaseFollow + 4, (CM_UINT32)(sizeof(g_TxBaseFollow)) - 4u); + CM_LongToChar(len, g_TxBaseFollow); + g_TxBaseFollow_len = (CM_INT32)len + 4; + /*- 填写内网sfp跟随数据 */ + len = SFM_GetSfpPrtclFollowData(g_TxBaseFollow + g_TxBaseFollow_len, (CM_UINT32)(sizeof(g_TxBaseFollow)- g_TxBaseFollow_len - 4u)); + g_TxBaseFollow_len += len; + /*- 填写平台跟随数据 */ + CM_RE_ASSERT(g_TxBaseFollow_len <= ((CM_INT32)sizeof(g_TxBaseFollow) - BASE_FOLLOW_ALL_LEN), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_9);/*输出缓冲至少空闲8字节*/ + CM_LongToChar(21u, g_TxBaseFollow + g_TxBaseFollow_len); + CM_LongToChar(sysCyc, g_TxBaseFollow + g_TxBaseFollow_len + 4); + CM_LongToChar(SFM_GetTxSn(), g_TxBaseFollow + g_TxBaseFollow_len + 8); + g_TxBaseFollow_len += 12; + /*- 填写区域周期号*/ + CM_LongToChar(areaCyc, g_TxBaseFollow + g_TxBaseFollow_len); + g_TxBaseFollow_len += 4; + g_TxBaseFollow[g_TxBaseFollow_len++] = s_2x2_Ctrl.TimeSyncFlag_Area; + CM_64ToChar((CM_UINT64)s_2x2_Ctrl.AreaTimeOffset, g_TxBaseFollow + g_TxBaseFollow_len); + g_TxBaseFollow_len += 8; + /* 2取比较后,若为主系执行发送*/ + if(0x55u == g_PFM_Cfg.M_2oo2_Enable) { - /*- 填写适配层(-1)跟随数据 */ - len = SFM_GetPrtclFollowData(g_TxBaseFollow + 4, (CM_UINT32)(sizeof(g_TxBaseFollow)) - 4u); - CM_LongToChar(len, g_TxBaseFollow); - g_TxBaseFollow_len = (CM_INT32)len + 4; - /*- 填写内网sfp跟随数据 */ - len = SFM_GetSfpPrtclFollowData(g_TxBaseFollow + g_TxBaseFollow_len, (CM_UINT32)(sizeof(g_TxBaseFollow)- g_TxBaseFollow_len - 4u)); - g_TxBaseFollow_len += len; - /*- 填写平台跟随数据 */ - /*- 填写平台跟随数据 */ - CM_RE_ASSERT(g_TxBaseFollow_len <= ((CM_INT32)sizeof(g_TxBaseFollow) - 25u), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_9);/*输出缓冲至少空闲8字节*/ - CM_LongToChar(21u, g_TxBaseFollow + g_TxBaseFollow_len); - CM_LongToChar(sysCyc, g_TxBaseFollow + g_TxBaseFollow_len + 4); - CM_LongToChar(SFM_GetTxSn(), g_TxBaseFollow + g_TxBaseFollow_len + 8); - g_TxBaseFollow_len += 12; - /*- 填写区域周期号*/ - CM_LongToChar(areaCyc, g_TxBaseFollow + g_TxBaseFollow_len); - g_TxBaseFollow_len += 4; - g_TxBaseFollow[g_TxBaseFollow_len++] = s_2x2_Ctrl.TimeSyncFlag_Area; - CM_64ToChar((CM_UINT64)s_2x2_Ctrl.AreaTimeOffset, g_TxBaseFollow + g_TxBaseFollow_len); - g_TxBaseFollow_len += 8; - /*- 发送 */ - SFM_2x2_Send(g_TxBaseFollow, (CM_UINT32)g_TxBaseFollow_len, ENUM_2x2_MSG_BASE_FOLLOW); - } - else - { - /*- 无处理 */ + s_2x2_BaseFollow_2oo2Check_Send(); } + MSCP_LOG_MSG("timecurr 3.1 Input 2x2Send = %lld us\n", NOW_USED_TIME); /*########################2x2对系数据接收########################*/ PFM_CFC_Check(34); @@ -2730,35 +2740,9 @@ void SFM_2x2_InputProc(void) if ((ENUM_2x2_OFFLINE == s_2x2_Ctrl.LocalState) || (ENUM_2x2_SLAVE == s_2x2_Ctrl.LocalState)) { - if ((g_RxBaseFollow_len >= 12u) && (s_2x2_Ctrl.RxBaseFollowSysCyc > 0u))/*通过数据长度判断是否有新数据*/ + if ((g_RxBaseFollow_len >= BASE_FOLLOW_ALL_LEN + 8u) && (s_2x2_Ctrl.RxBaseFollowSysCyc > 0u))/*通过数据长度判断是否有新数据*/ { - offset = 0u; - /*- 适配层协议数据跟随*/ - len_prtcl = CM_LongFromChar(g_RxBaseFollow); - CM_RE_ASSERT(len_prtcl <= ((CM_UINT32)g_RxBaseFollow_len - 4u), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_3); - SFM_SetPrtclFollowData(g_RxBaseFollow + 4u); - - /*- sfp协议数据跟随*/ - len_sfprtcl = CM_LongFromChar(g_RxBaseFollow + 4u + len_prtcl); - CM_RE_ASSERT(len_prtcl + len_sfprtcl <= ((CM_UINT32)g_RxBaseFollow_len - 8u), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_10); - SFM_SetSfpPrtclFollowData(len_sfprtcl, g_RxBaseFollow + 4u + len_prtcl + 4u); - - /*- 平台数据跟随*/ - len_pfm = CM_LongFromChar(g_RxBaseFollow + 4u + len_prtcl + 4u + len_sfprtcl); - CM_RE_ASSERT(len_pfm == ((CM_UINT32)g_RxBaseFollow_len - len_prtcl - len_sfprtcl - 12u), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_4); - CM_RE_ASSERT(len_pfm == 21u, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_5); - /*此处使用临时周期号接收,在周期末同步*/ - offset = 12u + len_prtcl + len_sfprtcl; - s_2x2_Ctrl.SysCycSync = CM_LongFromChar(&g_RxBaseFollow[offset]); /* parasoft-suppress BD-PB-CHECKRET "此处无需检查CM_LongFromChar()的返回值" */ - offset += 4u; - SFM_SetTxSn(CM_LongFromChar(&g_RxBaseFollow[offset])); - offset += 4u; - s_2x2_Ctrl.AreaCycSync = CM_LongFromChar(&g_RxBaseFollow[offset]); - offset += 4u; - s_2x2_Ctrl.TimeSyncFlag_Area = g_RxBaseFollow[offset]; - offset += 1u; - s_2x2_Ctrl.AreaTimeOffset = (CM_INT64)CM_64FromChar(&g_RxBaseFollow[offset]); - offset += 8u; + s_2x2_BaseFollow_Sync(); /*- 本周期是否跟随成功 */ /*- 记录本次跟随时间 */ @@ -2904,47 +2888,7 @@ void SFM_2x2_OutputProc(IN const CM_UINT8 *CheckBuf, CM_INT32 CheckLen) if ((sysCyc == s_2x2_Ctrl.RxCheckSysCyc) && (CheckLen == s_2x2_Ctrl.RxCheckLen)) { /*- 进行输出比较 */ - ret = CM_Memcmp((const void*)CheckBuf, (void*)s_2x2_Ctrl.RxCheckFrame, (CM_SIZE_T)CheckLen); - /*- 输出比较是否一致 */ - if (0 == ret) - { - /*- 更新输出比较状态 */ - s_2x2_Ctrl.LastCheckOKCount = SFM_2x2_GetSysCount(); - s_2x2_Ctrl.OutPutCheckFailFlag = 0u; - MSCP_LOG_MSG("Out Put Success!\n"); - } - else - { - /*- 更新OutPutCheckFailFlag则降级为离线,因为如果收到输出数据但是比较失败,则降为离线状态 */ - s_2x2_Ctrl.OutPutCheckFailFlag = 1u; - for(i = 0u;i < CheckLen;i++) - { - if(CheckBuf[i] == s_2x2_Ctrl.RxCheckFrame[i]) - { - - } - else - { - /*- 跳出 */ - break; - } - } - /*记录暗文日志*/ - (void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_2X2_OUT_CHECK_FAIL,3u, - sizeof(CM_UINT8),s_2x2_Ctrl.OutPutCheckFailFlag, - sizeof(CM_UINT32),i, - sizeof(CM_UINT32),s_2x2_Ctrl.RxCheckSysCyc); - MSCP_LOG_MSG("Out Put failed_[%d]!\n",i); - MSCP_LOG_BIN(CheckBuf,CheckLen); - if(ENUM_2x2_SLAVE == s_2x2_Ctrl.LocalState) - { - CM_RE_ASSERT(0, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_3); - } - else - { - /*- 无处理 */ - } - } + s_2x2_Output_SyncCheck(CheckBuf, CheckLen); } else { @@ -3082,13 +3026,13 @@ void SFM_2x2_EndProc(void) if(ENUM_2x2_SLAVE == SFM_2x2_GetPartner2x2State()) { /*- 发送跟随数据 */ - SFM_2x2_Send(g_TxAppFollow, (CM_UINT32)8, ENUM_2x2_MSG_APP_FOLLOW_CRC); + SFM_2x2_Send(g_TxAppFollow, (CM_UINT32)12, ENUM_2x2_MSG_APP_FOLLOW_CRC); MSCP_LOG_MSG("Iam master partner is slave send appfollowcrc\n"); } else { - SFM_2x2_Send(g_TxAppFollow + 4, (CM_UINT32)g_TxAppFollow_len, ENUM_2x2_MSG_APP_FOLLOW); - MSCP_LOG_MSG("Iam master partner is offline send appfollow, cyc:%d, len = %d, reallen = %d\n", g_MSCP_SysCount, g_TxAppFollow_len, CM_LongFromChar(g_TxAppFollow + 4)); + SFM_2x2_Send(g_TxAppFollow + 8, (CM_UINT32)g_TxAppFollow_len, ENUM_2x2_MSG_APP_FOLLOW); + MSCP_LOG_MSG("Iam master partner is offline send appfollow\n"); } curTickTest[1] = CM_GetTick(); break; @@ -3097,19 +3041,7 @@ void SFM_2x2_EndProc(void) curTickTest[0] = CM_GetTick(); if (s_2x2_Ctrl.RxAppFollowSysCyc >= sysCyc) { - cmp_ret = CM_Memcmp(g_TxAppFollow, g_RxAppFollowCrc, 8);//如果同步失败 备系降为离线 - if(0 == cmp_ret) - { - /*- 跟随数据和主系一致*/ - s_2x2_Ctrl.AppFollowCmpFlag = 0u; - MSCP_LOG_MSG("CRC cmp is OK\n"); - } - else - { - /*- 比较失败 降离线*/ - s_2x2_Ctrl.AppFollowCmpFlag = 1u; - MSCP_LOG_MSG("CRC cmp is fail\n"); - } + s_2x2_AppFollow_SyncCheck(); } else { @@ -3347,8 +3279,9 @@ CM_UINT8 SFM_2x2_SetFollowData(IN const CM_UINT8 Data[], IN CM_UINT32 Len) g_TxAppFollow_len = (CM_INT32)CM_UNSIGNED_INT_EXP(Len + 4u); crc = CM_Crc32(Data, Len); CM_LongToChar(crc, g_TxAppFollow); - CM_LongToChar(Len, g_TxAppFollow + 4); - (void)CM_Memcpy((void*)(g_TxAppFollow + 8), sizeof(g_TxAppFollow) - 8u, Data, (CM_SIZE_T)Len); + /* 预留4字节记录另一CPU的CRC */ + CM_LongToChar(Len, g_TxAppFollow + 8); + (void)CM_Memcpy((void*)(g_TxAppFollow + 12), sizeof(g_TxAppFollow) - 12u, Data, (CM_SIZE_T)Len); rt = 1u; } else @@ -4225,4 +4158,257 @@ static CM_UINT8 s_2x2_CommNormalNum(void) } return num; +} +/** + * @brief 输入阶段平台跟随数据的2oo2比较 + */ +static void s_2x2_BaseFollow_2oo2Check_Send(void) +{ + CM_UINT32 crc = 0u; + CM_UINT8 mine_buf[8u] = {0}, peer_buf[8u] = {0}; + CM_INT32 ret = 0; + /*- 计算本机跟随数据中协议部分的CRC值 */ + crc = CM_Crc32(g_TxBaseFollow, g_TxBaseFollow_len - BASE_FOLLOW_ALL_LEN); + CM_LongToChar(g_TxBaseFollow_len, mine_buf); + CM_LongToChar(crc, mine_buf + 4u); + ret = SFM_2oo2_Exchange_Currency(mine_buf, 8u, peer_buf, 8u, ENUM_2oo2_INPUT_EX); + /*- 计算对机跟随数据的CRC值 */ + CM_RE_ASSERT(ret == 8, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_19, TSCP_DARK_ASSERT_1); + /*- 比较本机和对机跟随数据的CRC值 */ + if(0 != CM_Memcmp(mine_buf, peer_buf, (CM_SIZE_T)8u)) + { + MSCP_LOG_DATALEN(g_TxBaseFollow, g_TxBaseFollow_len, "PFM_InputProc g_TxBaseFollow_len"); + CM_RE_ASSERT(0, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_19, TSCP_DARK_ASSERT_2); + } + /*- 比较成功,填入CRC后发送 */ + if(g_TxBaseFollow_len <= (sizeof(g_TxBaseFollow) - 4u)) + { + (void)CM_Memcpy(g_TxBaseFollow + g_TxBaseFollow_len, sizeof(g_TxBaseFollow) - g_TxBaseFollow_len - 4u, mine_buf + 4, 4u); + g_TxBaseFollow_len += 4u; + if(s_2x2_Ctrl.LocalState == ENUM_2x2_MASTER) + { + SFM_2x2_Send(g_TxBaseFollow, (CM_UINT32)g_TxBaseFollow_len, ENUM_2x2_MSG_BASE_FOLLOW); + } + } + +} +/** + * @brief 周期末阶段,备系接收主系应用跟随CRC后的比较逻辑 + */ +static void s_2x2_AppFollow_SyncCheck(void) +{ + CM_UINT32 mine_crc = 0u, partner_crc1 = 0u, partner_crc2 = 0u; + static CM_UINT32 error_tolerate = 1u; + mine_crc = CM_LongFromChar(g_TxAppFollow); + partner_crc1 = CM_LongFromChar(g_RxAppFollowCrc); + partner_crc2 = CM_LongFromChar(g_RxAppFollowCrc + 4u); + + /* 主系双CPU的CRC不一致 */ + if(partner_crc1 != partner_crc2) + { + /* 备系本机与主系其中一个CRC一致 容忍*/ + if(mine_crc == partner_crc1 || mine_crc == partner_crc2) + { + if(error_tolerate++ >= 1u) + { + MSCP_LOG_MSG("MASTER APPFOLLOW CRC ERROR OVER TOLERATE %d\n", error_tolerate); + s_2x2_Ctrl.AppFollowCmpFlag = 1u; + } + else + { + s_2x2_Ctrl.AppFollowCmpFlag = 0u; + MSCP_LOG_MSG("MASTER APPFOLLOW CRC ERROR TOLERATE %d\n", error_tolerate); + } + } + /* 备系本机与主系都不一致 比较失败宕机*/ + else + { + MSCP_LOG_MSG("APPFOLLOW CRC cmp is fail 1\n"); + s_2x2_Ctrl.AppFollowCmpFlag = 1u; + CM_RE_ASSERT(0, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_21, TSCP_DARK_ASSERT_1); + } + } + /* 主系双CPU的CRC一致 但与备系本机不一致 比较失败*/ + else if(mine_crc != partner_crc1) + { + s_2x2_Ctrl.AppFollowCmpFlag = 1u; + MSCP_LOG_MSG("APPFOLLOW CRC cmp is fail 2\n"); + } + /* 主系双CPU的CRC一致 且与备系本机一致 比较成功*/ + else + { + MSCP_LOG_MSG("APPFOLLOW CRC cmp is OK\n"); + s_2x2_Ctrl.AppFollowCmpFlag = 0u; + error_tolerate = 0u; + } + + if(1u == s_2x2_Ctrl.AppFollowCmpFlag) + { + /* 比较失败则设置容忍次数大于0(可能本周期备系校验错误降为离线,但下周期主系失效,导致备系进入容忍分支,认为校验成功又升备) */ + error_tolerate = ((error_tolerate >= 1u) ? error_tolerate : 1u); + MSCP_LOG_DATALEN(g_TxAppFollow + 8, g_TxAppFollow_len, "PFM_AppFollow_SyncCheck g_TxAppFollow"); + } +} +/** + * @brief 输出阶段,备系接收主系输出数据CRC后的比较逻辑 + */ +static void s_2x2_Output_SyncCheck(IN const CM_UINT8 *CheckBuf, CM_INT32 CheckLen) +{ + CM_UINT32 i = 0u; + CM_INT32 ret = -1, ret_p1p2 = -1, ret_m1p1 = -1, ret_m1p2 = -1; /* 记录对系双CRC比较、本机和对系cpu1、本机和对系cpu2比较结果 */ + CM_UINT32 singleCheckLen = CheckLen / 2u; /* checkbuf记录了两个CPU的校验信息,长度的一半为单个CPU校验数据长度 */ + static CM_UINT32 error_tolerate = 1u; + /*- 入参检查 */ + CM_ASSERT(NULL != CheckBuf, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_20, TSCP_DARK_ASSERT_1); + /* 接收的校验数据长度校验 */ + CM_RE_ASSERT(CheckLen == s_2x2_Ctrl.RxCheckLen, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_20, TSCP_DARK_ASSERT_2); + /* 比较接收的主系校验帧中,主系的两个CPU的CRC,记录结果ret_p1p2 */ + ret_p1p2 = CM_Memcmp((const void*)s_2x2_Ctrl.RxCheckFrame, (const void*)&s_2x2_Ctrl.RxCheckFrame[singleCheckLen], (CM_SIZE_T)singleCheckLen); + /* 比较备系本机与主系某一个CPU的CRC,记录结果ret_m1p1 */ + ret_m1p1 = CM_Memcmp((const void*)CheckBuf, (const void*)&s_2x2_Ctrl.RxCheckFrame[0], (CM_SIZE_T)singleCheckLen); + /* 比较备系本机与主系另一个CPU的CRC,记录结果ret_m1p2 */ + ret_m1p2 = CM_Memcmp((const void*)CheckBuf, (const void*)&s_2x2_Ctrl.RxCheckFrame[singleCheckLen], (CM_SIZE_T)singleCheckLen); + /* 对系(主系)发送的双CPU的CRC不一致 */ + if(0 != ret_p1p2) + { + /* 备系本机与主系其中一个CRC一致 容忍*/ + if(0 == ret_m1p1 || 0 == ret_m1p2) + { + if(error_tolerate++ >= 1u) + { + MSCP_LOG_MSG("MASTER OUTPUT CRC ERROR OVER TOLERATE %d\n", error_tolerate); + s_2x2_Ctrl.OutPutCheckFailFlag = 1u; + } + else + { + s_2x2_Ctrl.OutPutCheckFailFlag = 0u; + s_2x2_Ctrl.LastCheckOKCount = SFM_2x2_GetSysCount(); + MSCP_LOG_MSG("MASTER OUTPUT CRC ERROR TOLERATE %d\n", error_tolerate); + } + } + /* 备系本机与主系都不一致 比较失败*/ + else + { + MSCP_LOG_MSG("OUTPUT CRC cmp is fail 1\n"); + s_2x2_Ctrl.OutPutCheckFailFlag = 1u; + } + } + /* 对系(主系)发送的双CPU的CRC一致,比较失败 */ + else if(0 != ret_m1p1) + { + MSCP_LOG_MSG("OUTPUT CRC cmp is fail 2\n"); + s_2x2_Ctrl.OutPutCheckFailFlag = 1u; + for(i = 0u;i < singleCheckLen;i++) + { + if(CheckBuf[i] == s_2x2_Ctrl.RxCheckFrame[i]) + { + + } + else + { + /*- 跳出 */ + break; + } + } + /*记录暗文日志*/ + (void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_2X2_OUT_CHECK_FAIL,3u, + sizeof(CM_UINT8),s_2x2_Ctrl.OutPutCheckFailFlag, + sizeof(CM_UINT32),i, + sizeof(CM_UINT32),s_2x2_Ctrl.RxCheckSysCyc); + } + /* 主系双CPU的CRC一致 且与备系本机一致 比较成功*/ + else + { + MSCP_LOG_MSG("OUTPUT CRC cmp is OK\n"); + /*- 更新输出比较状态 */ + s_2x2_Ctrl.LastCheckOKCount = SFM_2x2_GetSysCount(); + s_2x2_Ctrl.OutPutCheckFailFlag = 0u; + error_tolerate = 0u; + } + /* 备系比较失败宕机*/ + if(1u == s_2x2_Ctrl.OutPutCheckFailFlag) + { + /* 比较失败则设置容忍次数大于0(可能本周期备系校验错误降为离线,但下周期主系失效,导致备系进入容忍分支,认为校验成功又升备) */ + error_tolerate = ((error_tolerate >= 1u) ? error_tolerate : 1u); + /* 打印比较不一致的通道数据 */ + for (i = 1; i <= g_2x2oo2_data_num; i++) + { + if ((CM_UINT32)CM_TRUE == g_2x2oo2_tx[g_2x2oo2_base][i].b_2x2_Enable) + { + ret = CM_Memcmp(CheckBuf + 4 + (i - 1) * 8, s_2x2_Ctrl.RxCheckFrame + 4 + (i - 1) * 8, 8); + if(ret != 0) + { + MSCP_LOG_MSG("2x2 output compare err, INDEX = %d, len = %d\n", i, (CM_SIZE_T)g_2x2oo2_tx[g_2x2oo2_base][i].buf_len); + MSCP_LOG_BIN(g_2x2oo2_tx[g_2x2oo2_base][i].p_buf, (CM_SIZE_T)g_2x2oo2_tx[g_2x2oo2_base][i].buf_len); + } + } + else + { + /*二取标志未使能*/ + } + } + if(ENUM_2x2_SLAVE == s_2x2_Ctrl.LocalState) + { + CM_RE_ASSERT(0, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_20, TSCP_DARK_ASSERT_3); + } + } +} +/** + * @brief 输入阶段,非主系进行相关CRC校验后跟随 + */ +static void s_2x2_BaseFollow_Sync(void) +{ + CM_UINT32 len_prtcl = 0u; /* 协议跟随数据长度 */ + CM_UINT32 len_sfprtcl = 0u; /* 协议跟随数据长度 */ + CM_UINT32 len_pfm = 0u; /* 平台跟随数据长度 */ + CM_UINT32 calcCrc = 0u, rxCrc = 0u, txCrc = 0u; /* CRC相关变量 */ + CM_UINT32 offset = 0u; /* 解包用offset*/ + /*- 适配层协议数据跟随*/ + g_RxBaseFollow_len -= 4;/*去除CRC的长度*/ + calcCrc = CM_Crc32(g_RxBaseFollow, (CM_UINT32)g_RxBaseFollow_len - BASE_FOLLOW_ALL_LEN); + offset = (CM_UINT32)g_RxBaseFollow_len; + rxCrc = CM_LongFromChar(&g_RxBaseFollow[offset]); + offset = (CM_UINT32)g_TxBaseFollow_len - 4u; + txCrc = CM_LongFromChar(&g_TxBaseFollow[offset]); + if((ENUM_2x2_SLAVE == s_2x2_Ctrl.LocalState) && (txCrc != rxCrc)) + { + /* 备系自己产生的平台跟随数据与主系不一致,做日志记录 */ + MSCP_LOG_MSG("2x2 BaseFollow CRC Err,TxCrc = %d,RxCrc = %d,Time:%d us\r\n", txCrc,rxCrc,NOW_USED_TIME); + } + /*- 比较收到的跟随数据与发送的跟随数据*/ + if(calcCrc == rxCrc) + { + offset = 0u; + len_prtcl = CM_LongFromChar((void*)&g_RxBaseFollow[offset]); + offset += 4u; + CM_RE_ASSERT(len_prtcl <= ((CM_UINT32)g_RxBaseFollow_len - 4u), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_22, TSCP_DARK_ASSERT_1); + SFM_SetPrtclFollowData((void*)&g_RxBaseFollow[offset]); + offset += len_prtcl; + + /*- sfp协议数据跟随*/ + len_sfprtcl = CM_LongFromChar((void*)&g_RxBaseFollow[offset]); + offset += 4u; + CM_RE_ASSERT(len_prtcl + len_sfprtcl <= ((CM_UINT32)g_RxBaseFollow_len - 8u), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_22, TSCP_DARK_ASSERT_2); + SFM_SetSfpPrtclFollowData(len_sfprtcl, (void*)&g_RxBaseFollow[offset]); + offset += len_sfprtcl; + + /*- 平台数据跟随*/ + len_pfm = CM_LongFromChar((void*)&g_RxBaseFollow[offset]); + offset += 4u; + CM_RE_ASSERT(len_pfm == ((CM_UINT32)g_RxBaseFollow_len - len_prtcl - len_sfprtcl - 12u), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_22, TSCP_DARK_ASSERT_3); + CM_RE_ASSERT(len_pfm == BASE_FOLLOW_DATA_LEN, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_22, TSCP_DARK_ASSERT_4); + } + /*此处使用临时周期号接收,在周期末同步*/ + offset = (CM_UINT32)g_RxBaseFollow_len - BASE_FOLLOW_ALL_LEN; + offset += 4u; + s_2x2_Ctrl.SysCycSync = CM_LongFromChar(&g_RxBaseFollow[offset]); /* parasoft-suppress BD-PB-CHECKRET "此处无需检查CM_LongFromChar()的返回值" */ + offset += 4u; + SFM_SetTxSn(CM_LongFromChar(&g_RxBaseFollow[offset])); + offset += 4u; + s_2x2_Ctrl.AreaCycSync = CM_LongFromChar(&g_RxBaseFollow[offset]); + offset += 4u; + s_2x2_Ctrl.TimeSyncFlag_Area = g_RxBaseFollow[offset]; + offset += 1u; + s_2x2_Ctrl.AreaTimeOffset = (CM_INT64)CM_64FromChar(&g_RxBaseFollow[offset]); + offset += 8u; } \ No newline at end of file