随机失效,心跳发送时机,重启tracelogger,已修改

This commit is contained in:
lh
2026-07-06 17:38:07 +08:00
parent b42b3a5edd
commit fe9a6dd9f7
5 changed files with 404 additions and 114 deletions
+50
View File
@@ -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]
+2
View File
@@ -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)
+55 -16
View File
@@ -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);
}
}
+10 -3
View File
@@ -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);
+287 -95
View File
@@ -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]));
}