/*
 * SFM_Area.c
 *
 *  Created on: 2025年8月28日
 *      Author: hisun
 */
#include "SFM_Area.h"
#include "SFM_2x2.h"
#include "SFM_2oo2.h"
#include "SFM_package.h"
#include "CM_CRC32.h"
#include "CM_Time.h"
#include "CM_Memory.h"
#include "DFM_Time.h"
#include "stdarg.h"
#include "SFM_Prtcl.h"

/*区域周期号*/
CM_UINT32 g_MSCP_AreaCount;

/* 开关状态第一次检测需等待3s(约10个周期)*/
#define RC_WAIT         (100)     /* RC等待CI启动*/
#define CI_WAIT         (15)     /* CI等待检测RC脉冲*/


#define SFM_LOG_MSG_AREA(fmt, ...) (SFM_AREA_LOG_MSG(FILENAME(__FILE__),(CM_INT32)__LINE__,(fmt), ##__VA_ARGS__))
/**
* @brief 平台记录格式化字符串日志
* @param filename 文件路径
* @param func 函数名
* @param line 行号
* @param fmt 格式化字符串
*/
static void SFM_AREA_LOG_MSG(IN const CM_CHAR *filename, IN CM_INT32 line, IN const CM_CHAR* fmt, ...);
static CM_UINT8 g_Area_State_Cache[100];
static CM_INT32 g_Area_State_Cache_Len = 0;
/*应用数据*/
static CM_UINT8 g_Area_App_DATA[SFM_AREA_DATA_BUFF_SIZE];             /* 本机收到的数据 */
static CM_INT32 g_Area_App_Data_Len = 0;                    
static CM_UINT8 g_2oo2_Area_App_DATA[SFM_AREA_DATA_BUFF_SIZE];        /* 2取交互收到的数据*/
static CM_INT32 g_2oo2_Area_App_Data_Len = 0;  

static CM_UINT8 g_2x2_Area_App_DATA[SFM_AREA_DATA_BUFF_SIZE];         /* 2x交互收到的数据*/
static CM_INT32 g_2x2_Area_App_Data_Len = 0;  
static CM_UINT8 g_2x2oo2_Area_App_DATA[SFM_AREA_DATA_BUFF_SIZE];      /* 2x后2取收到的数据*/
static CM_INT32 g_2x2oo2_Area_App_Data_Len = 0;  

static CM_UINT8* p_Area_App_Master_DATA;       /* 指向四个缓冲区中的来自主系的最新buf*/
static CM_INT32 g_Area_App_Master_Len;           /* 指向的缓冲区的长度*/
static CM_UINT8* p_Area_App_Slave_DATA;       /* 指向四个缓冲区中的来自备系的最新buf*/
static CM_INT32 g_Area_App_Slave_Len;           /* 指向的缓冲区的长度*/

#define AREA_2X_RECV_WAIT   (40u)               /* 2x接收等待时间*/

static CM_UINT8 s_area_Cache[NET_UDP_BUF_SIZE];  /**< 区域通信缓冲区 */
/* 区域线程控制*/
static STRU_AREA_THREAD_T s_Area_Thread_Ctrl;
/* 区域状态控制*/
static STRU_AREA_STATE_CTRL_T s_area_state_Ctrl;
/* 区域数据接收*/
static void s_Area_Recv(void);
/*获取最新的区域数据buf*/
static CM_INT32 s_Get_LatestAreaBuf(IN CM_UINT8* data1, IN CM_INT32 len1,IN CM_UINT8* data2, IN CM_INT32 len2,OUT CM_UINT8** dataOut);
/* CI状态机*/
static void s_Area_CI_Transition(void);
/* RC状态机*/
static void s_Area_RC_Transition(void);
/* 区域状态机*/
static void s_Area_State_Transition(void);
/* 从AB两系的脉冲选择有效的脉冲*/
static void s_Area_GetValidPulse(void);
/* 区域协程的2oo2x交互*/
static void s_Area_2oo2x2(void);
/* 根据脉冲状态获取区域状态 状态转换前进行*/
static void s_Area_GetStateFromPulse(void);
/* 主备系接收情况判断*/
static void s_Area_GetMasterData(void);
/**
 * @brief 直接从脉冲状态转换出区域状态
 * */
static ENUM_AREA_STATE_T s_ConvertPulseToState(ENUM_PULSE_TYPE_T pulse);
/**
* @brief 区域接收
* @see :: SFM_2x2_Send
* @see :: s_2x2_SendState
*/
static void s_2x2_Area_Recv(void);
/**
 * @brief 解析2x2数据，更新状态控制结构体，并根据不同类型的数据进行不同处理
 */
static void s_Parse2x2Data(ENUM_2x2_MSG_T msgType, CM_UINT32 msgCyc, CM_UINT16 framNum, CM_UINT16 framIndex, CM_UINT8* data, CM_INT32 len);
/**
 * @brief 解析区域数据，更新状态控制结构体，并根据不同类型的数据进行不同处理
 */
static void s_ParseAreaData(ENUM_AREA_MSG_T msgType, CM_UINT32 msgCyc, CM_UINT16 framNum, CM_UINT16 framIndex, CM_UINT8* data, CM_INT32 len);
/**
 * 区域通信处理线程
 */
static CM_THREAD_FUNC_T t_AreaThread(void);
/**
 * 发送区域数据时，先2取计算双CRC后发送
 */
static void s_2oo2Before_AreaSend(CM_UINT8 *buf, CM_INT32 len, CM_UINT32 bufsize, ENUM_AREA_MSG_T msg_typ);
/**
 * 初始化
 */
void SFM_Area_Init(void)
{
    CM_BOOL rt = CM_FALSE;
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    ENUM_PULSE_TYPE_T pulse;    /* 接收脉冲回读结果*/
    CM_UINT32 i = 0u;   /* 循环变量*/
    if(0x00u != g_PFM_Cfg.M_Area_Enable)
    {
        MSCP_LOG_MSG("Area Init Start\n");
        g_MSCP_AreaCount = 0u;
        /* 初始化信号量*/
        ret = CM_Sem_Init(&s_Area_Thread_Ctrl.m_Start);
        CM_ASSERT(ENUM_CM_TRUE == ret, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);
        ret = CM_Sem_Init(&s_Area_Thread_Ctrl.m_Stop);
        CM_ASSERT(ENUM_CM_TRUE == ret, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_2);
        ret = CM_Mutex_Init(&s_Area_Thread_Ctrl.mutex);
        CM_ASSERT(ENUM_CM_TRUE == ret, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_3);
        ret = CM_MQ_Init((CM_MQ_Struct_T*)&s_Area_Thread_Ctrl.LogMsgQ, (CM_UINT16)CFM_INNET_LOG_SIZE, (CM_UINT16)(CFM_INNET_LOG_SIZE));
        CM_ASSERT(ENUM_CM_TRUE == ret, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_4);

        /* 初始化脉冲回读失败*/
        ret = DFM_Pulse_FeedBack(&pulse);
        CM_ASSERT(ENUM_CM_TRUE == ret, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_5);

        s_area_state_Ctrl.SysCyc = 0u;
        s_area_state_Ctrl.LocalAreaState = ENUM_AREA_UNAVAILABLE;
        s_area_state_Ctrl.AnotherAreaState = ENUM_AREA_UNAVAILABLE;
        s_area_state_Ctrl.LastLocalAreaState = s_area_state_Ctrl.LocalAreaState;
        s_area_state_Ctrl.LastAnotherAreaState = s_area_state_Ctrl.AnotherAreaState;
        s_area_state_Ctrl.Local2x2State = ENUM_2x2_OFFLINE;
        s_area_state_Ctrl.Partner2x2State = ENUM_2x2_SHUTDOWN;
        s_area_state_Ctrl.TimeSyncFlag_2x2 = 0u;
        s_area_state_Ctrl.TimeSyncFlag_Area = 0u;
        s_area_state_Ctrl.RxAreaSysCyc = 0u;
        s_area_state_Ctrl.Rx2x2DataSysCyc = 0u;
        s_area_state_Ctrl.flag_Mf_Ss = 0u;
        s_area_state_Ctrl.pulseA = ENUM_PULSE_ERROR;
        s_area_state_Ctrl.pulseB = ENUM_PULSE_ERROR;
        s_area_state_Ctrl.pulse = ENUM_PULSE_ERROR;
        s_area_state_Ctrl.AnotherBoardID = 1u;
        s_area_state_Ctrl.isAllowed = 1u;
        s_area_state_Ctrl.WaitCounter = 0u;
        s_area_state_Ctrl.AreaRecved = 0u;
        s_area_state_Ctrl.AreaAppRecved = 0u;
        s_area_state_Ctrl.AllInterrupt = 1u;
        s_area_state_Ctrl.RCFollowFlag = 0u;
        s_area_state_Ctrl.AreaSwitchMode = ENUM_SWITCH_ERROR;
        for(i = 0u; i < sizeof(s_area_state_Ctrl.healthFlag); i++)
        {
            s_area_state_Ctrl.healthFlag[i] = 0u;
        }

        /*-启动区域交互独立线程 */
    	rt = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_AreaThread, "area_state", 0, CM_TASK_PRIORITY_73, NULL);
    	CM_ASSERT(CM_TRUE == rt, SFM_2x2_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_5);
    }
    else
    {
        SFM_LOG_MSG_AREA("Area is not enabled\n");
        s_area_state_Ctrl.LocalAreaState = ENUM_AREA_MASTER;
        s_area_state_Ctrl.AnotherAreaState = ENUM_AREA_UNAVAILABLE;
        s_area_state_Ctrl.LastLocalAreaState = s_area_state_Ctrl.LocalAreaState;
        s_area_state_Ctrl.LastAnotherAreaState = s_area_state_Ctrl.AnotherAreaState;
        s_area_state_Ctrl.flag_Mf_Ss = 0u;
    }
}
/**
 * 发送起始信号量
 */
void SFM_AREA_Thread_PostStart(void)
{
    if(0x00 != g_PFM_Cfg.M_Area_Enable)
    {
        CM_Sem_Post(s_Area_Thread_Ctrl.m_Start);
    }
    else
    {
        /* 无处理 */
    }
}
/**
 * 等待结束信号量
 */
void SFM_AREA_Thread_WaitStop(void)
{
    if(0x00 != g_PFM_Cfg.M_Area_Enable)
    {
        CM_Sem_Wait(s_Area_Thread_Ctrl.m_Stop);
    }
    else
    {
        /* 无处理 */
    }
}
/**
 * 区域通信处理线程
 */
static CM_THREAD_FUNC_T t_AreaThread(void)
{
#if QNX
    void* pmask = NULL;
    /*- 本线程锁定在 A53 core 1|2 */
    pmask = (void*)(0x01u | 0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
#endif
    CM_UINT8 sendBuf[100];
    CM_UINT32 offset = 0u;
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    static CM_UINT32 Slave_sysCyc = 0;
    static CM_UINT32 Master_sysCyc = 0;
    CM_UINT64 delta_Tick = 0u;      /* 区域接收超时时间*/
    CM_INT32 ret = 0;
    CM_UINT32 appLen = 0u;
    if(0xAA == g_PFM_Cfg.M_Area_Enable)
    {
        delta_Tick = g_PFM_Cfg.CYC_TIME - 160u;
    }
    else
    {
        /* CI接收40ms超时退出*/
        delta_Tick = 40u;
    }
    while(1)
    {
        CM_Sem_Wait(s_Area_Thread_Ctrl.m_Start);
        SFM_LOG_MSG_AREA("Area Cyc:%d\n", s_area_state_Ctrl.SysCyc);

        if(0xAA == g_PFM_Cfg.M_Area_Enable)
        {
            /* RC主系发送状态数据*/
            offset = 0u;
            CM_LongToChar(0u, &sendBuf[offset]);    /* 填充应用数据长度*/
            offset += 4u;
            CM_LongToChar(AREA_DATA_STATE_LEN, &sendBuf[offset]);    
            offset += 4u;
            sendBuf[offset] = g_PFM_Cfg.BOARD_ID;
            offset += 1u;
            sendBuf[offset] = s_area_state_Ctrl.LocalAreaState;
            offset += 1u;
            sendBuf[offset] = s_area_state_Ctrl.Local2x2State;
            offset += 1u;
            CM_LongToChar(g_MSCP_AreaCount, &sendBuf[offset]);
            offset += 4u;
            if(ENUM_2x2_MASTER == s_area_state_Ctrl.Local2x2State)
            {
                s_2oo2Before_AreaSend(sendBuf, offset, sizeof(sendBuf), ENUM_AREA_MSG_MASTER);
            }
            else
            {
                s_2oo2Before_AreaSend(sendBuf, offset, sizeof(sendBuf), ENUM_AREA_MSG_SLAVE);
            }
        }
        /*- 延时接收区域数据 */
        CM_Sleep(delta_Tick);
        s_Area_Recv();
        /* 2oo2x交互收到的数据*/
        s_Area_2oo2x2();
        /* 使用主系接收数据*/
        s_Area_GetMasterData();
        SFM_LOG_MSG_AREA("Sync Data Recv %d, rxCyc:%d, cyc:%d\n", s_area_state_Ctrl.AreaRecved, s_area_state_Ctrl.RxAreaSysCyc, s_area_state_Ctrl.SysCyc);
        SFM_LOG_MSG_AREA("flag_Mf_Ss = %d, Master_syscyc=%d, Slave_syscyc=%d, AreaRecved:%d, AnotherAreaState:%d, AnotherBoardID:%d\n", 
                                                                                            s_area_state_Ctrl.flag_Mf_Ss, Master_sysCyc, Slave_sysCyc,
                                                                                            s_area_state_Ctrl.AreaRecved,
                                                                                            s_area_state_Ctrl.AnotherAreaState,
                                                                                            s_area_state_Ctrl.AnotherBoardID);
        CM_Sem_Post(s_Area_Thread_Ctrl.m_Stop);
    }
    return NULL;
}
/**
* @brief 区域发送
* @param Data 发送报文指针
* @param DataLen 发送报文长度
* param msgType 报文类型
* @details
* @see :: s_2x2_Recv
* @see :: SFM_FrameSave
*/
void SFM_AREA_Send(IN const CM_UINT8 *Data, IN CM_UINT32 DataLen, IN ENUM_AREA_MSG_T msgType)
{

    /*- 变量初始化 */
    CM_UINT16 FrameNum = 0u;    /* 帧数 */
    CM_UINT16 FrameIndex = 0u;  /* 帧序号 */
    CM_UINT32 FrameLen = 0u;    /* 帧长度 */
    CM_UINT32 crc = 0u;         /* CRC */
    CM_UINT32 SysCyc = SFM_Area_GetSysCount(); /* 系统周期号 */
    ENUM_CM_RETURN checkRet = ENUM_CM_NULL;
    CM_UINT32 offset = 0u;
    PFM_LOG_SET_STOPTIMER(TSCP_DARK_AREA);
    /*- 入口检查 */
    CM_ASSERT(NULL != Data, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    /*- 计算帧数 */
    FrameNum = (CM_UINT16)(((CM_UINT32)DataLen <= NET_20K_SIZE) ? (1u) : ((((CM_UINT32)DataLen + NET_20K_SIZE) - 1u) / NET_20K_SIZE));
    /*
    2x2通信帧格式：
    4字节 长度（不含自身）
    4字节 周期号
    1字节 类型
    2字节 帧总数
    2字节 帧序号
    n字节 数据
    4字节 CRC（含长度）
    */
    /*- 填充报文头 */
    CM_LongToChar(NET_20K_SIZE + 13u, &s_area_Cache[offset]);        /*长度(暂时填写满帧)*/
    offset += 4u;
    CM_LongToChar(SysCyc, &s_area_Cache[offset]);              /*周期号*/ 
    offset += 4u;
    s_area_Cache[offset] = (CM_UINT8)msgType;                  /*类型*/
    offset += 1u;
    CM_ShortToChar(FrameNum, &s_area_Cache[offset]);           /*帧总数*/
    offset += 2u;
    /* s_area_Cache + 11 */                                /*帧序号(后面填写)*/

    /*- @alias 循环发送完整帧 */
    for (FrameIndex = 1u; FrameIndex < FrameNum; FrameIndex++)
    {
        offset = 11u;
        CM_ShortToChar(FrameIndex, &s_area_Cache[offset]);         /*帧序号*/
        offset += 2u;
        checkRet = CM_Memcpy((void*)(&s_area_Cache[offset]), (CM_SIZE_T)NET_20K_SIZE, (const void*)(Data + ((FrameIndex - 1u)*NET_20K_SIZE)), (CM_SIZE_T)NET_20K_SIZE); /* parasoft-suppress MISRA2004-17_1 MISRA2004-17_4 "指针运算提高代码执行效率" */
        CM_RE_ASSERT(checkRet == ENUM_CM_TRUE, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);
        crc = CM_Crc32(s_area_Cache, NET_20K_SIZE + offset);
        CM_LongToChar(crc, &s_area_Cache[offset + NET_20K_SIZE]); /*CRC*/
        offset += 4u;

        (void)CFM_Area_DataSend(s_area_Cache, (CM_INT32)(offset + NET_20K_SIZE));  /*交给通信层发送*/
    }

    offset = 11u;
    /*- 发送尾帧*/
    CM_ShortToChar(FrameIndex, &s_area_Cache[offset]);         /*帧序号*/
    offset += 2u;
    FrameLen = (CM_UINT32)DataLen - ((FrameIndex - 1u)*NET_20K_SIZE);
    checkRet = CM_Memcpy((void*)(&s_area_Cache[offset]), (CM_SIZE_T)NET_20K_SIZE, (const void*)(Data + ((FrameIndex - 1u)*NET_20K_SIZE)), (CM_SIZE_T)FrameLen); /* parasoft-suppress MISRA2004-17_1 MISRA2004-17_4 "指针运算提高代码执行效率" */
    CM_RE_ASSERT(checkRet == ENUM_CM_TRUE, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_3);
    CM_LongToChar(offset + FrameLen, s_area_Cache);              /*长度*/
    crc = CM_Crc32(s_area_Cache, offset + FrameLen);
    CM_LongToChar(crc, &s_area_Cache[offset + FrameLen]);      /*CRC*/
    offset += 4u;
    (void)CFM_Area_DataSend(s_area_Cache,(CM_INT32)CM_UNSIGNED_INT_EXP(offset + FrameLen));         /*交给通信层发送*/
    PFM_LOG_SET_STOPTIMER(TSCP_DARK_NULL);
}
/**
* @brief 区域接收
* @see :: SFM_2x2_Send
* @see :: s_2x2_SendState
*/
static void s_Area_Recv(void)
{
    /*- 变量初始化 */
    CM_INT32 rxLen = 0;       /* 网络接收长度 */
    CM_UINT32 msgLen = 0u;    /* 报文长度 */
    CM_UINT32 SrcID = 0u;     /* 源ID */
    CM_UINT32 DstID = 0u;     /* 目的ID */
    CM_UINT32 msgCyc = 0u;    /* 报文周期号 */
    CM_UINT32 msgSN = 0u;     /* 报文序列号 */
    CM_UINT16 FrameNum = 0u;  /* 帧数目 */
    CM_UINT16 FrameIndex = 0u;/* 帧序号 */
    CM_UINT32 msgCrc = 0u, msgCrc1 = 0u, msgCrc2 = 0u;    /* 报文CRC */
    CM_UINT32 calcCrc = 0u, calcCrc1 = 0u, calcCrc2 = 0u;   /* 本地计算CRC */
    CM_UINT8 *pData = NULL;   /* 指向帧数据的指针 */
    CM_INT32 DataLen = 0;     /* 帧数据长度 */
    ENUM_AREA_MSG_T type = ENUM_AREA_MSG_ERROR; /* 报文类型 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;          /* 临时变量 */
    CM_UINT32 offset = 0u;
    CM_UINT32 current_time;
    CM_UINT32 time_stamp;
    CM_UINT8* Buff_Area = NULL;
    CM_UINT32* Buff_Len = NULL;
    STRU_FrameCtrl_T* Buff_FrameCtrl = NULL;
    PFM_LOG_SET_STOPTIMER(TSCP_DARK_AREA);
    /*- 以太网循环接收2x2数据 */
    if(CM_TRUE == s_area_state_Ctrl.TimeSyncFlag_Area)
    {
		do
		{
			/*- 从通信层接收2x2报文 */
			rxLen = CFM_Area_DataRecv(s_area_Cache, (CM_UINT32)sizeof(s_area_Cache));
			/*- 收到的报文长度是否大于0 */
			if ((17u + 6u)<= rxLen)
			{
                current_time = (CM_UINT32)(CM_GetTick()/CM_UNSIGNED_MILLION);/*当前时间戳ms*/
                time_stamp = CM_LongFromChar(&s_area_Cache[0]);/*接收时间戳ms*/
                SFM_LOG_MSG_AREA("area current:%u, recv:%u\n", current_time, time_stamp);
                if((current_time - time_stamp) <= MSCP_AREA_OVER_TIME)
                {
                    /*- 解析2x2报文头 */
                    /*
                    2x2通信帧格式：
                    4字节 长度（不含自身）
                    4字节 周期号
                    1字节 类型
                    2字节 帧总数
                    2字节 帧序号
                    n字节 数据
                    4字节 CRC
                    */
                    rxLen -= 6u;
                    offset = 6u;
                    msgLen = CM_LongFromChar(&s_area_Cache[offset]);
                    offset += 4u;
                    SFM_LOG_MSG_AREA("MSGLEN:%d, rxlen:%d\n", msgLen, rxLen);
                    CM_RE_ASSERT((msgLen + 4u) == (CM_UINT32)rxLen, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_3, TSCP_DARK_ASSERT_1);
                    msgCyc = CM_LongFromChar(&s_area_Cache[offset]);
                    offset += 4u;
                    type = (ENUM_AREA_MSG_T)s_area_Cache[offset];
                    offset += 1u;
                    FrameNum = CM_ShortFromChar(&s_area_Cache[offset]);
                    offset += 2u;
                    FrameIndex = CM_ShortFromChar(&s_area_Cache[offset]);
                    offset += 2u;
                    msgCrc = CM_LongFromChar(s_area_Cache + msgLen + 6u);
                    calcCrc = CM_Crc32(s_area_Cache + 6u, msgLen);
                    /*- 校验报文头是否合法 */
                    if ((msgCrc == calcCrc) &&
                        ((msgCyc >= s_area_state_Ctrl.RxAreaSysCyc) || (msgCyc >= s_area_state_Ctrl.SysCyc)))
                    {
                        pData = s_area_Cache + offset;
                        DataLen = (CM_INT32)CM_UNSIGNED_INT_EXP(msgLen - offset + 6);
                        s_ParseAreaData(type, msgCyc, FrameNum, FrameIndex, pData, DataLen);
                    }
                    else
                    {
                        SFM_LOG_MSG_AREA("crc:%d, recvCrc:%d, cyc:%d, rxcyc:%d, syscyc:%d\n", msgCrc, calcCrc, msgCyc, s_area_state_Ctrl.RxAreaSysCyc, s_area_state_Ctrl.SysCyc);
                        /*- 无处理 */
                    }
                }
                else
                {

                }
			}/* end if (0 < rxLen)*/
			else
			{
				/*- 无处理 */
			}
		} while (0 < rxLen);
    }
    else
    {
    	/*时间同步未完成，清空所有2x接收数据*/
        SFM_LOG_MSG_AREA("TimeSyncFlag_Area = %d\n", s_area_state_Ctrl.TimeSyncFlag_Area);
		SFM_AREA_ClearRcvMsgQ();
    }
	PFM_LOG_SET_STOPTIMER(TSCP_DARK_NULL);
}

/**
* @brief 时间同步失败清空消息队列
* @param 无
* @return 无
*/
void SFM_AREA_ClearRcvMsgQ(void)
{
	if(CM_FALSE == s_area_state_Ctrl.TimeSyncFlag_Area)
	{
		/*误差过大，清空2x缓冲区*/
		CFM_NetAreaFlush();
	}
	else
	{
		/*无处理*/
	}
}
/**
* @brief 区域发送
* @param Data 发送报文指针
* @param DataLen 发送报文长度
* param msgType 报文类型
* @details
* @see :: s_2x2_Recv
* @see :: SFM_FrameSave
*/
void SFM_2x2_AREA_Send(IN const CM_UINT8 *Data, IN CM_UINT32 DataLen, IN ENUM_2x2_AREA_MSG_T msgType)
{

    /*- 变量初始化 */
    CM_UINT16 FrameNum = 0u;    /* 帧数 */
    CM_UINT16 FrameIndex = 0u;  /* 帧序号 */
    CM_UINT32 FrameLen = 0u;    /* 帧长度 */
    CM_UINT32 crc = 0u;         /* CRC */
    CM_UINT32 SysCyc = SFM_2x2_GetSysCount(); /* 系统周期号 */
    ENUM_CM_RETURN checkRet = ENUM_CM_NULL;
    CM_UINT32 offset = 0u;
    PFM_LOG_SET_STOPTIMER(TSCP_DARK_AREA);
    /*- 入口检查 */
    CM_ASSERT(NULL != Data, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_1);

    /*- 计算帧数 */
    FrameNum = (CM_UINT16)(((CM_UINT32)DataLen <= NET_20K_SIZE) ? (1u) : ((((CM_UINT32)DataLen + NET_20K_SIZE) - 1u) / NET_20K_SIZE));
    /*
    2x2通信帧格式：
    4字节 长度（不含自身）
    4字节 周期号
    1字节 类型
    2字节 帧总数
    2字节 帧序号
    n字节 数据
    4字节 CRC（含长度）
    */
    /*- 填充报文头 */
    CM_LongToChar(NET_20K_SIZE + 13u, &s_area_Cache[offset]);        /*长度(暂时填写满帧)*/
    offset += 4u;
    CM_LongToChar(SysCyc, &s_area_Cache[offset]);              /*周期号*/ 
    offset += 4u;
    s_area_Cache[offset] = (CM_UINT8)msgType;                  /*类型*/
    offset += 1u;
    CM_ShortToChar(FrameNum, &s_area_Cache[offset]);           /*帧总数*/
    offset += 2u;
    /* s_area_Cache + 11 */                                /*帧序号(后面填写)*/

    /*- @alias 循环发送完整帧 */
    for (FrameIndex = 1u; FrameIndex < FrameNum; FrameIndex++)
    {
        offset = 11u;
        CM_ShortToChar(FrameIndex, &s_area_Cache[offset]);         /*帧序号*/
        offset += 2u;
        checkRet = CM_Memcpy((void*)(&s_area_Cache[offset]), (CM_SIZE_T)NET_20K_SIZE, (const void*)(Data + ((FrameIndex - 1u)*NET_20K_SIZE)), (CM_SIZE_T)NET_20K_SIZE); /* parasoft-suppress MISRA2004-17_1 MISRA2004-17_4 "指针运算提高代码执行效率" */
        CM_RE_ASSERT(checkRet == ENUM_CM_TRUE, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);
        crc = CM_Crc32(s_area_Cache, NET_20K_SIZE + offset);
        CM_LongToChar(crc, &s_area_Cache[offset + NET_20K_SIZE]); /*CRC*/
        offset += 4u;

        (void)CFM_2x2_Area_DataSend(s_area_Cache, (CM_INT32)(offset + NET_20K_SIZE));  /*交给通信层发送*/
    }

    offset = 11u;
    /*- 发送尾帧*/
    CM_ShortToChar(FrameIndex, &s_area_Cache[offset]);         /*帧序号*/
    offset += 2u;
    FrameLen = (CM_UINT32)DataLen - ((FrameIndex - 1u)*NET_20K_SIZE);
    checkRet = CM_Memcpy((void*)(&s_area_Cache[offset]), (CM_SIZE_T)NET_20K_SIZE, (const void*)(Data + ((FrameIndex - 1u)*NET_20K_SIZE)), (CM_SIZE_T)FrameLen); /* parasoft-suppress MISRA2004-17_1 MISRA2004-17_4 "指针运算提高代码执行效率" */
    CM_RE_ASSERT(checkRet == ENUM_CM_TRUE, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_3);
    CM_LongToChar(offset + FrameLen, s_area_Cache);              /*长度*/
    crc = CM_Crc32(s_area_Cache, offset + FrameLen);
    CM_LongToChar(crc, &s_area_Cache[offset + FrameLen]);      /*CRC*/
    offset += 4u;
    (void)CFM_2x2_Area_DataSend(s_area_Cache,(CM_INT32)CM_UNSIGNED_INT_EXP(offset + FrameLen));         /*交给通信层发送*/
    PFM_LOG_SET_STOPTIMER(TSCP_DARK_NULL);
}
/**
* @brief 区域接收
* @see :: SFM_2x2_Send
* @see :: s_2x2_SendState
*/
static void s_2x2_Area_Recv(void)
{
    /*- 变量初始化 */
    CM_INT32 rxLen = 0;       /* 网络接收长度 */
    CM_UINT32 msgLen = 0u;    /* 报文长度 */
    CM_UINT32 SrcID = 0u;     /* 源ID */
    CM_UINT32 DstID = 0u;     /* 目的ID */
    CM_UINT32 msgCyc = 0u;    /* 报文周期号 */
    CM_UINT32 msgSN = 0u;     /* 报文序列号 */
    CM_UINT16 FrameNum = 0u;  /* 帧数目 */
    CM_UINT16 FrameIndex = 0u;/* 帧序号 */
    CM_UINT32 msgCrc = 0u;    /* 报文CRC */
    CM_UINT32 calcCrc = 0u;   /* 本地计算CRC */
    CM_UINT8 *pData = NULL;   /* 指向帧数据的指针 */
    CM_INT32 DataLen = 0;     /* 帧数据长度 */
    ENUM_2x2_MSG_T type = ENUM_2x2_MSG_ERROR; /* 报文类型 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;          /* 临时变量 */
    CM_UINT32 offset = 0u;
    PFM_LOG_SET_STOPTIMER(TSCP_DARK_AREA);
    /*- 以太网循环接收2x2数据 */
    if(CM_TRUE == s_area_state_Ctrl.TimeSyncFlag_2x2)
    {
		do
		{
			/*- 从通信层接收2x2报文 */
			rxLen = CFM_2x2_Area_DataRecv(s_area_Cache, (CM_UINT32)sizeof(s_area_Cache));
			/*- 收到的报文长度是否大于0 */
			if ((17u <= rxLen))
			{
				/*- 解析2x2报文头 */
				/*
				2x2通信帧格式：
				4字节 长度（不含自身）
				4字节 周期号
				1字节 类型
				2字节 帧总数
				2字节 帧序号
				n字节 数据
				4字节 CRC
				*/
                offset = 0u;
				msgLen = CM_LongFromChar(&s_area_Cache[offset]);
                offset += 4u;
				CM_RE_ASSERT((msgLen + 4u) == (CM_UINT32)rxLen, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_7, TSCP_DARK_ASSERT_1);
				msgCyc = CM_LongFromChar(&s_area_Cache[offset]);
                offset += 4u;
				type = (ENUM_AREA_MSG_T)s_area_Cache[offset];
                offset += 1u;
				FrameNum = CM_ShortFromChar(&s_area_Cache[offset]);
                offset += 2u;
				FrameIndex = CM_ShortFromChar(&s_area_Cache[offset]);
                offset += 2u;
				msgCrc = CM_LongFromChar(s_area_Cache + msgLen);
				calcCrc = CM_Crc32(s_area_Cache, msgLen);
				/*- 校验报文头是否合法 */
				if (/* msgCyc*/
				    msgCrc == calcCrc)
				{
					pData = s_area_Cache + offset;
					DataLen = (CM_INT32)CM_UNSIGNED_INT_EXP(msgLen - offset);
                    s_Parse2x2Data(type, msgCyc, FrameNum, FrameIndex, pData, DataLen);
				}
				else
				{
					/*- 无处理 */
				}
			}/* end if (0 < rxLen)*/
			else
			{
				/*- 无处理 */
			}
		} while (0 < rxLen);
    }
    else
    {
    	/*时间同步未完成，清空所有2x接收数据*/
        SFM_LOG_MSG_AREA("2X Time is Not Ok\n");
		SFM_2X2_AREA_ClearRcvMsgQ();
    }
	PFM_LOG_SET_STOPTIMER(TSCP_DARK_NULL);
}
/**
* @brief 时间同步失败清空消息队列
* @param 无
* @return 无
*/
void SFM_2X2_AREA_ClearRcvMsgQ(void)
{
	if(CM_FALSE == s_area_state_Ctrl.TimeSyncFlag_2x2)
	{
		/*误差过大，清空2x缓冲区*/
		CFM_Net2X_Area_Flush();
	}
	else
	{
		/*无处理*/
	}
}
/*获取最新的区域数据buf*/
static CM_INT32 s_Get_LatestAreaBuf(IN CM_UINT8* data1, IN CM_INT32 len1,IN CM_UINT8* data2, IN CM_INT32 len2,OUT CM_UINT8** dataOut)
{
    /**
     * 4字节长度
     * n字节应用数据
     * 4字节长度
     * 1字节板卡ID
     * 1字节区域状态
     * 1字节2x状态
     * 4字节区域周期号
     */
    CM_INT32 dataLen = 0;
    CM_UINT32 statelen1 = 0u, statelen2 = 0u, applen1 = 0u, applen2 = 0u;
    ENUM_2x2_STATE_T state2x2_1 = ENUM_2x2_OFFLINE, state2x2_2 = ENUM_2x2_OFFLINE;
    CM_UINT32 cyc1 = 0u;
    CM_UINT32 cyc2 = 0u;
    if((NULL != data1) && (NULL != data2) && (NULL != dataOut))
    {
        *dataOut = data1; /* 防空指针*/
        if((8 < len1) && (8 < len2))
        {
            applen1 = CM_LongFromChar(data1);
            applen2 = CM_LongFromChar(data2);
            statelen1 = CM_LongFromChar(data1 + applen1 + 4u);
            statelen2 = CM_LongFromChar(data2 + applen2 + 4u);
            SFM_LOG_MSG_AREA("applen1:%d, applen2:%d, statelen1:%d, statelen2:%d\n", applen1, applen2, statelen1, statelen2);
            if((statelen1 != AREA_DATA_STATE_LEN) && (statelen2 != AREA_DATA_STATE_LEN))
            {
                /* 状态段长度错误*/
                dataLen = 0;
            }
            else if((statelen1 == AREA_DATA_STATE_LEN) && (statelen2 == AREA_DATA_STATE_LEN))
            {
                /* 状态段长度均合法*/
                state2x2_1 = (ENUM_2x2_STATE_T)data1[10 + applen1];
                state2x2_2 = (ENUM_2x2_STATE_T)data2[10 + applen2];
                cyc1 = CM_LongFromChar(data1 + 11 + applen1);
                cyc2 = CM_LongFromChar(data2 + 11 + applen2);
                SFM_LOG_MSG_AREA("cyc1:%d, cyc2:%d\n",cyc1, cyc2);
                /* 热备状态不一致，选择主系*/
                if((ENUM_2x2_MASTER == state2x2_1) && (ENUM_2x2_MASTER != state2x2_2))
                {
                    *dataOut = data1;
                    dataLen = len1;
                }
                else if((ENUM_2x2_MASTER != state2x2_1) && (ENUM_2x2_MASTER == state2x2_2))
                {
                    *dataOut = data2;
                    dataLen = len2;
                }
                else if(cyc1 >= cyc2)
                {
                    /* 热备状态一致，根据周期号选择*/
                    *dataOut = data1;
                    dataLen = len1;
                }
                else
                {
                    /* 热备状态一致，根据周期号选择*/
                    *dataOut = data2;
                    dataLen = len2;
                }
            }
            else if(statelen1 == AREA_DATA_STATE_LEN)
            {
                /* 一个状态段长度合法*/
                *dataOut = data1;
                dataLen = len1; 
            }
            else
            {
                *dataOut = data2;
                dataLen = len2; 
            }
        }
        else if(8 < len1)
        {
            *dataOut = data1;
            dataLen = len1; 
        }
        else
        {
            *dataOut = data2;
            dataLen = len2;  
        }
    }
    else
    {

    }

    return dataLen;
}
/**
 * 获取区域数据缓冲区指针
 */
CM_UINT32 SFM_GetAreaData(OUT CM_UINT8** data)
{
    CM_UINT32 len = 0u;
    if(g_Area_App_Master_Len >= AREA_DATA_STATE_LEN + 8u)
    {
        len = g_Area_App_Master_Len - AREA_DATA_STATE_LEN - 4;
    }
    *data = p_Area_App_Master_DATA; 
    return len;
}
/* 区域状态切换*/
void SFM_Area_State_Transition(void)
{
    s_Area_GetStateFromPulse();

    if((ENUM_AREA_MASTER == s_area_state_Ctrl.AnotherAreaState) && (ENUM_AREA_MASTER == s_area_state_Ctrl.LocalAreaState))
    {
        /*双主用防护*/
        if(0xAAu == g_PFM_Cfg.M_Area_Enable)
        {
            /* RC直接宕机*/
            CM_RE_ASSERT(0, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1);
        }
        else
        {

        }
    }
    else
    {
        
    }

    /* 状态转换*/
    if( 0x00u == g_PFM_Cfg.M_Area_Enable)
    {
        /* 区域开关未开启*/
        SFM_LOG_MSG_AREA("Area is not Enabled\n");
    }
    else if(ENUM_AREA_MASTER == s_area_state_Ctrl.AnotherAreaState)
    {
        /* 另一区域主用，不判断开关状态*/
        SFM_LOG_MSG_AREA("mode:Unknown, Local is 0x%x, Transition Start\n", g_PFM_Cfg.M_Area_Enable);
        s_Area_State_Transition();
    }
    else
    {
        /* 另一区域非主用，判断开关状态*/
        switch(s_area_state_Ctrl.AreaSwitchMode)
        {
            case ENUM_SWITCH_RC:
                /* RC挡位*/
                if(0xAAu == g_PFM_Cfg.M_Area_Enable)
                {
                    /* RC */
                    s_area_state_Ctrl.LocalAreaState = ENUM_AREA_MASTER;
                    SFM_LOG_MSG_AREA("mode:RC, Local is 0x%x, State>>>>>>Master\n", g_PFM_Cfg.M_Area_Enable);
                }
                else if(0x55u == g_PFM_Cfg.M_Area_Enable)
                {
                    /* CI */
                    s_area_state_Ctrl.LocalAreaState = ENUM_AREA_UNAVAILABLE;
                    SFM_LOG_MSG_AREA("mode:RC, Local is 0x%x, State>>>>>>Unavailable\n", g_PFM_Cfg.M_Area_Enable);
                }
                else
                {

                }
                break;
            case ENUM_SWITCH_CI:
                /* CI挡位*/
                if(0xAAu == g_PFM_Cfg.M_Area_Enable)
                {
                    /* RC */
                    s_area_state_Ctrl.LocalAreaState = ENUM_AREA_UNAVAILABLE;
                    SFM_LOG_MSG_AREA("mode:CI, Local is 0x%x, State>>>>>>Unavailable\n", g_PFM_Cfg.M_Area_Enable);
                }
                else if(0x55u == g_PFM_Cfg.M_Area_Enable)
                {
                    /* CI */
                    s_area_state_Ctrl.LocalAreaState = ENUM_AREA_MASTER;
                    SFM_LOG_MSG_AREA("mode:CI, Local is 0x%x, State>>>>>>Master\n", g_PFM_Cfg.M_Area_Enable);
                }
                else
                {

                }
                break;
            case ENUM_SWITCH_AUTO:
                /* 自动挡位*/
                SFM_LOG_MSG_AREA("mode:AUTO, Local is 0x%x, Transition Start\n", g_PFM_Cfg.M_Area_Enable);
                s_Area_State_Transition();
                break;
            default:
                /* 开关获取模式获取失败，无处理 */
                SFM_LOG_MSG_AREA("Area Switch is Error\n");
                break;
        }
    }
}
/* 区域状态机*/
static void s_Area_State_Transition(void)
{
    ENUM_AREA_STATE_T tempState;    
    SFM_LOG_MSG_AREA("pulse is %d\n", s_area_state_Ctrl.pulse);        
    if(0x55u == g_PFM_Cfg.M_Area_Enable)
    {
        s_Area_CI_Transition();
    }
    else
    {
        s_Area_RC_Transition();
    }
}
/**
* @brief 平台记录格式化字符串日志
* @param filename 文件路径
* @param func 函数名
* @param line 行号
* @param fmt 格式化字符串
*/
static void SFM_AREA_LOG_MSG(IN const CM_CHAR *filename, IN CM_INT32 line, IN const CM_CHAR* fmt, ...)
{
    /*- 变量初始化 */
    va_list argList;
    CM_CHAR msgBuf[1024];
    CM_INT32 headLen = 0;
	CM_INT32 msgLen = 0;
	if(NULL == fmt)
	{
		/* 无处理 */
	}
	else
	{
		/*- 记录文件名、函数名、行号 */
		headLen = snprintf(msgBuf, sizeof(msgBuf), "ps:%s:%d:", filename, line);
		va_start(argList, (fmt));
		/*- 记录日志内容 */
		msgLen += vsnprintf(msgBuf + headLen, sizeof(msgBuf) - (CM_SIZE_T)headLen, fmt, argList);
		va_end(argList);
#ifdef WIN32
		Bootprintf("%s", msgBuf + headLen);
#endif
	    // printf("%s", msgBuf + headLen);
	    /*- 输出日志信息 */
	    CM_MQ_Write((CM_MQ_Struct_T*)&s_Area_Thread_Ctrl.LogMsgQ, (CM_UINT8*)msgBuf, (CM_UINT16)headLen + msgLen);
	}
}
/*日志转换*/
void SFM_AREA_LOG_Transition(void)
{
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	CM_UINT8 buf[1024] = {0};
	CM_UINT16 len = 1024;
	while(1)
	{
		len = 1024;
		rt = CM_MQ_Read(&s_Area_Thread_Ctrl.LogMsgQ, buf, (CM_UINT16*)&len);
		if(ENUM_CM_TRUE == rt)
		{
		    /*- 输出日志信息 */
		    (void)CFM_BaseLog_Send((CM_UINT8*)buf, len);
		}
		else
		{
			/*无处理*/
			break;
		}
	}
}
/*协程状态控制接口*/
STRU_AREA_STATE_CTRL_T* SFM_Area_BackPointer_Ctrl(void)
{
	/**< 主线程2x2控制 */
	return &s_area_state_Ctrl;
}
/* 根据状态设置脉冲*/
void SFM_SetPulse(ENUM_AREA_STATE_T state)
{
    ENUM_PULSE_TYPE_T pulseA, pulseB;
    if(0x00u != g_PFM_Cfg.M_Area_Enable)
    {
        switch(state)
        {
            case ENUM_AREA_MASTER:
                DFM_Pulse_Set(ENUM_PULSE_MASTER);
                break;
            case ENUM_AREA_SLAVE:
                DFM_Pulse_Set(ENUM_PULSE_SLAVE);
                break;
            case ENUM_AREA_UNAVAILABLE:
                DFM_Pulse_Set(ENUM_PULSE_UNAVAILABLE);
                break;
            default:
                DFM_Pulse_Set(ENUM_PULSE_ERROR);
                break;
        }
        /* 此处读取操作用于清空脉冲计数，不关注返回值*/
        (void)DFM_Pulse_FeedBack(&pulseA);
        (void)DFM_Pulse_Get(&pulseA, &pulseB);
    }
}
/* 根据状态设置主备用灯*/
void SFM_SetAreaLed(ENUM_AREA_STATE_T state)
{
    if(0x00u != g_PFM_Cfg.M_Area_Enable)
    {
        switch(state)
        {
            case ENUM_AREA_MASTER:
                DFM_ledAREA(0x01u);
                break;
            case ENUM_AREA_SLAVE:
                DFM_ledAREA(0x02u);
                break;
            case ENUM_AREA_UNAVAILABLE:
                DFM_ledAREA(0x00u);
                break;
            default:
                DFM_ledAREA(0x03u);
                break;
        }
    }
}
/* 获取接收到的周期号*/
CM_UINT32 SFM_Area_GetRxSysCount()
{
    return s_area_state_Ctrl.RxAreaSysCyc;
}
/* 获取区域周期号*/
CM_UINT32 SFM_Area_GetSysCount(void)
{
    return g_MSCP_AreaCount;
}
/* 从AB两系的脉冲选择有效的脉冲
*  必须在状态转换(SFM_Area_State_Transition)前进行
*/
static void s_Area_GetValidPulse(void)
{
    s_area_state_Ctrl.AllInterrupt = 0u; 
    /* 更新亚健康标志*/
    s_area_state_Ctrl.healthFlag[2] = s_area_state_Ctrl.healthFlag[1];
    s_area_state_Ctrl.healthFlag[1] = s_area_state_Ctrl.healthFlag[0];
    s_area_state_Ctrl.healthFlag[0] = 0u;

    if((ENUM_PULSE_ERROR == s_area_state_Ctrl.pulseA) && (ENUM_PULSE_ERROR == s_area_state_Ctrl.pulseB))
    {
        /* 检测双系脉冲均无效*/
        s_area_state_Ctrl.pulse = ENUM_PULSE_ERROR;
        if((0u == s_area_state_Ctrl.AreaRecved) && (1u == s_area_state_Ctrl.TimeSyncFlag_Area))
        {
            /* 脉冲无效，且UDP未收到，认为另一区域两系宕机*/
            s_area_state_Ctrl.RxAreaSysCyc = 0u;        /* 清空接收周期号，避免另一区域再起后不接收*/
            s_area_state_Ctrl.AllInterrupt = 1u; 
            s_area_state_Ctrl.healthFlag[0] = 1u;       /* 通信全中断时，认为健康*/
            SFM_LOG_MSG_AREA("Area All Interruptted!!!!!!!\n");
        }
        else
        {

        }
    }
    else if(1u == s_area_state_Ctrl.AreaRecved)
    {
        /* 根据协程接收到的板卡号选择脉冲*/
        /* 本周期收到区域数据，根据板卡号选择脉冲*/
        if(2u == s_area_state_Ctrl.AnotherBoardID)
        {
            s_area_state_Ctrl.pulse = s_area_state_Ctrl.pulseB;
        }
        else
        {
            s_area_state_Ctrl.pulse = s_area_state_Ctrl.pulseA;
        }

        if(s_area_state_Ctrl.AnotherAreaState == s_ConvertPulseToState(s_area_state_Ctrl.pulse))
        {
            /* 脉冲与UDP接收状态一致，健康状态*/
            s_area_state_Ctrl.healthFlag[0] = 1u;
        }
        else
        {
            SFM_LOG_MSG_AREA("Area Pulse State Unhealthy!!!!!!\n");
        }
    }
    else
    {
        /* 未收到UDP则选择更高优先级脉冲*/
        if(s_area_state_Ctrl.pulseA >= s_area_state_Ctrl.pulseB)
        {
            s_area_state_Ctrl.pulse = s_area_state_Ctrl.pulseA;
        }
        else
        {
            s_area_state_Ctrl.pulse = s_area_state_Ctrl.pulseB;
        }
    }
}
/* 区域协程的2oo2x交互*/
static void s_Area_2oo2x2(void)
{
    /* 清空缓冲区长度*/
    g_Area_App_Master_Len = 0;
    g_Area_App_Slave_Len = 0;
    g_2oo2_Area_App_Data_Len = 0u;
    g_2x2_Area_App_Data_Len = 0u;
    g_2x2oo2_Area_App_Data_Len = 0u;

    if(g_Area_App_Data_Len < AREA_DATA_STATE_LEN + 8)
    {
        /* 未收到另一区域主系数据*/
        (void)CM_Memcpy(g_Area_App_DATA, sizeof(g_Area_App_DATA), g_Area_State_Cache, g_Area_State_Cache_Len);
        SFM_LOG_MSG_AREA("Area Recv Another Master Fail\n");
        g_Area_App_Data_Len = g_Area_State_Cache_Len;
    }
    /* 2取交互*/
    g_2oo2_Area_App_Data_Len = SFM_2oo2_Currency_Area(g_Area_App_DATA, g_Area_App_Data_Len, g_2oo2_Area_App_DATA, sizeof(g_2oo2_Area_App_DATA));
    SFM_LOG_MSG_AREA("Area 2x2 Send Data 111, len=%d-%d\n", g_Area_App_Data_Len, g_2oo2_Area_App_Data_Len);
    g_Area_App_Master_Len = s_Get_LatestAreaBuf(g_Area_App_DATA, g_Area_App_Data_Len, g_2oo2_Area_App_DATA, g_2oo2_Area_App_Data_Len, &p_Area_App_Master_DATA);
    
    SFM_2x2_AREA_Send(p_Area_App_Master_DATA, g_Area_App_Master_Len, ENUM_2x2_AREA_MSG_DATA);
    SFM_LOG_MSG_AREA("Area 2x2 Send Data, len=%d\n", g_Area_App_Master_Len);

    /* 2x接收*/
    CM_Sleep(AREA_2X_RECV_WAIT);
    s_2x2_Area_Recv();
    SFM_LOG_MSG_AREA("Area 2x2 Data Recv, len=%d\n", g_2x2_Area_App_Data_Len);
    /* 2取2x接收的数据*/
    g_2x2oo2_Area_App_Data_Len = SFM_2oo2_Currency_Area(g_2x2_Area_App_DATA, g_2x2_Area_App_Data_Len, g_2x2oo2_Area_App_DATA, sizeof(g_2x2oo2_Area_App_DATA));
    SFM_LOG_MSG_AREA("Area 2oo2 After 2x2 Data Recv, len=%d\n", g_2x2oo2_Area_App_Data_Len);

    if(ENUM_2x2_MASTER == s_area_state_Ctrl.Local2x2State)
    {
        /* 主系只使用自己的数据*/
        g_Area_App_Master_Len = s_Get_LatestAreaBuf(g_Area_App_DATA, g_Area_App_Data_Len, g_2oo2_Area_App_DATA, g_2oo2_Area_App_Data_Len, &p_Area_App_Master_DATA);
        g_Area_App_Slave_Len = s_Get_LatestAreaBuf(g_2x2_Area_App_DATA, g_2x2_Area_App_Data_Len, g_2x2oo2_Area_App_DATA, g_2x2oo2_Area_App_Data_Len, &p_Area_App_Slave_DATA);
    }
    else
    {
        /* 非主系使用主系同步数据*/
        g_Area_App_Master_Len = s_Get_LatestAreaBuf(g_2x2_Area_App_DATA, g_2x2_Area_App_Data_Len, g_2x2oo2_Area_App_DATA, g_2x2oo2_Area_App_Data_Len, &p_Area_App_Master_DATA);
        g_Area_App_Slave_Len = s_Get_LatestAreaBuf(g_Area_App_DATA, g_Area_App_Data_Len, g_2oo2_Area_App_DATA, g_2oo2_Area_App_Data_Len, &p_Area_App_Slave_DATA);
    }
    g_Area_App_Data_Len = 0;
    g_Area_State_Cache_Len = 0;
    SFM_LOG_MSG_AREA("Master Data Len:%d, Slave Data Len:%d\n",g_Area_App_Master_Len ,g_Area_App_Slave_Len );
}
/* 根据脉冲状态获取区域状态 状态转换前进行*/
static void s_Area_GetStateFromPulse(void)
{
    /* 获取有效脉冲*/
    static CM_UINT32 notSameCnt = 0u;
    ENUM_AREA_STATE_T state = ENUM_AREA_UNAVAILABLE;
    s_Area_GetValidPulse();
    if(1u == s_area_state_Ctrl.AreaRecved)
    {
        state = s_ConvertPulseToState(s_area_state_Ctrl.pulse);
        if(state != s_area_state_Ctrl.AnotherAreaState)
        {
            notSameCnt++;
            SFM_LOG_MSG_AREA("Area Pulse State Not Same Pulse is %d State is %d\n", state, s_area_state_Ctrl.AnotherAreaState);
        }
        else
        {
            
        }
    }
    else if(0u == s_area_state_Ctrl.AreaRecved)
    {
        /* 本周期未收到udp通信,则使用脉冲状态作为对区域状态*/
        s_area_state_Ctrl.AnotherAreaState = s_ConvertPulseToState(s_area_state_Ctrl.pulse);
    }
    else
    {

    }
    // printf("Area Pulse State Not Same Cnt = %d", notSameCnt);
    SFM_LOG_MSG_AREA("Area Pulse State Not Same Cnt = %d\n", notSameCnt);
}
/**
 * @brief 周期末区域同步
 * @param CI_Buf CI待发送区域数据
 * @param buf_len CI_Buf待发送数据长度
 * @param buf_size CI_Buf缓冲区最大容量
 * */
void SFM_Area_EndProc(CM_UINT8* CI_Buf, CM_INT32 buf_len, CM_UINT32 buf_size)
{
    CM_UINT8* p_areaData = NULL;	/*区域数据指针*/
    CM_UINT32 areaDataLen = 0; 		/*区域数据长度*/
    CM_UINT8 sendBuf[100] = {0u};
    CM_UINT32 offset = 0u;  /* 组包使用的offset*/
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    ENUM_AREA_STATE_T state_area = SFM_Area_GetLocalAreaState();
    ENUM_2x2_STATE_T state_2x2  = SFM_2x2_GetLocal2x2State();
    /* 区域数据设置*/
    MSCP_LOG_MSG("Local Area is %d\n", g_PFM_Cfg.M_Area_Enable);
    SFM_AREA_Thread_WaitStop();
    if(0xAAu == g_PFM_Cfg.M_Area_Enable)
    {
        /* 仅RC设置*/
        areaDataLen = SFM_GetAreaData(&p_areaData);
        if(NULL != RC_API_FollowUp && 4u < areaDataLen)
        {
            s_area_state_Ctrl.RCFollowFlag = RC_API_FollowUp(p_areaData, areaDataLen);
            MSCP_LOG_MSG("RC:Set App Data, alllen=%d, len=%d, time:%llums\n", areaDataLen, CM_LongFromChar(p_areaData), NOW_USED_TIME / 1000u);
        }
        else
        {
            MSCP_LOG_MSG("RC:Set App Func Fail, len = %d, time:%llums\n", areaDataLen, NOW_USED_TIME / 1000u);
        }
    }
    else if(0x55u == g_PFM_Cfg.M_Area_Enable)
    {
		/* CI*/
        if(buf_len <= (CM_INT32)buf_size - AREA_DATA_STATE_LEN - 12)
        {
            offset = buf_len;
            CM_LongToChar(AREA_DATA_STATE_LEN, &CI_Buf[offset]);
            offset += 4u;
            CI_Buf[offset] = g_PFM_Cfg.BOARD_ID;
            offset += 1u;
            CI_Buf[offset] = state_area;
            offset += 1u;
            CI_Buf[offset] = state_2x2;
            offset += 1u;
            CM_LongToChar(g_MSCP_AreaCount, &CI_Buf[offset]);
            offset += 4u;
            if((state_area == ENUM_AREA_MASTER) && (state_2x2 == ENUM_2x2_MASTER))
            {
                /* 主用主系发送应用同步数据与状态*/
                s_2oo2Before_AreaSend(CI_Buf, offset, buf_size, ENUM_AREA_MSG_MASTER);
                MSCP_LOG_MSG("CI:Send App Data and State, len = %d\n", offset + 8);
            }
            else
            {
                /* 非主用主发送状态数据*/
                offset -= buf_len;
                ret = CM_Memcpy(sendBuf + 4, sizeof(sendBuf), CI_Buf + buf_len, offset);
                CM_ASSERT(ENUM_CM_TRUE == ret, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_1);
                CM_LongToChar(0u, sendBuf);
                offset += 4u;
                s_2oo2Before_AreaSend(sendBuf, offset, sizeof(sendBuf), ENUM_AREA_MSG_SLAVE);
                MSCP_LOG_MSG("CI:Send State\n");
            }
        }
        else
        {
            /* 无处理*/
            MSCP_LOG_MSG("CI:Send App Data too Long\n");
        }
        MSCP_LOG_MSG("CI Recv Send Used:%llums\n", NOW_USED_TIME / 1000u);
    }
	else
	{
		/* 区域开关未开，无处理*/
	}
}
/**
 * @brief 直接从脉冲状态转换出区域状态
 * */
static ENUM_AREA_STATE_T s_ConvertPulseToState(ENUM_PULSE_TYPE_T pulse)
{
    ENUM_AREA_STATE_T state = ENUM_AREA_UNAVAILABLE;
    switch (pulse)
    {
    case ENUM_PULSE_MASTER:
        state = ENUM_AREA_MASTER;
        break;
    case ENUM_PULSE_SLAVE:
        state = ENUM_AREA_SLAVE;
        break;
    default:
        state = ENUM_AREA_UNAVAILABLE;
        break;
    }

    return state;
}
/**
 * 发送区域数据时，先2取计算双CRC后发送
 */
static void s_2oo2Before_AreaSend(CM_UINT8 *buf, CM_INT32 len, CM_UINT32 bufsize, ENUM_AREA_MSG_T msg_type)
{
    CM_UINT8 mybuf[12] = { 0u };  /* 本机2oo2缓冲区 */
    CM_UINT8 peerbuf[12] = { 0u };/* 邻机2oo2缓冲区 */
    CM_UINT32 crc = 0u, crc1 = 0u, crc2 = 0u;   /* crc值 */
    CM_INT32 ret = 0u;

    crc = CM_Crc32(buf, len);
    if(1u == g_PFM_Cfg.CPU_ID)
    {
        crc1 = CM_Crc32_1(buf, len);
        CM_LongToChar(crc1, mybuf + 8);
    }
    else
    {
        crc2 = CM_Crc32_2(buf, len);
        CM_LongToChar(crc2, mybuf + 8);
    }
    
    CM_LongToChar(len, mybuf);
    CM_LongToChar(crc, mybuf + 4);
    ret = SFM_2oo2_Currency_Area(mybuf, 12u, peerbuf, 12u);
    /*- 2oo2严格比较特征信息 */
    CM_RE_ASSERT(12 == ret, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_6);
    ret = CM_Memcmp(mybuf, peerbuf, (CM_SIZE_T)8);
    CM_RE_ASSERT(0 == ret, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_7);
    if(1u == g_PFM_Cfg.CPU_ID)
    {
        crc2 = CM_LongFromChar(peerbuf + 8);       
    }
    else
    {
        crc1 = CM_LongFromChar(peerbuf + 8);
    }
    if(bufsize >= len + 8)
    {
        CM_LongToChar(crc1, &buf[len]);
        len += 4;
        CM_LongToChar(crc2, &buf[len]);
        len += 4;
        SFM_AREA_Send(buf, len, msg_type);
    }
    else
    {
        SFM_LOG_MSG_AREA("Area Send Buf too long!!!\n");
    }

}
/* 主备系接收情况判断*/
static void s_Area_GetMasterData(void)
{
    CM_UINT32 appLen = 0u;
    static CM_UINT32 Slave_sysCyc = 0;
    static CM_UINT32 Master_sysCyc = 0;
    appLen = 0u;
    if(g_Area_App_Slave_Len >= AREA_DATA_STATE_LEN + 8)
    {
        appLen = CM_LongFromChar(&p_Area_App_Slave_DATA[0]);
        Slave_sysCyc = CM_LongFromChar(&p_Area_App_Slave_DATA[appLen + 11u]);
    }
    else
    {

    }
    /*使用主系的数据*/
    s_area_state_Ctrl.AreaRecved = 0u;
    s_area_state_Ctrl.AreaAppRecved = 0u;
    if(g_Area_App_Master_Len >= AREA_DATA_STATE_LEN + 8)
    {
        appLen = CM_LongFromChar(&p_Area_App_Master_DATA[0]);
        Master_sysCyc = CM_LongFromChar(&p_Area_App_Master_DATA[appLen + 11u]);
        s_area_state_Ctrl.AreaRecved = 1u;
        if(appLen > 0u)
        {
            /* 接收到区域应用数据*/
            s_area_state_Ctrl.AreaAppRecved = 1u;
        }
        /* 更新接收周期号为主系的接收周期号*/
        s_area_state_Ctrl.RxAreaSysCyc = Master_sysCyc;
        s_area_state_Ctrl.AnotherBoardID = p_Area_App_Master_DATA[appLen + 8u];
        s_area_state_Ctrl.AnotherAreaState = p_Area_App_Master_DATA[appLen + 9u];
    }
    else
    {
        /* 主系没收到数据*/
        s_area_state_Ctrl.AnotherAreaState = ENUM_AREA_UNAVAILABLE;
    }

    /* 备系收到最新区域数据，主系未收到，设置标志位*/
    if(Slave_sysCyc > Master_sysCyc && Slave_sysCyc >= s_area_state_Ctrl.SysCyc && CM_TRUE == s_area_state_Ctrl.TimeSyncFlag_2x2)
    {
        s_area_state_Ctrl.flag_Mf_Ss = 1u;
    }
    else
    {
        s_area_state_Ctrl.flag_Mf_Ss = 0u;
    }      
}
/**
 * @brief 同步周期号
 */
void SFM_Area_UpdateCYC(void)
{
    ENUM_AREA_STATE_T state_area = SFM_Area_GetLocalAreaState();
	if((ENUM_AREA_MASTER != state_area) && (1u == s_area_state_Ctrl.AreaRecved))
	{
		/* 非主用更新周期号*/
		MSCP_LOG_MSG("Area Set CYC:%d->%d\n", g_MSCP_AreaCount, s_area_state_Ctrl.RxAreaSysCyc);
		g_MSCP_AreaCount = s_area_state_Ctrl.RxAreaSysCyc;
		
	}
    else
    {

    }
}
/* CI状态机*/
static void s_Area_CI_Transition(void)
{
    switch(s_area_state_Ctrl.LocalAreaState)
    {
        case ENUM_AREA_UNAVAILABLE:
            
            if((s_area_state_Ctrl.WaitCounter >= CI_WAIT) && (1u == s_area_state_Ctrl.isAllowed))
            {
                /* RC也为不可用，则CI升主用*/
                s_area_state_Ctrl.LocalAreaState = ENUM_AREA_MASTER;
                SFM_LOG_MSG_AREA("CI:Unavailable>>>>>>Master\n");
            }
            else
            {
                SFM_LOG_MSG_AREA("CI:Unavailable>>>>>>Master, WC:%d, IA:%d\n", s_area_state_Ctrl.WaitCounter, s_area_state_Ctrl.isAllowed);
            }
        
            break;
        case ENUM_AREA_SLAVE:
            /* CI无备用状态，永远无法进入该分支*/
            break;
        case ENUM_AREA_MASTER:
            /* 双主用在此函数前防护*/
            SFM_LOG_MSG_AREA("0x%x:MASTER>>>>>>>>>MASTER\n", g_PFM_Cfg.M_Area_Enable);
            break;
        default:
            /*无处理*/
            break;
    }
}
/* RC状态机*/
static void s_Area_RC_Transition(void)
{
    switch(s_area_state_Ctrl.LocalAreaState)
    {
        case ENUM_AREA_UNAVAILABLE:
            /*RC*/
            if((s_area_state_Ctrl.RxAreaSysCyc == s_area_state_Ctrl.SysCyc) && 
                (1u == s_area_state_Ctrl.AreaAppRecved) && 
                (ENUM_AREA_MASTER == s_area_state_Ctrl.AnotherAreaState) && 
                (1u == s_area_state_Ctrl.RCFollowFlag)) 
            {
                /* RC收到CI主用的应用同步数据，且完成时间同步，RC升备*/
                s_area_state_Ctrl.LocalAreaState = ENUM_AREA_SLAVE;
                SFM_LOG_MSG_AREA("RC:Unavailable>>>>>>Slave(sync success)\n");
            }
            else if((s_area_state_Ctrl.WaitCounter >= RC_WAIT) && (1u == s_area_state_Ctrl.isAllowed))
            {
                /*CI未启动，RC升主*/
                s_area_state_Ctrl.LocalAreaState = ENUM_AREA_MASTER;
                SFM_LOG_MSG_AREA("RC:Unavailable>>>>>>Master(CI is not started)\n");
            }
            else
            {
                /*无处理，维持不可用*/
                SFM_LOG_MSG_AREA("RC:Unavailable>>>>>>Slave(TS_A=%d, RxCYC=%d, CYC=%d, WC:%d, IA:%d, AAR:%d, AAS:%d, RF:%d)\n", 
                                s_area_state_Ctrl.TimeSyncFlag_Area, s_area_state_Ctrl.RxAreaSysCyc, s_area_state_Ctrl.SysCyc, 
                                s_area_state_Ctrl.WaitCounter, s_area_state_Ctrl.isAllowed, s_area_state_Ctrl.AreaAppRecved, 
                                s_area_state_Ctrl.AnotherAreaState, s_area_state_Ctrl.RCFollowFlag);
            }
            
            break;
        case ENUM_AREA_SLAVE:
            /*RC*/
            if((1u == s_area_state_Ctrl.AreaAppRecved) && (1u == s_area_state_Ctrl.RCFollowFlag))
            {
                SFM_LOG_MSG_AREA("RC:SLAVE>>>>>>>>>SLAVE\n");
            }
            else if((1u == s_area_state_Ctrl.AllInterrupt) && ((s_area_state_Ctrl.healthFlag[1] + s_area_state_Ctrl.healthFlag[2]) >= 1u))
            {
                /*CI故障，降为不可用，则RC升为主用（上周期不为亚健康状态）*/
                s_area_state_Ctrl.LocalAreaState = ENUM_AREA_MASTER;
                SFM_LOG_MSG_AREA("RC:SLAVE>>>>>>>>>Master(CI is unavailable), pulse:%d, CYC:%d, RXCYC:%d\n", s_area_state_Ctrl.pulse, s_area_state_Ctrl.SysCyc, s_area_state_Ctrl.RxAreaSysCyc);
            }
            else
            {
                /*RC未收到CI主用的应用同步数据(脉冲正常)*/
                s_area_state_Ctrl.LocalAreaState = ENUM_AREA_UNAVAILABLE;
                SFM_LOG_MSG_AREA("RC:SLAVE>>>>>>>>>Unavailable(sync data recv failed), pulse:%d, CYC:%d, RXCYC:%d, healthy:%d, last health:%d, last last health:%d, RF:%d\n", 
                                s_area_state_Ctrl.pulse, s_area_state_Ctrl.SysCyc, s_area_state_Ctrl.RxAreaSysCyc, 
                                s_area_state_Ctrl.healthFlag[0], s_area_state_Ctrl.healthFlag[1], s_area_state_Ctrl.healthFlag[2], s_area_state_Ctrl.RCFollowFlag);
            }
            break;
        case ENUM_AREA_MASTER:
            /* 双主用在此函数前防护*/
            SFM_LOG_MSG_AREA("0x%x:MASTER>>>>>>>>>MASTER\n", g_PFM_Cfg.M_Area_Enable);
            break;
        default:
            /*无处理*/
            break;
    }
}
static void s_Parse2x2Data(ENUM_2x2_MSG_T msgType, CM_UINT32 msgCyc, CM_UINT16 framNum, CM_UINT16 framIndex, CM_UINT8* data, CM_INT32 len)
{
    static STRU_FrameCtrl_T s_2x2_Area_FrameCtrl; /**< 分帧接收控制 */
    CM_UINT32 ret = 0u;
    switch (msgType)
    {
    case ENUM_2x2_AREA_MSG_DATA:
        if(msgCyc > s_area_state_Ctrl.Rx2x2DataSysCyc)
        {
            /*- 分帧接收跟随报文 */
            CM_RE_ASSERT(framNum <= (SFM_AREA_DATA_BUFF_SIZE / NET_20K_SIZE), SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_1);
            CM_RE_ASSERT(framIndex <= framNum, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_2);
            ret = SFM_FrameSave(&s_2x2_Area_FrameCtrl, (CM_UINT8)ENUM_2x2_MSG_BASE_FOLLOW, framNum, framIndex, data, len, g_2x2_Area_App_DATA, &g_2x2_Area_App_Data_Len, (CM_UINT32)sizeof(g_2x2_Area_App_DATA));
            /*- 是否收齐了跟随报文 */
            if (ENUM_CM_TRUE == ret)
            {
                s_area_state_Ctrl.Rx2x2DataSysCyc = msgCyc;
            }
            else
            {
                
            }
        }
        break;
    default:
        /* 无处理*/
        break;
    }/* end switch */
} 
static void s_ParseAreaData(ENUM_AREA_MSG_T msgType, CM_UINT32 msgCyc, CM_UINT16 framNum, CM_UINT16 framIndex, CM_UINT8* data, CM_INT32 len)
{
    static STRU_FrameCtrl_T s_Area_FrameCtrl[2]; /**< 分帧接收控制 */
    CM_UINT32 msgCrc1 = 0u, msgCrc2 = 0u, calcCrc1 = 0u, calcCrc2 = 0u;
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    switch(msgType)
    {
        case ENUM_AREA_MSG_MASTER:
            /*- 分帧接收跟随报文 */
            CM_RE_ASSERT(framNum <= (SFM_AREA_DATA_BUFF_SIZE / NET_20K_SIZE), SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_1);
            CM_RE_ASSERT(framIndex <= framNum, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_2);
            ret = SFM_FrameSave(&s_Area_FrameCtrl[0], (CM_UINT8)msgType, framNum, framIndex, data, len, g_Area_App_DATA, &g_Area_App_Data_Len, sizeof(g_Area_App_DATA));
            /*- 是否收齐了跟随报文 */
            if (ENUM_CM_TRUE == ret && 8u <= g_Area_App_Data_Len)
            {
                g_Area_App_Data_Len -= 8;
                msgCrc1 = CM_LongFromChar(g_Area_App_DATA + g_Area_App_Data_Len);
                msgCrc2 = CM_LongFromChar(g_Area_App_DATA + g_Area_App_Data_Len + 4);
                calcCrc1 = CM_Crc32_1(g_Area_App_DATA, g_Area_App_Data_Len);
                calcCrc2 = CM_Crc32_2(g_Area_App_DATA, g_Area_App_Data_Len);
                if(calcCrc1 != msgCrc1 || calcCrc2 != msgCrc2)
                {
                    SFM_LOG_MSG_AREA("Recv %d double crc fail\n", msgType);
                    g_Area_App_Data_Len = 0u;
                }
                else
                {
                    SFM_LOG_MSG_AREA("Recv Success, cyc:%d\n", msgCyc);
                }
            }
            else
            {
                
            }
            break;
        case ENUM_AREA_MSG_SLAVE:
            CM_RE_ASSERT(framNum == 1, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_3);
            CM_RE_ASSERT(framIndex <= framNum, SFM_AREA_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_4);
            ret = SFM_FrameSave(&s_Area_FrameCtrl[1], (CM_UINT8)msgType, framNum, framIndex, data, len, g_Area_State_Cache, &g_Area_State_Cache_Len, sizeof(g_Area_State_Cache));
            if (ENUM_CM_TRUE == ret && 8u <= g_Area_State_Cache_Len)
            {
                g_Area_State_Cache_Len -= 8;
                msgCrc1 = CM_LongFromChar(g_Area_State_Cache + g_Area_State_Cache_Len);
                msgCrc2 = CM_LongFromChar(g_Area_State_Cache + g_Area_State_Cache_Len + 4);
                calcCrc1 = CM_Crc32_1(g_Area_State_Cache, g_Area_State_Cache_Len);
                calcCrc2 = CM_Crc32_2(g_Area_State_Cache, g_Area_State_Cache_Len);
                if(calcCrc1 != msgCrc1 || calcCrc2 != msgCrc2)
                {
                    SFM_LOG_MSG_AREA("Recv %d double crc fail\n", msgType);
                    g_Area_State_Cache_Len = 0u;
                }
                else
                {
                    SFM_LOG_MSG_AREA("Recv Success, cyc:%d\n", msgCyc);
                }
            }
            else
            {
                
            }
            break;
        default:
            break;
    }
}