From fe9a6dd9f72d70513004c4ead2c2a7521d2c450c Mon Sep 17 00:00:00 2001 From: lh <3191213465@qq.com> Date: Mon, 6 Jul 2026 17:38:07 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9A=8F=E6=9C=BA=E5=A4=B1=E6=95=88=EF=BC=8C?= =?UTF-8?q?=E5=BF=83=E8=B7=B3=E5=8F=91=E9=80=81=E6=97=B6=E6=9C=BA=EF=BC=8C?= =?UTF-8?q?=E9=87=8D=E5=90=AFtracelogger=EF=BC=8C=E5=B7=B2=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TSCP/src/MSCP/CFM/CFM_Net.c | 50 ++++ TSCP/src/MSCP/MSCP_main.c | 2 + TSCP/src/MSCP/PFM/PFM_InputOutput.c | 71 ++++-- TSCP/src/MSCP/PFM/PFM_Log.c | 13 +- TSCP/src/MSCP/SFM/SFM_2x2.c | 382 +++++++++++++++++++++------- 5 files changed, 404 insertions(+), 114 deletions(-) diff --git a/TSCP/src/MSCP/CFM/CFM_Net.c b/TSCP/src/MSCP/CFM/CFM_Net.c index 4384978..484259c 100644 --- a/TSCP/src/MSCP/CFM/CFM_Net.c +++ b/TSCP/src/MSCP/CFM/CFM_Net.c @@ -57,6 +57,18 @@ /*日志攒包发送 攒包大小*/ #define LOG_MAX (5120u) +/* 心跳在周期结束前30ms执行发送 */ +#define CFM_HEART_WAITE (30u) + +/* 心跳发送线程控制结构体 */ +typedef struct +{ + CM_SEM_T m_Start; /* 心跳线程开始信号量 */ + CM_SEM_T m_Stop; /* 心跳线程结束信号量 */ +} STRU_CFM_HEART_CTRL_T; + +static STRU_CFM_HEART_CTRL_T s_CFM_HeartCtrl; + /** 接收线程控制 */ typedef struct { @@ -322,6 +334,8 @@ static CM_THREAD_FUNC_T t_TimeThread(IN CM_Thread_Arg_Struct_T *arg); static CM_THREAD_FUNC_T t_RemoteUpdateThread(IN CM_Thread_Arg_Struct_T *arg); static CM_THREAD_FUNC_T t_ClearArpThread(void); +/* 单独的心跳发送线程 */ +static CM_THREAD_FUNC_T t_OutNetHeartSendThread(IN CM_Thread_Arg_Struct_T* arg); /*********************************2取相关*****************************************/ /** * @brief 2oo2相关网络通信初始化 @@ -2250,6 +2264,13 @@ static void s_NetInit_Outnet(void) rtCheck = CM_Thread_Create((CM_THREAD_T *)NULL, (CM_THREAD_FUNC_T)t_ClearArpThread, "Clear_Arp", 0, CM_TASK_PRIORITY_94, NULL); CM_RE_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_13); + rt = CM_Sem_Init(&s_CFM_HeartCtrl.m_Start); + CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_14); + rt = CM_Sem_Init(&s_CFM_HeartCtrl.m_Stop); + CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_15); + rtCheck = CM_Thread_Create((CM_THREAD_T*) NULL, (CM_THREAD_FUNC_T) t_OutNetHeartSendThread,"heart_send", 0, CM_TASK_PRIORITY_82, (CM_Thread_Arg_Struct_T*)&s_CFM_HeartCtrl); + CM_ASSERT(CM_TRUE == rtCheck, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_16); + CM_Sleep(100u); /* 延时等待线程启动 */ } @@ -4125,7 +4146,36 @@ void CFM_AssertRecved(void) assertMsgNum = CM_MQ_Get_Msg_Num(&s_CFM_Rx2oo2_Assert.MsgQ); CM_ASSERT((0u == assertMsgNum), NET_MODE, DARK_FAULT_CODE_FUN_ORDER_41, TSCP_DARK_ASSERT_1); } +/** + * @brief 发送心跳线程的启动信号量,需要在平台周期开始时发送 + */ +void CFM_Heart_Thread_PostStart(void) +{ + (void)CM_Sem_Post(s_CFM_HeartCtrl.m_Start); +} +/* 单独的心跳发送线程 */ +static CM_THREAD_FUNC_T t_OutNetHeartSendThread(IN CM_Thread_Arg_Struct_T* arg) +{ + STRU_CFM_HEART_CTRL_T *pCtrl = (STRU_CFM_HEART_CTRL_T*)arg; + CM_UINT32 cyc_time = g_PFM_Cfg.CYC_TIME; + ENUM_2x2_STATE_T state_2x2 = ENUM_2x2_SHUTDOWN; +#if QNX + void* pmask = NULL; + /*- 本线程锁定在 A53 core 1 */ + pmask = (void*)(0x01u|0x02u); + (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask); +#endif + while(1) + { + CM_Sem_Wait(pCtrl->m_Start); + state_2x2 = SFM_2x2_GetLocal2x2State(); + CM_Sleep(cyc_time - CFM_HEART_WAITE); + /*- 发送主线程热备状态的外网心跳*/ + (void)CFM_TxOutnetHeart(state_2x2); + } + return NULL; +} /* MAC层:14字节 dst MAC [6] src MAC [6] type [2] diff --git a/TSCP/src/MSCP/MSCP_main.c b/TSCP/src/MSCP/MSCP_main.c index 7dd876b..e2dab8f 100644 --- a/TSCP/src/MSCP/MSCP_main.c +++ b/TSCP/src/MSCP/MSCP_main.c @@ -456,6 +456,8 @@ static CM_THREAD_FUNC_T MSCP_CycBase(void) DFM_Drv_CycLog(); /*TODO 发送2x状态起始信号量*/ SFM_2x2_Thread_PostStart(); + /* 发送心跳线程起始信号量 */ + CFM_Heart_Thread_PostStart(); PFM_CFC_Check(24); /*- @alias 2oo2周期校时 */ if (0x55u == g_PFM_Cfg.M_2oo2_Enable) diff --git a/TSCP/src/MSCP/PFM/PFM_InputOutput.c b/TSCP/src/MSCP/PFM/PFM_InputOutput.c index aadef15..74d9ddd 100644 --- a/TSCP/src/MSCP/PFM/PFM_InputOutput.c +++ b/TSCP/src/MSCP/PFM/PFM_InputOutput.c @@ -85,6 +85,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同步 */ @@ -489,8 +494,6 @@ void PFM_InputProc(void) } PFM_CFC_Check(30); - /*- 外网心跳数据发送前组包*/ - (void)CFM_TxOutnetHeart(localstate); PFM_CFC_Check(31); /*预留*/ /*************************本地输入数据2oo2交换和比较*************************/ MSCP_LOG_MSG("timecurr 1 Input Recv = %lld us\n", NOW_USED_TIME); @@ -670,18 +673,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 { @@ -794,14 +787,15 @@ 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严格比较特征信息 */ CM_RE_ASSERT(8 == len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_1); - if (0 == CM_Memcmp(mybuf, peerbuf, (CM_SIZE_T)8)) + if(0 == CM_Memcmp(mybuf, peerbuf, (CM_SIZE_T)8)) { /*- 无处理 */ + CM_Memcpy(&g_TxAppFollow[4u], 4u, &peerbuf[4u], 4u); } else { @@ -964,6 +958,7 @@ static CM_INT32 s_2x2OutputCheckFrame_Pack(OUT CM_UINT8 *buf, IN CM_UINT32 BufSi CM_UINT32 len = 0u; /* 输出跟随报文长度 */ CM_UINT32 crc = 0u; /* 输出跟随报文CRC */ CM_UINT32 sysCyc = SFM_2x2_GetSysCount(); /* 系统周期号 */ + CM_UINT32 peerLen = 0u; /* 邻机输出校验报文长度 */ /*- 入参检查*/ CM_ASSERT(((4 + (g_2x2oo2_data_num * 8)) <= (CM_INT32)BufSize) && (NULL != buf), IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_1); @@ -977,6 +972,7 @@ static CM_INT32 s_2x2OutputCheckFrame_Pack(OUT CM_UINT8 *buf, IN CM_UINT32 BufSi { len = (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][ch].buf_len; crc = CM_Crc32(g_2x2oo2_tx[g_2x2oo2_base][ch].p_buf, len); + MSCP_LOG_MSG("ch = %d, len = %d\n", ch, len); CM_LongToChar(len, &buf[i]); i += 4; CM_LongToChar(crc, &buf[i]); @@ -988,6 +984,10 @@ static CM_INT32 s_2x2OutputCheckFrame_Pack(OUT CM_UINT8 *buf, IN CM_UINT32 BufSi } } + peerLen = SFM_2oo2_Exchange_Currency(buf, i, &buf[i], BufSize - i, ENUM_2oo2_OUTPUT_EX); + CM_RE_ASSERT(peerLen == i, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_18, TSCP_DARK_ASSERT_1); + i += peerLen; + /*- 返回输出校验报文长度 */ return i; } @@ -1827,3 +1827,42 @@ void PFM_GetRciTempBuf(OUT CM_UINT16 *RedBuf, OUT CM_UINT16 *BlueBuf) MSCP_LOG_MSG("RED or BLUE Buf is NULL\n"); } } +/** + * @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}; + CM_UINT32 offset = 0u; /* 用于日志打印时,判断通道*/ + /*- 2oo2交换输出校验帧 */ + CM_ASSERT(NULL != check_2oo2_Buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_20, 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_20, 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) + { + offset = (CM_UINT32)(i - 1) * 8 + 4u; + ret = CM_Memcmp(&check_2oo2_Buf[offset], &buf_peer[offset], 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_20, TSCP_DARK_ASSERT_3); + } +} diff --git a/TSCP/src/MSCP/PFM/PFM_Log.c b/TSCP/src/MSCP/PFM/PFM_Log.c index aada3cf..a0d2320 100644 --- a/TSCP/src/MSCP/PFM/PFM_Log.c +++ b/TSCP/src/MSCP/PFM/PFM_Log.c @@ -355,6 +355,7 @@ void MSCP_ASSERT(unsigned int x, unsigned int MaintenanceFlag, unsigned short Mo /*- 安全关断*/ DFM_saftyOff(); + /* 启动跟踪录制 */ MSCP_ASSERT_TraceLog(); /*- 设置LED指示灯*/ if(ENUM_INIT_DRV <= PFM_LOG_GET_INIT_STAGE()) @@ -379,12 +380,14 @@ void MSCP_ASSERT(unsigned int x, unsigned int MaintenanceFlag, unsigned short Mo { CFM_LogCiphertextSend(); } + + /*- 等待日志队列全部发送*/ LogQisEmpty = CFM_LogQ_isEmpty(); while (ENUM_CM_FALSE == LogQisEmpty) { CFM_LogCiphertextSend(); + CM_Sleep(5u); LogQisEmpty = CFM_LogQ_isEmpty(); - CM_Sleep(2u); } /*- 退出运营故障码*/ @@ -503,17 +506,22 @@ void MSCP_REBOOT_ASSERT(unsigned int x, unsigned int MaintenanceFlag,unsigned sh { CFM_LogCiphertextSend(); } + /*- 等待日志队列全部发送*/ LogQisEmpty = CFM_LogQ_isEmpty(); while (ENUM_CM_FALSE == LogQisEmpty) { CFM_LogCiphertextSend(); + CM_Sleep(5u); LogQisEmpty = CFM_LogQ_isEmpty(); - CM_Sleep(2u); } + + /* 启动跟踪录制 */ + MSCP_ASSERT_TraceLog(); /*- 是否执行重启命令*/ if(AutoReboot_Flag == 0x55u) { (void)printf("See You Later!!!\n"); + CM_Sleep(2000u); /* 等待tracelogger记录完成 */ (void)system("shutdown"); /*- 休眠等待重启 */ CM_Sleep(CM_UINT32_MAX); @@ -522,7 +530,6 @@ void MSCP_REBOOT_ASSERT(unsigned int x, unsigned int MaintenanceFlag,unsigned sh { (void)printf("Please check err!!!\n"); } - MSCP_ASSERT_TraceLog(); /*- 设置故障模式*/ PFM_SetBoardState(ENUM_BOARDSTATE_DEFAULT); diff --git a/TSCP/src/MSCP/SFM/SFM_2x2.c b/TSCP/src/MSCP/SFM/SFM_2x2.c index 3c34d10..d15844e 100644 --- a/TSCP/src/MSCP/SFM/SFM_2x2.c +++ b/TSCP/src/MSCP/SFM/SFM_2x2.c @@ -32,6 +32,9 @@ #include "PFM_SelfCheck.h" #include "stdarg.h" +#define BASE_FOLLOW_DATA_LEN (8u) /*平台跟随数据长度*/ +#define BASE_FOLLOW_ALL_LEN (8u+4u) /*平台跟随数据总长度*/ + /*通信中断时间和同步超时时间可以相同,此时优先执行通信中断切系*/ CM_INT32 g_2x2oo2_base = 0; /**< 2x2oo2双缓冲区的平台索引 */ @@ -65,7 +68,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]; /**< 发送的应用跟随数据报文 */ @@ -96,6 +99,22 @@ static CM_BOOL s_State_2x2_Analysis(OUT STRU_2X2_STATE_CTRL_T *p_partner_state,C /*2x状态同步*/ static ENUM_CM_RETURN s_State_2x2Sync(OUT STRU_2X2_STATE_CTRL_T *p_partner_state); static void s_State_Transition(void); +/** + * @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); /** * 统一置切系标志 @@ -636,7 +655,6 @@ static void s_State_Transition(void) /*- 变量初始化 */ CM_UINT8 boardID = 0u; /* 板卡ID */ static CM_UINT32 dropCount = 0u; - CM_UINT32 comstate = 0u; /* 四线通信状态,有三线正常即为ok*/ ENUM_CM_RETURN Flag_Sick_Down = ENUM_CM_FALSE; /* TODO:如果自己健康度不足以升主 */ ENUM_2x2_STATE_T TempState = ENUM_2x2_SHUTDOWN; /*临时状态*/ @@ -939,7 +957,6 @@ static void s_State_Transition(void) (ENUM_CM_FALSE == MSCP_Get_2X_Com_State(&s_2x2_state_Ctrl.MineUartOKCount[0],0u)) && (ENUM_CM_FALSE == MSCP_Get_2X_Com_State(&s_2x2_state_Ctrl.PeerUartOKCount[0],0u))) { - /*在完全中断前,有三线通信正常则允许切系*/ if( /*与当前周期差3-5认为正常,超过阈值认为不同时断线,通信故障*/ (MSCP_Get_2X_DisCom_Count(&s_2x2_state_Ctrl.MineComOKCount[0],0u) <= MSCP_2X2_SYNC_TIMEOUT_CYC) && (MSCP_Get_2X_DisCom_Count(&s_2x2_state_Ctrl.PeerComOKCount[0],0u) <= MSCP_2X2_SYNC_TIMEOUT_CYC) && @@ -1905,7 +1922,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); } @@ -1972,7 +1989,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); } @@ -2160,18 +2177,12 @@ void SFM_2x2_InputProc(void) STRU_2X2_CTRL_T peerCtrl; /* 邻机热备状态 */ CM_INT32 ret = 0; /* 临时变量 */ CM_UINT32 sysCyc = SFM_2x2_GetSysCount(); /* 系统周期号 */ - CM_UINT32 len_prtcl = 0u; /* 协议跟随数据长度 */ - CM_UINT32 len_sfprtcl = 0u; /* 协议跟随数据长度 */ - CM_UINT32 len_pfm = 0u; /* 平台跟随数据长度 */ 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); @@ -2180,18 +2191,15 @@ void SFM_2x2_InputProc(void) 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) - 12u), SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_9);/*输出缓冲至少空闲8字节*/ - CM_LongToChar(8u, g_TxBaseFollow + g_TxBaseFollow_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(BASE_FOLLOW_DATA_LEN, g_TxBaseFollow + g_TxBaseFollow_len); CM_LongToChar(sysCyc, g_TxBaseFollow + g_TxBaseFollow_len + 4u); CM_LongToChar(SFM_GetTxSn(), g_TxBaseFollow + g_TxBaseFollow_len + 8u); g_TxBaseFollow_len += 12u; - /*- 发送 */ - SFM_2x2_Send(g_TxBaseFollow, (CM_UINT32)g_TxBaseFollow_len, ENUM_2x2_MSG_BASE_FOLLOW); - } - else + /* 2取比较后,若为主系执行发送*/ + if(0x55u == g_PFM_Cfg.M_2oo2_Enable) { - /*- 无处理 */ + s_2x2_BaseFollow_2oo2Check_Send(); } MSCP_LOG_MSG("timecurr 3.1 Input 2x2Send = %lld us\n", NOW_USED_TIME); /*########################2x2对系数据接收########################*/ @@ -2276,25 +2284,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))/*通过数据长度判断是否有新数据*/ { - /*- 适配层协议数据跟随*/ - 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 == 8u, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_5); - /*此处使用临时周期号接收,在周期末同步*/ - s_2x2_Ctrl.SysCycSync = CM_LongFromChar(g_RxBaseFollow + 12u + len_prtcl + len_sfprtcl); /* parasoft-suppress BD-PB-CHECKRET "此处无需检查CM_LongFromChar()的返回值" */ - SFM_SetTxSn(CM_LongFromChar(g_RxBaseFollow + 12u + len_prtcl + len_sfprtcl + 4u)); + s_2x2_BaseFollow_Sync(); /*- 本周期是否跟随成功 */ /*- 记录本次跟随时间 */ @@ -2362,6 +2354,8 @@ void SFM_2x2_OutputProc(IN const CM_UINT8 *CheckBuf, CM_INT32 CheckLen) { /*- 发送输出校验帧*/ SFM_2x2_Send(CheckBuf, (CM_UINT32)CheckLen, ENUM_2x2_MSG_OUTCHECK); + ret = CM_Memcmp(CheckBuf, CheckBuf + CheckLen / 2, CheckLen / 2); + CM_RE_ASSERT(0 == ret, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_3); } else { @@ -2439,47 +2433,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 { @@ -2617,12 +2571,14 @@ 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); + cmp_ret = CM_Memcmp(&g_TxAppFollow[0], &g_TxAppFollow[4], 4u); + CM_RE_ASSERT(0 == cmp_ret, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_3); 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); + 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(); @@ -2632,19 +2588,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 { @@ -2846,8 +2790,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 @@ -3394,3 +3339,250 @@ static void s_2x2_CloseSwitchFlag(void) s_2x2_state_Ctrl.ctrSwitchFlag = 0u; s_2x2_state_Ctrl.aidSwitchFlag = 0u; } +/** + * @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[0]); + CM_LongToChar(crc, &mine_buf[4]); + 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_20, 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_20, 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[0]); + partner_crc1 = CM_LongFromChar(&g_RxAppFollowCrc[0]); + partner_crc2 = CM_LongFromChar(&g_RxAppFollowCrc[4]); + + /* 主系双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_22, 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_UINT32 offset = 0u; /* 用于日志打印时,判断通道*/ + /*- 入参检查 */ + CM_ASSERT(NULL != CheckBuf, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_21, TSCP_DARK_ASSERT_1); + /* 接收的校验数据长度校验 */ + CM_RE_ASSERT(CheckLen == s_2x2_Ctrl.RxCheckLen, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_21, TSCP_DARK_ASSERT_2); + /* 比较接收的主系校验帧中,主系的两个CPU的CRC,记录结果ret_p1p2 */ + ret_p1p2 = CM_Memcmp((const void*)&s_2x2_Ctrl.RxCheckFrame[0], (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); + if(ENUM_2x2_SLAVE == s_2x2_Ctrl.LocalState) + { + /* 打印比较不一致的通道数据 */ + for (i = 1; i <= g_2x2oo2_data_num; i++) + { + if ((CM_UINT32)CM_TRUE == g_2x2oo2_tx[g_2x2oo2_base][i].b_2x2_Enable) + { + offset = (CM_UINT32)(i - 1) * 8 + 4u; + ret = CM_Memcmp(CheckBuf + offset, &s_2x2_Ctrl.RxCheckFrame[offset], 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 + { + /*二取标志未使能*/ + } + } + CM_RE_ASSERT(0, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_21, 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_23, 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_23, 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_23, TSCP_DARK_ASSERT_3); + CM_RE_ASSERT(len_pfm == BASE_FOLLOW_DATA_LEN, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_23, TSCP_DARK_ASSERT_4); + } + /*此处使用临时周期号接收,在周期末同步*/ + offset = (CM_UINT32)g_RxBaseFollow_len - BASE_FOLLOW_DATA_LEN; + s_2x2_Ctrl.SysCycSync = CM_LongFromChar((void*)&g_RxBaseFollow[offset]); /* parasoft-suppress BD-PB-CHECKRET "此处无需检查CM_LongFromChar()的返回值" */ + offset += 4u; + SFM_SetTxSn(CM_LongFromChar((void*)&g_RxBaseFollow[offset])); +}