/**
* @file PFM_InputOutput.c
* @brief Platform Function Module: 输入输出管理
* @details
* 平台输入微周期和输出微周期的2oo2、2x2功能实现
* @author GT-BU
* @date 2021.02.20
* @version V1.0
* @copyright TCT
* @par 修改日志
* <table>
* <tr><th>Date        <th>Version  <th>Author     <th>Description
* <tr><td>2021.02.01  <td>V1.0     <td>GT-BU      <td>创建初始版本
* </table>
*/
#include "PFM_InputOutput.h"
#include "CM_Convert.h"
#include "CM_CRC32.h"
#include "CM_Memory.h"
#include "CM_Time.h"
#include "CFM_Raw.h"
#include "SFM_2oo2.h"
#include "SFM_2x2.h"
#include "SFM_Prtcl.h"
#include "PFM_Cfg.h"
#include "PFM_Log.h"
#include "PFM_ControlFlowCheck.h"
#include "CM_MQ.h"
#include "CFM_Net.h"
#include "MSCP_APP_API.h"
#include "CM_Com.h"
#include "DFM_Time.h"
#include "PFM_RemoteUpdate.h"
/*平台通信容量*/
#define PFM_INNETRAW_BUFF_SIZE (1024u*1024u*10u)     /* 内网透传通信透传UDP缓冲区大小 1M*5，应用许用量为2M */
#define PFM_OUTNETRAW_BUFF_SIZE (1024u*1024u*10u) /* 外网安全通信通道UDP缓冲区大小 1M*10，应用许用量为500k */

/*
* 通信通道涉及的内容：
* CFM建立通信层通道，通信报文的接收、发送
*                         CFM                       SFM                    PFM
* 内网安全通信 | UDP通信端口，接收、发送 | 内网安全协议解析、封装 | 2oo2交换，2x2交换 |
* 内网透传通信 | UDP通信端口，接收、发送 |           /            | 2oo2交换，2x2交换 |
* 外网安全通信 | UDP通信端口，接收、发送 | 外网安全协议解析、封装 | 2oo2交换，2x2交换 |
* 外网透传通信 | UDP通信端口，接收、发送 |           /            | 2oo2交换，2x2交换 |
*/

static CM_INT32 s_2x2oo2_app = 1;                /* app缓冲区索引 */

static const CM_INT32 s_2x2oo2_InnetSafe = 1;    /* 内网安全通信的通道索引 */
static const CM_INT32 s_2x2oo2_OutnetSafe = 2;   /* 外网安全通信的通道索引 */
static const CM_INT32 s_2x2oo2_OutnetRaw = 3;    /* 外网透传通道的通道索引 */
static const CM_INT32 s_2x2oo2_RemoteUpdate = 4;    /* 远程部署通道的通道索引 */
static const CM_INT32 s_2x2oo2_OutnetHeart = 5;    /* 外网心跳通道的通道索引 */
static CM_INT32 s_2x2oo2_InnetRaw_num = 0;       /* 内网透传通道的数量 */
static CM_INT32 s_2x2oo2_InnetRaw_Extend_num = 0;/* 内网透传通道的数量 */
static CM_INT32 s_2x2oo2_InnetRaw[INNET_RAW_DOUBLE_PASS_NUM];/* 内网透传通道的通道索引们 */
/*2x分帧接收临时缓冲区*/
CM_UINT8 g_2x2oo2_Frame_TempBuf[SFM_OUTNETSAFE_BUFF_SIZE] = {0u};
/* 透传收发通道的简化宏 */
#define APP_RAW_TX(ch) (g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_InnetRaw[(ch)]])
#define APP_RAW_RX(ch) (g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_InnetRaw[(ch)]])
#define PFM_RAW_TX(ch) (g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_InnetRaw[(ch)]])
#define PFM_RAW_RX(ch) (g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetRaw[(ch)]])

static CM_UINT32 s_InnetRaw_Mine_AppReadIndex[INNET_RAW_DOUBLE_PASS_NUM];  /**< 应用接收内网透传消息的指针 */
static CM_UINT32 s_InnetRaw_Peer_AppReadIndex[INNET_RAW_DOUBLE_PASS_NUM];  /**< 应用接收内网透传消息的指针 */
static CM_UINT32 s_OutnetRaw_Mine_AppReadIndex;  /**< 应用接收外网透传消息的指针 */
static CM_UINT32 s_OutnetRaw_Peer_AppReadIndex;  /**< 应用接收外网透传消息的指针 */
static CM_UINT32 s_OutnetHeart_Mine_AppReadIndex;  /**< 应用接收外网心跳消息的指针 */
static CM_UINT32 s_OutnetHeart_Peer_AppReadIndex;  /**< 应用接收外网心跳消息的指针 */

/*记录红蓝网通信设备临时buf*/
static CM_UINT16 s_rciRedTempBuf[16u * 18u] = {0u};
static CM_UINT16 s_rciBlueTempBuf[16u * 18u] = {0u};
static CM_UINT16 s_rciRedTempBufOffset = 0u;
static CM_UINT16 s_rciBlueTempBufOffset = 0u;

extern CM_INT32 g_PFM_Check;
/* 输入阶段的2oo2交换*/
static void s_input_2oo2sync(void);
/* 将收到的外网输入报文填写到安全协议层 */
static void s_RxOutnetToSFM(IN const CM_UINT8 buf[], IN CM_UINT32 len);
/* 2取2生成输出校验报文 */
static CM_INT32 s_2oo2OutputCheckFrame_Pack(OUT CM_UINT8 buf[], IN CM_UINT32 BufSize);
/* 2x2生成输出校验报文 */
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同步
*/
static void s_input_2x2sync(void)
{
    /*- 变量初始化 */
    CM_INT32 i = 0;
    ENUM_2x2_STATE_T state_2x2 = SFM_2x2_GetLocal2x2State(); /* 本系热备状态 */
    /*- 本机是否为主系 */
    if (ENUM_2x2_MASTER == state_2x2)
    {
        /*- 从第一个2x2oo2通信队列开始|是否遍历完成|下一个队列 */
        for (i = 1; i <= g_2x2oo2_data_num; i++)
        {
            /*- 本队列是否需要2x2同步 */
            if (CM_TRUE == (CM_BOOL)g_2x2oo2_rx[g_2x2oo2_base][i].b_2x2_Enable)
            {
                /*- 将整个通信队列发送到对系 */
                SFM_2x2_Send(g_2x2oo2_rx[g_2x2oo2_base][i].p_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][i].mine_len, (ENUM_2x2_MSG_T)(i));
                SFM_2x2_Send(g_2x2oo2_rx[g_2x2oo2_base][i].p_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][i].peer_len, (ENUM_2x2_MSG_T)(g_2x2oo2_data_num+i));
            }
            else
    		{
            	MSCP_LOG_MSG("(CM_BOOL)g_2x2oo2_rx[g_2x2oo2_base][%d].b_2x2_Enable = %d\n", i,(CM_BOOL)g_2x2oo2_rx[g_2x2oo2_base][i].b_2x2_Enable);
    		}
        }
    }
    else
	{
		/*- 无处理 */
	}
}

/**
* @brief 输入阶段的2oo2交换
*/
static void s_input_2oo2sync(void)
{
    /*- 变量初始化 */
	CM_UINT64 templog[20];
    CM_INT32 i = 0; /* 循环变量 */
    CM_UINT8 ret = 0;
    CM_UINT64 syn2oo2time = 0u;
    /*- 从第一个2x2oo2通信队列开始|是否遍历完成|下一个队列 */
    for (i = 1; i <= g_2x2oo2_data_num; i++)
    {
        /*- 本队列是否需要2oo2同步 */
        if (CM_TRUE == (CM_BOOL)g_2x2oo2_rx[g_2x2oo2_base][i].b_2oo2_Enable)
        {
            /*- 同步本通信队列 */
            g_2x2oo2_rx[g_2x2oo2_base][i].peer_len = (CM_UINT32)SFM_2oo2_Exchange_Currency(
                g_2x2oo2_rx[g_2x2oo2_base][i].p_mine_buf, (CM_INT32)g_2x2oo2_rx[g_2x2oo2_base][i].mine_len,
                g_2x2oo2_rx[g_2x2oo2_base][i].p_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][i].buf_size, ENUM_2oo2_INPUT_EX);
        }
        else
		{
			/*- 无处理 */
		}
    }

    templog[0] = CM_GetTick();
    /*- @alias 协议过滤2取重复数据 */
    if(1 == g_PFM_Cfg.CPU_ID)
    {
    	ret = SFM_OutProtclTwoRepeat(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].mine_len,
                g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_peer_buf,&g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].peer_len);
    }
    else
    {
    	ret = SFM_OutProtclTwoRepeat(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_peer_buf,g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].peer_len,
    			g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_mine_buf, &g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].mine_len);
    }
    CM_ASSERT(ret == 1, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_14, TSCP_DARK_ASSERT_1);
    templog[1] = CM_GetTick();

    syn2oo2time = (templog[1] - templog[0])/1000u;
    MSCP_LOG_MSG("s_input_2oo2sync 2oo2syntime = %lld\n",syn2oo2time);
    (void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_PFMINPUTOUTPUT_INPUT2oo2SYNC, 8U, &syn2oo2time);
}

/**
* @brief 微周期控制初始化 
*/
void PFM_Init(void)
{
    /*- 变量初始化 */
    CM_INT32 base = 0;
    CM_INT32 i = 0;
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 初始化双缓冲索引 */
    g_2x2oo2_base = 0;
    s_2x2oo2_app = 1;

    /*- @alias 初始化内网安全通信和外网安全通信配置 */
    for (base = 0; base < 2; base++)/*- 遍历双缓冲区 */
    {
        /*- 初始化内网安全接收配置 */
        g_2x2oo2_rx[base][s_2x2oo2_InnetSafe].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_InnetSafe].b_2x2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_InnetSafe].buf_size = (CM_UINT32)SFM_INNETSAFE_BUFF_SIZE;
        rt = CM_Mutex_Init(&g_2x2oo2_rx[base][s_2x2oo2_InnetSafe].app_mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1);
        /*- 初始化外网安全接收配置 */
        g_2x2oo2_rx[base][s_2x2oo2_OutnetSafe].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_OutnetSafe].b_2x2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_OutnetSafe].buf_size = (CM_UINT32)SFM_OUTNETSAFE_BUFF_SIZE;
        rt = CM_Mutex_Init(&g_2x2oo2_rx[base][s_2x2oo2_OutnetSafe].app_mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_2);
        /*- 初始化外网透传接收配置 */
        g_2x2oo2_rx[base][s_2x2oo2_OutnetRaw].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_OutnetRaw].b_2x2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_OutnetRaw].buf_size = (CM_UINT32)PFM_OUTNETRAW_BUFF_SIZE;
        rt = CM_Mutex_Init(&g_2x2oo2_rx[base][s_2x2oo2_OutnetRaw].app_mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_3);
		/*- 初始化远程部署内网安全接收配置 */
        g_2x2oo2_rx[base][s_2x2oo2_RemoteUpdate].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_RemoteUpdate].b_2x2_Enable = (CM_UINT32)CM_FALSE;
        g_2x2oo2_rx[base][s_2x2oo2_RemoteUpdate].buf_size = (CM_UINT32)SFM_INNETSAFE_RM_BUFF_SIZE;
        rt = CM_Mutex_Init(&g_2x2oo2_rx[base][s_2x2oo2_RemoteUpdate].app_mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_18);
        /*- 初始化外网心跳信息接收配置 */
        g_2x2oo2_rx[base][s_2x2oo2_OutnetHeart].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_OutnetHeart].b_2x2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_rx[base][s_2x2oo2_OutnetHeart].buf_size = (CM_UINT32)SFM_INNETSAFE_BUFF_SIZE;
        rt = CM_Mutex_Init(&g_2x2oo2_rx[base][s_2x2oo2_OutnetHeart].app_mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_19);
        

        /*- 初始化内网安全发送配置 */
        g_2x2oo2_tx[base][s_2x2oo2_InnetSafe].buf_size = (CM_UINT32)SFM_INNETSAFE_BUFF_SIZE;
        g_2x2oo2_tx[base][s_2x2oo2_InnetSafe].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_tx[base][s_2x2oo2_InnetSafe].b_2x2_Enable = (CM_UINT32)CM_TRUE;
        rt = CM_Mutex_Init(&g_2x2oo2_tx[base][s_2x2oo2_InnetSafe].mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_5);
        /*- 初始化外网安全发送配置 */
        g_2x2oo2_tx[base][s_2x2oo2_OutnetSafe].buf_size = (CM_UINT32)SFM_OUTNETSAFE_BUFF_SIZE;
        g_2x2oo2_tx[base][s_2x2oo2_OutnetSafe].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_tx[base][s_2x2oo2_OutnetSafe].b_2x2_Enable = (CM_UINT32)CM_TRUE;
        rt = CM_Mutex_Init(&g_2x2oo2_tx[base][s_2x2oo2_OutnetSafe].mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_6);
        /*- 初始化外网透传发送配置 */
        g_2x2oo2_tx[base][s_2x2oo2_OutnetRaw].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_tx[base][s_2x2oo2_OutnetRaw].b_2x2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_tx[base][s_2x2oo2_OutnetRaw].buf_size = (CM_UINT32)PFM_OUTNETRAW_BUFF_SIZE;
        rt = CM_Mutex_Init(&g_2x2oo2_tx[base][s_2x2oo2_OutnetRaw].mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_7);
		/*- 初始化远程部署内网安全发送配置 */
        g_2x2oo2_tx[base][s_2x2oo2_RemoteUpdate].buf_size = (CM_UINT32)SFM_INNETSAFE_RM_BUFF_SIZE;
        g_2x2oo2_tx[base][s_2x2oo2_RemoteUpdate].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_tx[base][s_2x2oo2_RemoteUpdate].b_2x2_Enable = (CM_UINT32)CM_FALSE;
        rt = CM_Mutex_Init(&g_2x2oo2_tx[base][s_2x2oo2_RemoteUpdate].mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_17);
        /*- 初始化外网心跳信息发送配置 */
        g_2x2oo2_tx[base][s_2x2oo2_OutnetHeart].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
        g_2x2oo2_tx[base][s_2x2oo2_OutnetHeart].b_2x2_Enable = (CM_UINT32)CM_FALSE;
        g_2x2oo2_tx[base][s_2x2oo2_OutnetHeart].buf_size = (CM_UINT32)SFM_INNETSAFE_BUFF_SIZE;
        rt = CM_Mutex_Init(&g_2x2oo2_tx[base][s_2x2oo2_OutnetHeart].mutex);
        CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_20);
    }   
    
    /*- @alias 初始化内网透传通道配置 */
    s_2x2oo2_InnetRaw_num = g_PFM_Cfg.Local_Cfg.Port_Innet_Raw_Num;
    s_2x2oo2_InnetRaw_Extend_num = g_PFM_Cfg.Local_Cfg.Port_Innet_Raw_Extend_Num;
    for (base = 0; base < 2; base++)/* 遍历双缓冲区 */
    {
        for (i = 1; i <= (s_2x2oo2_InnetRaw_num + s_2x2oo2_InnetRaw_Extend_num); i++)/* 遍历所有透传通道 */
        {
            /* 初始化透传通道索引 */
            s_2x2oo2_InnetRaw[i] = s_2x2oo2_OutnetHeart + i;
			/* 初始化接收通道配置 -只有全部数据需要二取，时间戳不需要2取*/
			if((CM_UINT16)0x55u == g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].INNET_2oo2_RAW)
			{
				if((CM_UINT16)0xAAu == g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].TIME_STAMP_ENABLE)
				{
					g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
					g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].helpinfo_buf_size = (CM_UINT32)0u;
				}
				else
				{
					/*需要二取时间戳，不需要全部数据二取*/
					g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].b_2oo2_Enable = (CM_UINT32)CM_FALSE;
					/*辅助信息-缓冲区长度分配*/
					g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].helpinfo_buf_size = (CM_UINT32)CFM_INNET_RAW_MSG_NUM_MAX * 12u;
				}
				g_2x2oo2_tx[base][s_2x2oo2_InnetRaw[(i)]].b_2oo2_Enable = (CM_UINT32)CM_TRUE;
			}
			else
			{
				/*该通道透传数据均不需要二取*/
				g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].b_2oo2_Enable = (CM_UINT32)CM_FALSE;
				g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].helpinfo_buf_size = (CM_UINT32)0u;
				g_2x2oo2_tx[base][s_2x2oo2_InnetRaw[(i)]].b_2oo2_Enable = (CM_UINT32)CM_FALSE;
			}

			if((CM_UINT16)0x55u == g_PFM_Cfg.Local_Cfg.Innet_Raw_Parameter[i].INNET_2x2_RAW)
			{
				g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].b_2x2_Enable = (CM_UINT32)CM_TRUE;
				g_2x2oo2_tx[base][s_2x2oo2_InnetRaw[(i)]].b_2x2_Enable = (CM_UINT32)CM_TRUE;
			}
			else
			{
				g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].b_2x2_Enable = (CM_UINT32)CM_FALSE;
				g_2x2oo2_tx[base][s_2x2oo2_InnetRaw[(i)]].b_2x2_Enable = (CM_UINT32)CM_FALSE;
			}

			g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].buf_size = (CM_UINT32)PFM_INNETRAW_BUFF_SIZE;
			rt = CM_Mutex_Init(&g_2x2oo2_rx[base][s_2x2oo2_InnetRaw[(i)]].app_mutex);
			CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_8);
			/* 初始化发送通道配置 */
			g_2x2oo2_tx[base][s_2x2oo2_InnetRaw[(i)]].buf_size = (CM_UINT32)PFM_INNETRAW_BUFF_SIZE;
			rt = CM_Mutex_Init(&g_2x2oo2_tx[base][s_2x2oo2_InnetRaw[(i)]].mutex);
			CM_ASSERT(ENUM_CM_TRUE == rt, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_9);
        }
    }
    /*- 确定通道总数 = 固定通道数 + 内网透传通道数 + 内网透传扩展通道数 */
    g_2x2oo2_data_num = s_2x2oo2_OutnetHeart + s_2x2oo2_InnetRaw_num + s_2x2oo2_InnetRaw_Extend_num;

    /*- @alias 缓冲区内存分配 */
    for (base = 0; base < 2; base++)/* 遍历双缓冲区 */
    {
        for (i = 1; i <= g_2x2oo2_data_num; i++)/*遍历所有通道*/
        {
            /* 为接收通道分配内存 */
        	if(0u < g_2x2oo2_rx[base][i].buf_size)
        	{
				g_2x2oo2_rx[base][i].p_mine_buf = (CM_UINT8*)CM_Malloc((CM_SIZE_T)g_2x2oo2_rx[base][i].buf_size);
				CM_ASSERT(NULL != g_2x2oo2_rx[base][i].p_mine_buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_10);
        	}
        	else
        	{
        		/*- 无处理 */
        	}
            if (CM_TRUE == (CM_BOOL)g_2x2oo2_rx[base][i].b_2oo2_Enable)
            {
                g_2x2oo2_rx[base][i].p_peer_buf = (CM_UINT8*)CM_Malloc((CM_SIZE_T)g_2x2oo2_rx[base][i].buf_size);
                CM_ASSERT(NULL != g_2x2oo2_rx[base][i].p_peer_buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_11);
            }
            else
    		{
    			/*- 无处理 */
    		}
            if (CM_TRUE == (CM_BOOL)g_2x2oo2_rx[base][i].b_2x2_Enable)
            {
            	g_2x2RcvMaxNum[base] = g_2x2oo2_data_num*base + i;/*记录2x双缓冲区最大序号*/
                g_2x2oo2_rx[base][i].p_rmt_mine_buf = (CM_UINT8*)CM_Malloc((CM_SIZE_T)g_2x2oo2_rx[base][i].buf_size);
                CM_ASSERT(NULL != g_2x2oo2_rx[base][i].p_rmt_mine_buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_12);
            }
            else
    		{
    			/*- 无处理 */
    		}
            if ((CM_TRUE == (CM_BOOL)g_2x2oo2_rx[base][i].b_2oo2_Enable) && (CM_TRUE == (CM_BOOL)g_2x2oo2_rx[base][i].b_2x2_Enable))
            {
                g_2x2oo2_rx[base][i].p_rmt_peer_buf = (CM_UINT8*)CM_Malloc((CM_SIZE_T)g_2x2oo2_rx[base][i].buf_size);
                CM_ASSERT(NULL != g_2x2oo2_rx[base][i].p_rmt_peer_buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_13);
            }
            else
    		{
    			/*- 无处理 */
    		}
            /*初始化辅助信息通道缓冲区*/
            if (0u < g_2x2oo2_rx[base][i].helpinfo_buf_size)
            {
				g_2x2oo2_rx[base][i].p_mine_helpinfo_buf = (CM_UINT8*)CM_Malloc((CM_SIZE_T)g_2x2oo2_rx[base][i].helpinfo_buf_size);
				CM_ASSERT(NULL != g_2x2oo2_rx[base][i].p_mine_helpinfo_buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_14);
				g_2x2oo2_rx[base][i].p_peer_helpinfo_buf = (CM_UINT8*)CM_Malloc((CM_SIZE_T)g_2x2oo2_rx[base][i].helpinfo_buf_size);
				CM_ASSERT(NULL != g_2x2oo2_rx[base][i].p_peer_helpinfo_buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_15);
            }

            else
            {
            	/*- 无处理 */
            }
            /* 为发送通道分配内存 */
            if(0u < g_2x2oo2_tx[base][i].buf_size)
            {
				g_2x2oo2_tx[base][i].p_buf = (CM_UINT8*)CM_Malloc((CM_SIZE_T)g_2x2oo2_tx[base][i].buf_size);
				CM_ASSERT(NULL != g_2x2oo2_tx[base][i].p_buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_16);
            }
            else
            {
            	/*- 无处理 */
            }
        }
    }
}

/**
* @brief 双缓冲切换
*/
void PFM_BufSwich(void)
{
    /*- 变量初始化 */
    CM_INT32 i = 0;

    /*- 内外网安全协议对应用任务的缓冲区切换 */
    PFM_CFC_Check(1);
    SFM_PrtclBufSwitch();

    /*内网安全通道-缓冲区长度清零*/
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_InnetSafe].mine_len = 0u;
	g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_InnetSafe].peer_len = 0u;
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_InnetSafe].rmt_mine_len = 0u;
	g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_InnetSafe].rmt_peer_len = 0u;
	/*外网安全通道-缓冲区长度清零*/
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetSafe].mine_len = 0u;
	g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetSafe].peer_len = 0u;
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetSafe].rmt_mine_len = 0u;
	g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetSafe].rmt_peer_len = 0u;

	/*外网透传通道-缓冲区长度清零*/
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].peer_len = 0u;
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].mine_len = 0u;
    g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetRaw].app_index_log = 0u;/*清空本周期平台及将记录的标志*/
    /*远程部署通道通道-缓冲区长度清零*/
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_RemoteUpdate].mine_len = 0u;
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_RemoteUpdate].peer_len = 0u;

    /*心跳通道-缓冲区长度清零*/
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetHeart].mine_len = 0u;
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetHeart].peer_len = 0u;
    g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetHeart].rmt_mine_len = 0u;
	g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetHeart].rmt_peer_len = 0u;
    g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetHeart].app_index_log = 0u;
    /*- @alias 内网透传通道长度归0 */
    for (i = 1; i <= (s_2x2oo2_InnetRaw_num + s_2x2oo2_InnetRaw_Extend_num); i++)
    {
    	APP_RAW_RX(i).mine_len = 0u;
    	APP_RAW_RX(i).mine_helpinfo_len = 0u;
    	APP_RAW_RX(i).peer_len = 0u;
    	APP_RAW_RX(i).peer_helpinfo_len = 0u;
    	PFM_RAW_RX(i).app_index_log = 0u;
    	
    	/*- @alias 内网透传通道的读索引归0 */
        s_InnetRaw_Mine_AppReadIndex[i] = 0u;
        s_InnetRaw_Peer_AppReadIndex[i] = 0u;
    }

    /*- 2x2oo2通信队列的缓冲区切换 */
    g_2x2oo2_base = 1 - g_2x2oo2_base;
    s_2x2oo2_app = 1 - s_2x2oo2_app;
    CM_RE_ASSERT((0 == g_2x2oo2_base) || (1 == g_2x2oo2_base), IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    CM_RE_ASSERT((0 == s_2x2oo2_app) || (1 == s_2x2oo2_app), IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2);
    CM_RE_ASSERT(g_2x2oo2_base != s_2x2oo2_app, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_3);

    PFM_CFC_Check(2);
	/*- @alias 外网透传通道的读索引归0 */
	s_OutnetRaw_Mine_AppReadIndex = 0u;
    s_OutnetRaw_Peer_AppReadIndex = 0u;

    s_OutnetHeart_Mine_AppReadIndex = 0;
    s_OutnetHeart_Peer_AppReadIndex = 0;
}

/**
* @brief 输入微周期处理
* @details 
* 输入微周期的2oo2、2x2处理：
* 平台数据接收；
* 2x2发送；
* 本地输入数据2oo2交换和比较；
* 输入阶段2x2处理；
* 交付协议适配层处理。
*/
void PFM_InputProc(void)
{
    /*- 变量初始化 */
    CM_INT32 i = 0;
    ENUM_2x2_STATE_T p_state_2x2 = ENUM_2x2_SHUTDOWN; /* 对系热备状态 */

    /************************平台数据接收*************************/
    /*- 外网安全数据接收 */
    PFM_CFC_Check(26);
    g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].mine_len = (CM_UINT32)SFM_RxOutnetSafe(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_mine_buf, (CM_UINT32)g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].buf_size);
    MSCP_LOG_MSG("g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].mine_len = %d\n",g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].mine_len);
    /*判断外网透传使能开关*/
    if((CM_UINT32)0x55u == g_PFM_Cfg.M_OutnetRaw_Enable)
    {
    	/*- 外网透传数据接收 */
    	g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetRaw].mine_len = CFM_RxOutnetRaw(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetRaw].p_mine_buf, (CM_UINT32)g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetRaw].buf_size);
	}
    else
    {
    	/*外网透传未使能*/
    }
    /*- 外网心跳数据接收 */
    g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetHeart].mine_len = CFM_RxOutnetHeart(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetHeart].p_mine_buf, (CM_UINT32)g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetHeart].buf_size);
    /*- 内网安全数据接收 */
    PFM_CFC_Check(27);
    g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].mine_len = (CM_UINT32)SFM_RxInnetSafe(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_mine_buf, (CM_UINT32)g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].buf_size);
    PFM_CFC_Check(28);
	g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].mine_len = (CM_UINT32)SFM_RxInnetSafeRm(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].p_mine_buf, (CM_UINT32)g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].buf_size);
    PFM_CFC_Check(29);
    /*- @alias 内网透传数据接收 */
    for (i = 1; i <= s_2x2oo2_InnetRaw_num + s_2x2oo2_InnetRaw_Extend_num; i++)
    {
    	PFM_RAW_RX(i).mine_len = CFM_RxInnetRaw_COM(i, PFM_RAW_RX(i).p_mine_buf, (CM_UINT32)PFM_RAW_RX(i).buf_size,/*透传数据*/
    							 PFM_RAW_RX(i).p_mine_helpinfo_buf,&PFM_RAW_RX(i).mine_helpinfo_len, /*透传数据本机辅助信息*/
								 PFM_RAW_RX(i).p_peer_helpinfo_buf,&PFM_RAW_RX(i).peer_helpinfo_len, /*透传数据临机辅助信息*/
								 (CM_UINT32)PFM_RAW_RX(i).helpinfo_buf_size);/*透传数据缓冲区长度*/
    	MSCP_LOG_MSG("[%d]:APP_LastReadIndex:%d,T = %d us\n", i, PFM_RAW_RX(i).app_index_log,NOW_USED_TIME);
    }

    PFM_CFC_Check(30);
    /*- 外网心跳数据发送前组包*/
    g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetHeart].buf_len = PFM_OutnetHeart_Send();
    /*- 发送外网心跳数据*/
    (void)CFM_TxOutnetHeart(g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetHeart].p_buf, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetHeart].buf_len);
	/*- 清空心跳数据得长度(主备都清空) */
	g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetHeart].buf_len = 0;
    PFM_CFC_Check(31); /*预留*/
    /*************************本地输入数据2oo2交换和比较*************************/
    MSCP_LOG_MSG("timecurr 1 Input Recv = %lld us\n", NOW_USED_TIME);
    /*- 是否开启2oo2功能 */
    if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
    {
        /*- 执行输入阶段的2oo2交换 */
        s_input_2oo2sync();
    }
    else
	{
		/*- 无处理 */
	}

    /*************************2x2发送*************************/
    MSCP_LOG_MSG("timecurr 2 Input 2oo2 = %lld us\n", NOW_USED_TIME);
    PFM_CFC_Check(32);
    /*- 是否开启2x2功能*/
    if (0x55u == g_PFM_Cfg.M_2x2_Enable)
    {
        /*- 执行输入阶段的2x2同步 */
        (void)s_input_2x2sync();
    }
    else
	{
		/*- 无处理 */
	}
    MSCP_LOG_MSG("timecurr 3 Input 2x2Send = %lld us\n", NOW_USED_TIME);

    /*************************输入阶段2x2处理*************************/
    /*接收对系输入数据，系内交换和比较，更新热备状态，发送状态信息*/
    /*- 是否开启2x2功能 */
    if (0x55u == g_PFM_Cfg.M_2x2_Enable)
    {
        /*- 输入阶段2x2处理 */
        SFM_2x2_InputProc();
    }
    else
    {
        /*- 更新控制流状态 */
    	PFM_CFC_Check(33);
        PFM_CFC_Check(34);
        PFM_CFC_Check(35);
        PFM_CFC_Check(36);
        PFM_CFC_Check(37);
        PFM_CFC_Check(38);
        PFM_CFC_Check(39);
    }
    MSCP_LOG_MSG("timecurr 4 Input 2x2Data = %lld us\n", NOW_USED_TIME);
    /*************************交付协议适配层处理*************************/
    /*- 获取对系热备状态 */
    p_state_2x2 = SFM_2x2_GetPartner2x2State();
    MSCP_LOG_MSG("SFM_Write bef T = %d us\n",NOW_USED_TIME);
    /*- @alias 将周期输入数据交付给协议适配层处理 */
    if (MSCP_CPU_1 == g_PFM_Cfg.CPU_ID)
    {
    	SFM_WriteInnetSafeRmInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].p_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].mine_len, ENUM_INNET_PURPLE);
    	SFM_WriteInnetSafeRmInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].p_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].peer_len, ENUM_INNET_GREEN);
    	
    	
        if (ENUM_2x2_MASTER == p_state_2x2)
        {
            /* 对系为主系，只使用主系输入 */
            PFM_CFC_Check(40);
            SFM_WriteInnetSafeInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_rmt_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].rmt_mine_len, ENUM_INNET_GREEN);
            
            PFM_CFC_Check(41);
            SFM_WriteInnetSafeInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_rmt_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].rmt_peer_len, ENUM_INNET_PURPLE);
            
            PFM_CFC_Check(42);
            s_RxOutnetToSFM(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_rmt_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].rmt_mine_len);
            PFM_CFC_Check(43);
            s_RxOutnetToSFM(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_rmt_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].rmt_peer_len);
        }
        else
        {            
            /* 对系不是主，使用自己的输入 */
            PFM_CFC_Check(40);
            SFM_WriteInnetSafeInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].mine_len, ENUM_INNET_GREEN);
            
            PFM_CFC_Check(41);
            SFM_WriteInnetSafeInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].peer_len, ENUM_INNET_PURPLE);
            
            PFM_CFC_Check(42);
            s_RxOutnetToSFM(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].mine_len);
            PFM_CFC_Check(43);
            s_RxOutnetToSFM(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].peer_len);
        }        
    }
    else
    {
    	SFM_WriteInnetSafeRmInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].p_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].peer_len, ENUM_INNET_GREEN);
    	SFM_WriteInnetSafeRmInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].p_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].mine_len, ENUM_INNET_PURPLE);
    	
    	
        if (ENUM_2x2_MASTER == p_state_2x2)
        {
            /* 对系为主系，只使用主系输入 */
            PFM_CFC_Check(40);
            SFM_WriteInnetSafeInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_rmt_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].rmt_peer_len, ENUM_INNET_GREEN);
            PFM_CFC_Check(41);
            SFM_WriteInnetSafeInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_rmt_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].rmt_mine_len, ENUM_INNET_PURPLE);
            PFM_CFC_Check(42);
            s_RxOutnetToSFM(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_rmt_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].rmt_peer_len);
            PFM_CFC_Check(43);
            s_RxOutnetToSFM(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_rmt_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].rmt_mine_len);

        }
        else
        {
            /* 对系不是主，使用自己的输入 */
            PFM_CFC_Check(40);
            SFM_WriteInnetSafeInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].peer_len, ENUM_INNET_GREEN);
            PFM_CFC_Check(41);
            SFM_WriteInnetSafeInput(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_InnetSafe].mine_len, ENUM_INNET_PURPLE);
            PFM_CFC_Check(42);
            s_RxOutnetToSFM(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_peer_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].peer_len);
            PFM_CFC_Check(43);
            s_RxOutnetToSFM(g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_mine_buf, g_2x2oo2_rx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].mine_len);
		}
	}

    MSCP_LOG_MSG("timecurr 5 Input SetPro = %lld us\n", NOW_USED_TIME);
}

/**
* @brief 输出微周期处理
* @details 
* 输出微周期的2oo2、2x2处理：
* 从协议适配层获取输出数据；
* 生成输出校验帧；
* 2oo2输出比较；
* 输出阶段2x2处理；
* 平台数据发送。
*/
void PFM_OutputProc(void)
{
    /*- 变量初始化 */
    CM_INT32 check_2oo2_Len = 0;          /* 输出校验帧长度 */
    CM_UINT8 check_2oo2_Buf[500] = { 0u }; /* 输出校验帧数组 */
    CM_INT32 check_2x2_Len = 0;          /* 输出校验帧长度 */
    CM_UINT8 check_2x2_Buf[500] = { 0u }; /* 输出校验帧数组 */
    CM_INT32 i = 0, ret = 0;                 /* 循环变量 */
    ENUM_2x2_STATE_T state_2x2 = ENUM_2x2_SHUTDOWN; /* 本系热备状态 */


    /*########################从协议适配层获取输出数据########################*/
    /*- 从协议适配层获取输出数据 */
    PFM_CFC_Check(5);
    g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_InnetSafe].buf_len = (CM_INT32)SFM_ReadInnetCodedOutput(g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_buf, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_InnetSafe].buf_size);
	g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].buf_len = (CM_INT32)SFM_ReadInnetRmCodedOutput(g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].p_buf, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].buf_size);
    PFM_CFC_Check(6);
    g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].buf_len = (CM_INT32)SFM_ReadOutnetCodedOutput(g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_buf, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].buf_size);
    /*########################生成输出校验帧########################*/
	PFM_CFC_Check(7);
    /*- 是否开启了2oo2功能或2x2功能 */
    if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
    {
        /*- 生成输出校验帧 */
    	check_2oo2_Len = s_2oo2OutputCheckFrame_Pack(check_2oo2_Buf, (CM_UINT32)sizeof(check_2oo2_Buf));
    }
    else
	{
		/*- 无处理 */
	}
    PFM_CFC_Check(8);
    if(0x55u == g_PFM_Cfg.M_2x2_Enable)
    {
    	/*- 生成输出校验帧 */
    	check_2x2_Len = s_2x2OutputCheckFrame_Pack(check_2x2_Buf, (CM_UINT32)sizeof(check_2x2_Buf));
	}
	else
	{
		/*- 无处理 */
	}
    MSCP_LOG_MSG("timecurr 14 OutputCheckFrame_Pack = %lld us\n", NOW_USED_TIME);
    /*########################2oo2输出比较########################*/
    PFM_CFC_Check(9);
    /*- 是否开启了2oo2功能 */
    if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
    {
        /* 2取校验 */
        (void)s_output_2oo2check(check_2oo2_Buf, (CM_UINT32)check_2oo2_Len);
    }
    else
    {
        /*- 无处理 */
    }

    MSCP_LOG_MSG("timecurr 15 Output2oo2 = %lld us\n", NOW_USED_TIME);

    /*########################输出阶段2x2处理########################*/
    /*发送/接收输出校验，接收对系状态，系内交换，输出校验，更新热备状态，生成和发送跟随数据*/
    if (0x55u == g_PFM_Cfg.M_2x2_Enable)
    {
        /*- 输出阶段2x2处理 */
        ret = SFM_2oo2_Exchange_Currency(check_2x2_Buf, check_2x2_Len, &check_2x2_Buf[check_2x2_Len], sizeof(check_2x2_Buf) - check_2x2_Len, ENUM_2oo2_OUTPUT_EX);
        check_2x2_Len += ret;
        SFM_2x2_OutputProc(check_2x2_Buf, check_2x2_Len);
    }
    else
    {
        /*- 更新控制流状态 */

    	PFM_CFC_Check(10);
    	PFM_CFC_Check(11);
    	PFM_CFC_Check(12);
    	PFM_CFC_Check(13);
    	PFM_CFC_Check(14);
    }
    MSCP_LOG_MSG("timecurr 16 Output2x2 = %lld us\n", NOW_USED_TIME);

    /*########################平台数据发送########################*/
	PFM_CFC_Check(15);
    if (0x55u == g_PFM_Cfg.M_2x2_Enable)
    {
		/*热备状态切换*/
		SFM_2x2_ChangeState();
    }
    else
    {
    	/*无处理 */
    }
    PFM_CFC_Check(16);
    /*- 获取当前热备状态 */
    state_2x2 = SFM_2x2_GetLocal2x2State();
    MSCP_LOG_MSG("SFM_2x2_GetSysCount() = %d, s_txSn = %d\n", SFM_2x2_GetSysCount(), SFM_GetTxSn());
    MSCP_LOG_MSG("timecurr 16.1 = %lld us\n", NOW_USED_TIME);
    /*- 本系是否为主 */
    if (ENUM_2x2_MASTER == state_2x2)
    {
    	MSCP_LOG_MSG("Out:innetSafe = %d, innetRaw = %d, outnetSafe = %d\n", (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_InnetSafe].buf_len, (CM_UINT32)PFM_RAW_TX(i).buf_len, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].buf_len);
        /*- 发送内网安全输出数据 */
    	PFM_CFC_Check(17);
        SFM_TxInnetSafe(g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_InnetSafe].p_buf, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_InnetSafe].buf_len);

        PFM_CFC_Check(18);
        /*- @alias 发送内网透传输出数据 */
        for (i = 1; i <= (s_2x2oo2_InnetRaw_num + s_2x2oo2_InnetRaw_Extend_num); i++)
        {
            (void)CFM_TxInnetRaw(i, PFM_RAW_TX(i).p_buf, (CM_UINT32)PFM_RAW_TX(i).buf_len);
        }

        /*- 发送外网安全输出数据 */  
        PFM_CFC_Check(19);
        SFM_TxOutnetSafe(g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].p_buf, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetSafe].buf_len);
        /*- 发送外网透传输出数据 */
        PFM_CFC_Check(20);
        (void)CFM_TxOutnetRaw(g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetRaw].p_buf, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetRaw].buf_len);
    }
    else
    {
        /*- 直接更新控制流状态 */
    	PFM_CFC_Check(17);
    	PFM_CFC_Check(18);
    	PFM_CFC_Check(19);
    	PFM_CFC_Check(20);
    }
    /*- 发送内网安全维护模式数据*/
	SFM_TxInnetSafeRm(g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].p_buf, (CM_UINT32)g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].buf_len);
	MSCP_LOG_MSG("SFM_TxInnetSafeRm = %d\n",g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_RemoteUpdate].buf_len);
    /*- 清空外网透传数据得长度(主备都清空) */
	g_2x2oo2_tx[g_2x2oo2_base][s_2x2oo2_OutnetRaw].buf_len = 0;
    /*- @alias 清空内网透传数据得长度(主备都清空) */
    for (i = 1; i <= (s_2x2oo2_InnetRaw_num + s_2x2oo2_InnetRaw_Extend_num); i++)
    {
        PFM_RAW_TX(i).buf_len = 0;
    }
    PFM_CFC_Check(21);/*预留控制流*/
    /*- 硬件重启输出*/
    MSCP_LOG_MSG("timecurr 16.2 = %lld us\n", NOW_USED_TIME);
    PFM_HardWareBoot_OutPut();
    MSCP_LOG_MSG("timecurr 17 OutputSend = %lld us\n", NOW_USED_TIME);
}

/**
* @brief 周期末处理
* @details
* 生成和传输跟随数据
*/
void PFM_EndProc(void)
{
    /*- 变量初始化 */
    CM_UINT8 mybuf[8] = { 0u };  /* 本机2oo2缓冲区 */
    CM_UINT8 peerbuf[8] = { 0u };/* 邻机2oo2缓冲区 */
    CM_INT32 len = 0; /* 长度 */
    ENUM_BOARD_STATE_T remoteState;
    static CM_UINT8 MaintenanceFlag = 0u;
    /* 应用关键数据的2oo2比较 */
    /*80 * 10 * 1024 耗时20ms*/
    /*- 是否开启了2oo2功能 */
    PFM_CFC_Check(48);
    if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
    {
        /*- 生成跟随数据的特征信息 */
        CM_LongToChar((CM_UINT32)g_TxAppFollow_len, mybuf);
        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))
        {
        	/* 填入另一个CPU的CRC，本机的CRC在接口函数里设置的时候已计算，直接使用 */
            CM_Memcpy(&g_TxAppFollow[4u], 4u, &peerbuf[4u], 4u);
        }
        else
        {
        	MSCP_LOG_DATALEN(g_TxAppFollow, g_TxAppFollow_len, "PFM_EndProc g_TxAppFollow_len");
        	CM_RE_ASSERT(0, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_2);
        }
        /*板卡状态与硬件重启IO更新*/
        PFM_HardWareBoot_UpData();
		/*- 周期末维护模式转换 */
        remoteState = PFM_GetBoardState();
        CM_LongToChar(remoteState,mybuf);
        len = SFM_2oo2_Exchange_Currency(mybuf, 4, peerbuf, 4u, ENUM_2oo2_OUTPUT_CHECK);
        CM_RE_ASSERT(0 == CM_Memcmp(mybuf, peerbuf, (CM_SIZE_T)4), IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_3);
        if(1u == MaintenanceFlag)
        {
			(void)SFM_2oo2_Exchange_Currency(mybuf, 0, peerbuf, 0u, ENUM_2oo2_SHUTDOWNQUIT);
        	/*- 进入运营模式 */
			CM_ASSERT(0, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_4, TSCP_DARK_ASSERT_4);
        }
        else if(ENUM_BOARDSTATE_EXIT == g_boardState)
        {
        	MaintenanceFlag = 1u;
        }
        else
        {
        	/*- 继续运行 */
        }
    }
    else
    {

        /*- 无处理 */
    }
    MSCP_LOG_MSG("timecurr 9 PFM_EndProc txCompare = %lld us\n", NOW_USED_TIME);
    PFM_CFC_Check(49);
    /* 应用关键数据跟随 */
    /*- 是否开启了2x2功能 */
    if (0x55u == g_PFM_Cfg.M_2x2_Enable)
    {
        /*- 周期末2x2处理 */
        SFM_2x2_EndProc();
    }
    else
    {

        /*- 无处理 */
    }
       
}

/**
* @brief 将收到的外网输入报文填写到安全协议层
* @param Buf 外网输入报文指针
* @param len 外网输入报文长度
*/
static void s_RxOutnetToSFM(IN const CM_UINT8 buf[], IN CM_UINT32 len)
{
    /*- 变量初始化 */
	CM_UINT8 i = 0u;
    CM_UINT32 redLen = 0u;   /* 红网报文长度 */
    CM_UINT32 blueLen = 0u;  /* 蓝网报文长度 */
    CM_UINT32 offset = 0u;  /* 蓝网报文长度 */
    CM_UINT32 tmpLen = len;  /* 蓝网报文长度 */
    for(i = 0u;i < 2u; i++)
    {
    	tmpLen = len - offset;
    	/*- 输入合法性检查是否通过 */
		if (tmpLen >= 8u)
		{
			/*- 将红、蓝网外网输入报文分别填入安全协议层 */
			redLen = CM_LongFromChar(&buf[offset]);
			CM_RE_ASSERT(redLen <= (tmpLen - 8u),IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_5, TSCP_DARK_ASSERT_1);
			SFM_WriteOutnetSafeInput(&buf[offset + 4u], redLen, ENUM_OUTNET_RED);  /* parasoft-suppress MISRA2004-17_1 MISRA2004-17_4 "指针运算提高代码执行效率" */
			/*- 注册函数是否为空 */
			if(NULL == p_Status_Communication_Func)
			{
				/*- 无处理 */
			}
			else
			{
				/*- 将数据给到应用,应用解包判断通信情况  */
				(*p_Status_Communication_Func)(&buf[offset + 4u], redLen, ENUM_OUTNET_RED, s_rciRedTempBuf, &s_rciRedTempBufOffset);
			}
			blueLen = CM_LongFromChar(&buf[offset + 4u + redLen]);                /* parasoft-suppress MISRA2004-17_1 MISRA2004-17_4 "指针运算提高代码执行效率" */
			CM_RE_ASSERT(blueLen <= (tmpLen - 8u - redLen),IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_5, TSCP_DARK_ASSERT_2);
			SFM_WriteOutnetSafeInput(&buf[offset + 8u + redLen], blueLen, ENUM_OUTNET_BLUE);/* parasoft-suppress MISRA2004-17_1 MISRA2004-17_4 "指针运算提高代码执行效率" */
			if(NULL == p_Status_Communication_Func)
			{
				/*- 无处理 */
			}
			else
			{
				/*- 将数据给到应用,应用解包判断通信情况  */
				(*p_Status_Communication_Func)(&buf[offset + 8u + redLen], blueLen, ENUM_OUTNET_BLUE, s_rciBlueTempBuf, &s_rciBlueTempBufOffset);
			}
			offset = blueLen + 8u + redLen;
	    }
	    else
		{
			/*- 无处理 */
	    	(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_PFMINPUTOUTPUT_RXOUTNETTOSFM, 4U, &tmpLen);
		}
    }
}

/**
* @brief 生成输出校验报文
* @param Buf 输出校验报文指针
* @param BufSize 输出校验报文缓冲区大小
* @return 输出校验报文长度
*/
static CM_INT32 s_2oo2OutputCheckFrame_Pack(OUT CM_UINT8 buf[], IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_INT32 i = 0;       /* 循环变量 */
    CM_INT32 ch = 0;      /* 循环变量 */
    CM_UINT32 len = 0u;   /* 输出跟随报文长度 */
    CM_UINT32 crc = 0u;   /* 输出跟随报文CRC */
    CM_UINT32 sysCyc = SFM_2x2_GetSysCount(); /* 系统周期号 */

    /*- 入参检查*/
    CM_ASSERT(((6 + (g_2x2oo2_data_num * 8)) <= (CM_INT32)BufSize) && (NULL != buf), IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_6, TSCP_DARK_ASSERT_1);

    /*- 填写周期号 */
    CM_LongToChar(sysCyc, buf);
    i += 4;
    /*- @alias 填写输出报文的长度和crc */
    for (ch = 1; ch <= g_2x2oo2_data_num; ch++)
    {
    	if ((CM_UINT32)CM_TRUE == g_2x2oo2_tx[g_2x2oo2_base][ch].b_2oo2_Enable)
    	{
			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);
			CM_LongToChar(len, &buf[i]);
			i += 4;
			CM_LongToChar(crc, &buf[i]);
			i += 4;
    	}
    	else
    	{
    		/*二取标志未使能*/
    	}
    }
    /*二取表决加入硬重启标志*/
    buf[i++] = PFM_GetBoardRebootState();
    MSCP_LOG_MSG("PFM_GetBoardState = %d, PFM_GetBoardRebootState = %d\n",PFM_GetBoardState(), PFM_GetBoardRebootState());
    /*- 返回输出校验报文长度 */
    return i;
}
/**
* @brief 生成输出校验报文
* @param Buf 输出校验报文指针
* @param BufSize 输出校验报文缓冲区大小
* @return 输出校验报文长度
*/
static CM_INT32 s_2x2OutputCheckFrame_Pack(OUT CM_UINT8 *buf, IN CM_UINT32 BufSize)
{
    /*- 变量初始化 */
    CM_INT32 i = 0;       /* 循环变量 */
    CM_INT32 ch = 0;      /* 循环变量 */
    CM_UINT32 len = 0u;   /* 输出跟随报文长度 */
    CM_UINT32 crc = 0u;   /* 输出跟随报文CRC */
    CM_UINT32 sysCyc = SFM_2x2_GetSysCount(); /* 系统周期号 */
    /*- 入参检查*/
    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);

    /*- 填写周期号 */
    CM_LongToChar(sysCyc, buf);
    i += 4;
    /*- @alias 填写输出报文的长度和crc */
    for (ch = 1; ch <= g_2x2oo2_data_num; ch++)
    {
    	if ((CM_UINT32)CM_TRUE == g_2x2oo2_tx[g_2x2oo2_base][ch].b_2x2_Enable)
    	{
			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);
			CM_LongToChar(len, &buf[i]);
			i += 4;
			CM_LongToChar(crc, &buf[i]);
			i += 4;
    	}
    	else
    	{
    		/*二取标志未使能*/
    	}
    }
  
    /*- 返回输出校验报文长度 */
    return i;
}
/**
* @brief 接收外网透传报文
* @param rxBuf 收到的应用报文数组
* @param rxSize 接收应用报文的缓冲区（rxBuf）大小，应不小于可能收到的最长应用报文长度
* @return 收到的应用报文长度
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
*/
CM_UINT32 PFM_OutnetRaw_AppRecv(OUT CM_UINT8* rxBuf, IN CM_UINT32 rxSize)
{
    /*- 变量初始化 */
    CM_UINT32 msgLen = 0u; /* 消息长度 */
    CM_UINT32 rt = 0u;     /* 函数返回值 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    ENUM_2x2_STATE_T state_2x2 = SFM_2x2_GetLastPartner2x2State(); /*获取上周期对系热备状态*/
	g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].app_index_log++;/*记录应用调用次数，每周期清零*/
    CM_UINT8   *p_Mine_Buf  = NULL;
    CM_UINT32  Mine_len     = 0u;
    CM_UINT8   *p_Peer_Buf  = NULL;
    CM_UINT32  Peer_len     = 0u;
    CM_MUTEX_T *p_mutex     = NULL;
    /*根据主备状态分配缓冲区 */
    if(ENUM_2x2_MASTER != state_2x2)
    {
        p_Mine_Buf  = g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_mine_buf;
        Mine_len    = g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].mine_len;
        p_Peer_Buf  = g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_peer_buf;
        Peer_len    = g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].peer_len;
        p_mutex     = &g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].app_mutex;
    }
    else
    {
        p_Mine_Buf  = g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_rmt_mine_buf;
        Mine_len    = g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].rmt_mine_len;
        p_Peer_Buf  = g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_rmt_peer_buf;
        Peer_len    = g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].rmt_peer_len;
        p_mutex     = &g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].app_mutex;
    }
    /*- 入参检查 */
    CM_ASSERT(((NULL != rxBuf) && (NULL != p_Mine_Buf) && (NULL != p_Peer_Buf) && (NULL != p_mutex)) , IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_21);
    /*- 自己是否是CPU1 */
    if (1u == g_PFM_Cfg.CPU_ID)
    {
        /*- 本机通道是否有数据未取走 */
        if ((s_OutnetRaw_Mine_AppReadIndex + 4u) <= (CM_UINT32)Mine_len)
        {
            msgLen = CM_LongFromChar(p_Mine_Buf + s_OutnetRaw_Mine_AppReadIndex);
            CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1);
            CM_RE_ASSERT((s_OutnetRaw_Mine_AppReadIndex + 4u + msgLen) <= (CM_UINT32)Mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_2);
            CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_3);
            rt = msgLen;
            /*- 锁定接收通道 */
            ret = CM_Mutex_Lock(*p_mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_4);
            (void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_Mine_Buf + s_OutnetRaw_Mine_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
            /*- 解锁接收通道 */
            ret = CM_Mutex_Unlock(*p_mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_5);
            s_OutnetRaw_Mine_AppReadIndex += (CM_UINT32)msgLen + 4u;
        }
        /*- 邻机通道是否有数据未取走 */
        else if ((s_OutnetRaw_Peer_AppReadIndex + 4u) < (CM_UINT32)Peer_len)
        {
            msgLen = CM_LongFromChar(p_Peer_Buf + s_OutnetRaw_Peer_AppReadIndex);
            CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_6);
            CM_RE_ASSERT((s_OutnetRaw_Peer_AppReadIndex + 4u + msgLen) <= (CM_UINT32)Peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_7);
            CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_8);
            rt = msgLen;
            /*- 锁定接收通道 */
            ret = CM_Mutex_Lock(*p_mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_9);
            (void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_Peer_Buf + s_OutnetRaw_Peer_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
            /*- 解锁接收通道 */
            ret = CM_Mutex_Unlock(*p_mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_10);
            s_OutnetRaw_Peer_AppReadIndex += (CM_UINT32)msgLen + 4u;
        }
        else
        {
            /*- 双网都取完了，返回true */
        }

    }
    else
    {

        /*- 邻机通道是否有数据未取走 */
        if ((s_OutnetRaw_Peer_AppReadIndex + 4u) < (CM_UINT32)Peer_len)
        {
            msgLen = CM_LongFromChar(p_Peer_Buf + s_OutnetRaw_Peer_AppReadIndex);
            CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_11);
            CM_RE_ASSERT((s_OutnetRaw_Peer_AppReadIndex + 4u + msgLen) <= (CM_UINT32)Peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_12);
            CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_13);
            rt = msgLen;
            /*- 锁定接收通道 */
            ret = CM_Mutex_Lock(*p_mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_14);
            (void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_Peer_Buf + s_OutnetRaw_Peer_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
            /*- 解锁接收通道 */
            ret = CM_Mutex_Unlock(*p_mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_15);
            s_OutnetRaw_Peer_AppReadIndex += (CM_UINT32)msgLen + 4u;

        }
        /*- 本机通道是否有数据未取走 */
        else if ((s_OutnetRaw_Mine_AppReadIndex + 4u) <= (CM_UINT32)Mine_len)
        {
            msgLen = CM_LongFromChar(p_Mine_Buf + s_OutnetRaw_Mine_AppReadIndex);
            CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_16);
            CM_RE_ASSERT((s_OutnetRaw_Mine_AppReadIndex + 4u + msgLen) <= (CM_UINT32)Mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_17);
            CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_18);
            rt = msgLen;
            /*- 锁定接收通道 */
            ret = CM_Mutex_Lock(*p_mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_19);
            (void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_Mine_Buf + s_OutnetRaw_Mine_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
            /*- 解锁接收通道 */
            ret = CM_Mutex_Unlock(*p_mutex);
            CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_20);
            s_OutnetRaw_Mine_AppReadIndex += (CM_UINT32)msgLen + 4u;

        }
        else
        {
            /*- 双网都取完了，返回true */
        }
    }
    /*- 返回接收结果 */
    /* MSCP_LOG_MSG("PFM_OutnetRaw_AppRecv msgLen =%d\n",msgLen); */
	/* MSCP_LOG_MSG("PFM_OutnetRaw_AppRecv rt =%d\n",rt); */
    return rt;
}


/**
* @brief 发送外网透传报文
* @param txBuf 发送的应用报文数组
* @param txLen 发送的应用报文长度
* @return 函数执行结果
* - 1 成功
* - 0 失败(输入非法)
* @details
* 每次调用发送一条完整的应用报文
* 每周期可多次调用本函数从而发送多个应用报文，
* 注意总发送长度不要超过周期通信总量限制
*/
CM_UINT8 PFM_OutnetRaw_AppSend( IN const CM_UINT8* txBuf, IN CM_UINT32 txLen, IN CM_UINT16 dstName, IN CM_UINT16 dstLogicID, IN CM_UINT16 type)
{
    /*- 入口检查 */
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;
	CM_UINT32 sysCount = SFM_2x2_GetSysCount();  /* 周期号 */

	CM_ASSERT(0x55u == g_PFM_Cfg.M_OutnetRaw_Enable, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_1);
	CM_ASSERT(NULL != txBuf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_4);
	CM_RE_ASSERT(txLen <= NET_20K_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_2);
    /*- 写入外网透传数组 */
	/*CC外网输出帧
	2字节 长度
	1字节 协议版本
	4字节 周期号
	4字节帧序号
	2字节 目的设备id
	2字节 目的逻辑id
	2字节 协议类型
	n字节 数据
	4字节CRC
	*/
    CM_ShortToChar((CM_UINT16)(txLen + 19), g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf + g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len);
    g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf[g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len + 2] = 0u;                          /*协议版本 固定填0*/
    CM_LongToChar(sysCount, g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf + g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len + 3); /*填入周期号*/
    /* 此处空出4个字节的帧序号位置 ，发送的时候填充*/
    CM_LongToChar(0u, g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf + g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len + 7);
    CM_ShortToChar(dstName, g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf + g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len + 11); /* 填入目的ID*/
    CM_ShortToChar(dstLogicID, g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf + g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len + 13);
    CM_ShortToChar(type, g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf + g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len + 15);

    /*- 写入外网透传数组 */
    ret = CM_Memcpy((void*)(g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf + g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len + 17),
        (CM_SIZE_T)CM_UNSIGNED_INT_EXP(g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_size - (CM_UINT32)g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len - 17u),
        (const void*)(txBuf), (CM_SIZE_T)(txLen));
    CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_9, TSCP_DARK_ASSERT_3);
    CM_LongToChar(0u, g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].p_buf + g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len + txLen + 17);
    g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetRaw].buf_len += (CM_INT32)CM_UNSIGNED_INT_EXP(txLen+21u);

    /*- 返回执行结果 */

    return (CM_UINT8)ret;
}
/**
* @brief 接收内网透传报文
* @param ch 通道ID
* @param pSrcName 源设备ID
* @param rxBuf 收到的应用报文数组
* @param rxSize 接收应用报文的缓冲区（rxBuf）大小，应不小于可能收到的最长应用报文长度
* @return 收到的应用报文长度
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
*/
CM_UINT32 PFM_InnetRaw_AppRecv(IN CM_INT32 ch, OUT CM_UINT16* pSrcName, OUT CM_UINT8* rxBuf, IN CM_UINT32 rxSize)
{
    /*- 变量初始化 */
    CM_UINT32 msgLen = 0u; /* 消息长度 */
    CM_UINT32 rt = 0u;     /* 函数返回值 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
	APP_RAW_RX(ch).app_index_log++;/*记录应用调用次数，每周期清零*/
    /*- 入参检查 */
    CM_ASSERT(NULL != rxBuf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_17);
	/*- 自己是否是CPU1 */
	if (1u == g_PFM_Cfg.CPU_ID)
	{
		/*- 锁定接收通道 */
		ret = CM_Mutex_Lock(APP_RAW_RX(ch).app_mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_1);
		/*- 本机通道是否有数据未取走 */
		if ((s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE) <= (CM_UINT32)(APP_RAW_RX(ch).mine_len))
		{
			msgLen = CM_LongFromChar(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch]);
			CM_RE_ASSERT(msgLen >= PFM_RAW_DEVID_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_2);
			CM_RE_ASSERT((s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_LEN_SIZE + msgLen) <= (CM_UINT32)APP_RAW_RX(ch).mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_3);
			CM_RE_ASSERT((msgLen - PFM_RAW_DEVID_SIZE) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_4);
			rt = msgLen - PFM_RAW_DEVID_SIZE;
			*pSrcName = CM_ShortFromChar(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_LEN_SIZE);
			(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE), (CM_SIZE_T)CM_UNSIGNED_INT_EXP(msgLen - PFM_RAW_DEVID_SIZE));
			s_InnetRaw_Mine_AppReadIndex[ch] += (CM_UINT32)msgLen + PFM_RAW_LEN_SIZE;
		}
		/*- 邻机通道是否有数据未取走 */
		else if ((s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE) < (CM_UINT32)APP_RAW_RX(ch).peer_len)
		{
			msgLen = CM_LongFromChar(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch]);
			CM_RE_ASSERT(msgLen >= PFM_RAW_DEVID_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_5);
			CM_RE_ASSERT((s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_LEN_SIZE + msgLen) <= (CM_UINT32)APP_RAW_RX(ch).peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_6);
			CM_RE_ASSERT((msgLen - PFM_RAW_DEVID_SIZE) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_7);
			rt = msgLen - PFM_RAW_DEVID_SIZE;
			*pSrcName = CM_ShortFromChar(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_LEN_SIZE);
			(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE), (CM_SIZE_T)CM_UNSIGNED_INT_EXP(msgLen - PFM_RAW_DEVID_SIZE));
			s_InnetRaw_Peer_AppReadIndex[ch] += (CM_UINT32)msgLen + PFM_RAW_LEN_SIZE;
		}
		else
		{
			/*- 双网都取完了，返回true */
		}
		/*- 解锁接收通道 */
		ret = CM_Mutex_Unlock(APP_RAW_RX(ch).app_mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_8);
	}
	else
	{
		/*- 锁定接收通道 */
		ret = CM_Mutex_Lock(APP_RAW_RX(ch).app_mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_9);
		/*- 邻机通道是否有数据未取走 */
		if ((s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE) < (CM_UINT32)APP_RAW_RX(ch).peer_len)
		{
			msgLen = CM_LongFromChar(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch]);
			CM_RE_ASSERT(msgLen >= PFM_RAW_DEVID_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_10);
			CM_RE_ASSERT((s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_LEN_SIZE + msgLen) <= (CM_UINT32)APP_RAW_RX(ch).peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_11);
			CM_RE_ASSERT((msgLen - PFM_RAW_DEVID_SIZE) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_12);
			rt = msgLen - PFM_RAW_DEVID_SIZE;
			*pSrcName = CM_ShortFromChar(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_LEN_SIZE);
			(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE), (CM_SIZE_T)CM_UNSIGNED_INT_EXP(msgLen - PFM_RAW_DEVID_SIZE));
			s_InnetRaw_Peer_AppReadIndex[ch] += (CM_UINT32)msgLen + PFM_RAW_LEN_SIZE;
		}
		/*- 本机通道是否有数据未取走 */
		else if ((s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE) <= (CM_UINT32)(APP_RAW_RX(ch).mine_len))
		{
			msgLen = CM_LongFromChar(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch]);
			CM_RE_ASSERT(msgLen >= PFM_RAW_DEVID_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_13);
			CM_RE_ASSERT((s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_LEN_SIZE + msgLen) <= (CM_UINT32)APP_RAW_RX(ch).mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_14);
			CM_RE_ASSERT((msgLen - PFM_RAW_DEVID_SIZE) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_15);
			rt = msgLen - PFM_RAW_DEVID_SIZE;
			*pSrcName = CM_ShortFromChar(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_LEN_SIZE);
			(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE), (CM_SIZE_T)CM_UNSIGNED_INT_EXP(msgLen - PFM_RAW_DEVID_SIZE));
			s_InnetRaw_Mine_AppReadIndex[ch] += (CM_UINT32)msgLen + PFM_RAW_LEN_SIZE;
		}
		else
		{
			/*- 双网都取完了，返回true */
		}
		/*- 解锁接收通道 */
		ret = CM_Mutex_Unlock(APP_RAW_RX(ch).app_mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_10, TSCP_DARK_ASSERT_16);
	}

    /*- 返回接收结果 */
    return rt;
}
/**
* @brief 快速接收内网透传报文
* @param ch 通道ID
* @param pSrcName 源设备ID
* @param rxBuf 收到的应用报文数组二级指针
* @return 收到的应用报文长度
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
*/
CM_UINT32 PFM_InnetRaw_AppRecv_Fast(IN CM_INT32 ch, OUT CM_UINT16* pSrcName, OUT const CM_UINT8** rxBuf)
{
	/*- 变量初始化 */
	CM_UINT32 msgLen = 0u; /* 消息长度 */
	CM_UINT32 rt = 0u;     /* 函数返回值 */
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;
	APP_RAW_RX(ch).app_index_log++;/*记录应用调用次数，每周期清零*/
	/*- 入参检查 */
	CM_ASSERT(NULL != rxBuf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_13);
	/*- 自己是否是CPU1 */
	if (1u == g_PFM_Cfg.CPU_ID)
	{
		/*- 锁定接收通道 */
		ret = CM_Mutex_Lock(APP_RAW_RX(ch).app_mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
		/*- 本机通道是否有数据未取走 */
		if ((s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE) <= (CM_UINT32)(APP_RAW_RX(ch).mine_len))
		{
			msgLen = CM_LongFromChar(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch]);
			CM_RE_ASSERT(msgLen >= PFM_RAW_DEVID_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
			CM_RE_ASSERT((s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_LEN_SIZE + msgLen) <= (CM_UINT32)APP_RAW_RX(ch).mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_3);
			rt = msgLen - PFM_RAW_DEVID_SIZE;
			*pSrcName = CM_ShortFromChar(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_LEN_SIZE);
			rxBuf[0] = APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE;
			s_InnetRaw_Mine_AppReadIndex[ch] += (CM_UINT32)msgLen + PFM_RAW_LEN_SIZE;
		}
		/*- 邻机通道是否有数据未取走 */
		else if ((s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE) < (CM_UINT32)APP_RAW_RX(ch).peer_len)
		{
			msgLen = CM_LongFromChar(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch]);
			CM_RE_ASSERT(msgLen >= PFM_RAW_DEVID_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_4);
			CM_RE_ASSERT((s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_LEN_SIZE + msgLen) <= (CM_UINT32)APP_RAW_RX(ch).peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_5);
			rt = msgLen - PFM_RAW_DEVID_SIZE;
			*pSrcName = CM_ShortFromChar(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_LEN_SIZE);
			rxBuf[0] = APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE;
			s_InnetRaw_Peer_AppReadIndex[ch] += (CM_UINT32)msgLen + PFM_RAW_LEN_SIZE;
		}
		else
		{
			/*- 双网都取完了，返回true */
		}
		/*- 解锁接收通道 */
		ret = CM_Mutex_Unlock(APP_RAW_RX(ch).app_mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_6);
	}
	else
	{
		/*- 锁定接收通道 */
		ret = CM_Mutex_Lock(APP_RAW_RX(ch).app_mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_7);
		/*- 邻机通道是否有数据未取走 */
		if ((s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE) < (CM_UINT32)APP_RAW_RX(ch).peer_len)
		{
			msgLen = CM_LongFromChar(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch]);
			CM_RE_ASSERT(msgLen >= PFM_RAW_DEVID_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_8);
			CM_RE_ASSERT((s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_LEN_SIZE + msgLen) <= (CM_UINT32)APP_RAW_RX(ch).peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_9);
			rt = msgLen - PFM_RAW_DEVID_SIZE;
			*pSrcName = CM_ShortFromChar(APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_LEN_SIZE);
			rxBuf[0] = APP_RAW_RX(ch).p_peer_buf + s_InnetRaw_Peer_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE;
			s_InnetRaw_Peer_AppReadIndex[ch] += (CM_UINT32)msgLen + PFM_RAW_LEN_SIZE;
		}
		/*- 本机通道是否有数据未取走 */
		else if ((s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE) <= (CM_UINT32)(APP_RAW_RX(ch).mine_len))
		{
			msgLen = CM_LongFromChar(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch]);
			CM_RE_ASSERT(msgLen >= PFM_RAW_DEVID_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_10);
			CM_RE_ASSERT((s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_LEN_SIZE + msgLen) <= (CM_UINT32)APP_RAW_RX(ch).mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_11);
			rt = msgLen - PFM_RAW_DEVID_SIZE;
			*pSrcName = CM_ShortFromChar(APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_LEN_SIZE);
			rxBuf[0] = APP_RAW_RX(ch).p_mine_buf + s_InnetRaw_Mine_AppReadIndex[ch] + PFM_RAW_HEADER_SIZE;
			s_InnetRaw_Mine_AppReadIndex[ch] += (CM_UINT32)msgLen + PFM_RAW_LEN_SIZE;
		}
		else
		{
			/*- 双网都取完了，返回true */
		}
		/*- 解锁接收通道 */
		ret = CM_Mutex_Unlock(APP_RAW_RX(ch).app_mutex);
		CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_12);
	}

	/*- 返回接收结果 */
	return rt;
}
/**
* @brief 接收内网透传辅助信息
* @param ch 通道ID
* @param pSrcName 源设备ID
* @param rxBuf 收到的应用报文数组
* @param rxSize 接收应用报文的缓冲区（rxBuf）大小，应不小于可能收到的最长应用报文长度
* @return 收到的应用报文长度
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
*/
CM_UINT32 PFM_InnetRawHelpInfo_AppRecv(IN CM_INT32 ch, OUT CM_UINT8* MainInfoBuf,OUT CM_UINT8* PeerInfoBuf,IN CM_INT16 rxSize,OUT CM_UINT16 *PeerInfoLen)
{
	/*- 变量初始化 */
	CM_UINT32 msgLen = 0u; /* 消息长度 */
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;
	/*- 入参检查 */
	CM_ASSERT((NULL != MainInfoBuf) && (NULL != PeerInfoBuf) && (NULL != PeerInfoLen), IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_3);
	/*- 锁定接收通道 */
	ret = CM_Mutex_Lock(APP_RAW_RX(ch).app_mutex);
	CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_1);
	(void)CM_Memcpy(MainInfoBuf,(CM_SIZE_T)rxSize,APP_RAW_RX(ch).p_mine_helpinfo_buf,(CM_SIZE_T)APP_RAW_RX(ch).mine_helpinfo_len);
	msgLen = APP_RAW_RX(ch).mine_helpinfo_len;
	/*- 使能2取获取邻机数据，未使能2取获取本机数据*/
	if(0x55u == g_PFM_Cfg.M_2oo2_Enable)
	{
		(void)CM_Memcpy(PeerInfoBuf,(CM_SIZE_T)rxSize,APP_RAW_RX(ch).p_peer_helpinfo_buf,(CM_SIZE_T)APP_RAW_RX(ch).peer_helpinfo_len);
		*PeerInfoLen = (CM_UINT16)APP_RAW_RX(ch).peer_helpinfo_len;
	}
	else
	{
		(void)CM_Memcpy(PeerInfoBuf,(CM_SIZE_T)rxSize,APP_RAW_RX(ch).p_mine_helpinfo_buf,(CM_SIZE_T)APP_RAW_RX(ch).mine_helpinfo_len);
		*PeerInfoLen = (CM_UINT16)APP_RAW_RX(ch).mine_helpinfo_len;
	}
	/*- 解锁接收通道 */
	ret = CM_Mutex_Unlock(APP_RAW_RX(ch).app_mutex);
	CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_12, TSCP_DARK_ASSERT_2);
	return msgLen;
}
/**
* @brief 发送内网透传报文
* @param ch 通道ID
* @param dstName 目的设备ID
* @param txBuf 发送的应用报文数组
* @param txLen 发送的应用报文长度
* @return 函数执行结果
* - 1 成功
* - 0 失败(输入非法)
* @details
* 每次调用发送一条完整的应用报文
* 每周期可多次调用本函数从而发送多个应用报文，
* 注意总发送长度不要超过周期通信总量限制
*/
CM_UINT8 PFM_InnetRaw_AppSend(IN CM_INT32 ch, IN CM_UINT16 dstName, IN const CM_UINT8* txBuf, IN CM_UINT32 txLen)
{
    /*- 入口检查 */
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;
	CM_RE_ASSERT(txLen <= NET_20K_SIZE, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_1);
	CM_RE_ASSERT((txLen + 4u + (CM_UINT32)(APP_RAW_TX(ch).buf_len)) <= (CM_UINT32)(APP_RAW_TX(ch).buf_size), IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_2);
    CM_ASSERT(NULL != txBuf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_4);
    /*- 写入内网透传数组 */
    /*
     2字节 长度
     2字节 目的ID
     n字节 数据
     */
    CM_ShortToChar((CM_UINT16)(txLen + 2u), APP_RAW_TX(ch).p_buf + APP_RAW_TX(ch).buf_len);
    CM_ShortToChar(dstName, APP_RAW_TX(ch).p_buf + APP_RAW_TX(ch).buf_len + 2);
    ret = CM_Memcpy((void*)(APP_RAW_TX(ch).p_buf + APP_RAW_TX(ch).buf_len + 4),
        (CM_SIZE_T)CM_UNSIGNED_INT_EXP(APP_RAW_TX(ch).buf_size - (CM_UINT32)APP_RAW_TX(ch).buf_len - 4u),
        (const void*)(txBuf), (CM_SIZE_T)(txLen));
    CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_13, TSCP_DARK_ASSERT_3);
    APP_RAW_TX(ch).buf_len += (CM_INT32)CM_UNSIGNED_INT_EXP(txLen + 4u);		
    /*- 返回执行结果 */
    return (CM_UINT8)1u;
}

/**
* @brief 发送外网心跳报文
* @return 发送报文长度 取值范围：0~0x7FFFFFFF
* @details 仅限平台调用，不可对应用提供接口
*/
CM_INT32 PFM_OutnetHeart_Send(void)
{
    /*- 初始化变量 */
	ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    CM_UINT8 offset = 2u;
    CM_UINT8 buf[20] = {0};/*- 临时数组*/
    CM_UINT32 crc = 0u;
    STRU_2x2oo2_tx_T *p_2x2oo2_tx = &g_2x2oo2_tx[s_2x2oo2_app][s_2x2oo2_OutnetHeart];
    /*
		 2字节 长度
		 n字节 数据
     	 */
    /*- 写入外网心跳数组 */
    buf[offset++] = 0x06u;/* 请求类型*/
    buf[offset++] = SFM_2x2_GetLastLocal2x2State();
    CM_LongToChar(SFM_2x2_GetSysCount(), &buf[offset]);
    offset += 4u;
    crc = CM_Crc32(&buf[2u],offset-2u);/*- 此处不需防护，offset初始值就是2*/
    CM_LongToChar(crc, &buf[offset]);
    offset += 4u;
    /*- 填写数据长度*/
    CM_ShortToChar((CM_UINT16)(offset-2u), &buf[0u]);
    /* 总长度*/
    ret = CM_Memcpy((void*)p_2x2oo2_tx->p_buf,
        (CM_SIZE_T)CM_UNSIGNED_INT_EXP(p_2x2oo2_tx->buf_size),
        (const void*)(buf), (CM_SIZE_T)(offset));
    CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_16, TSCP_DARK_ASSERT_1);
    p_2x2oo2_tx->buf_len += (CM_INT32)CM_UNSIGNED_INT_EXP(offset);
    /*- 返回发送报文长度*/
    return p_2x2oo2_tx->buf_len;
}

/**
* @brief 接收外网心跳报文
* @param rxBuf 收到的应用报文数组 取值范围：非空
* @param rxSize 接收应用报文的缓冲区大小 取值范围：0~0xFFFFFFFF
* @return 收到的应用报文长度 取值范围：0~0xFFFFFFFF
* @details
* 每次调用获得一条完整的应用报文
* 每周期应持续调用本函数直到获得的报文长度 *pRxLen == 0
* 接收应用报文的缓冲区（rxBuf）大小，应不小于可能收到的最长应用报文长度
*/
CM_UINT32 PFM_OutnetHeart_AppRecv(OUT CM_UINT8* rxBuf, IN CM_UINT32 rxSize)
{
    /*- 变量初始化 */
    CM_UINT32 msgLen = 0u; /*- 消息长度 */
    CM_UINT32 rt = 0u;     /*- 函数返回值 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    STRU_2x2oo2_rx_T *p_2x2oo2_rx = &g_2x2oo2_rx[s_2x2oo2_app][s_2x2oo2_OutnetHeart];
	p_2x2oo2_rx->app_index_log++;/*-记录应用调用次数，每周期清零*/
    /*- 入参检查 */
    CM_ASSERT(NULL != rxBuf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_1);
    /*- 本系是否为主系 */
    if(ENUM_2x2_MASTER == SFM_2x2_GetLastLocal2x2State())
    {
		/*- 自己是否是CPU1 */
		if (1u == g_PFM_Cfg.CPU_ID)
		{
			/*- 本机通道是否有数据未取走 */
			if ((s_OutnetHeart_Mine_AppReadIndex + 4u) <= (CM_UINT32)(p_2x2oo2_rx->mine_len))
			{
				msgLen = CM_LongFromChar(p_2x2oo2_rx->p_mine_buf + s_OutnetHeart_Mine_AppReadIndex);
				CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_2);
				CM_RE_ASSERT((s_OutnetHeart_Mine_AppReadIndex + 4u + msgLen) <= (CM_UINT32)p_2x2oo2_rx->mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_3);
				CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_4);
				rt = msgLen;
				/*- 锁定接收通道 */
				ret = CM_Mutex_Lock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_5);
				/*- 拷贝数据到输出缓冲区 */
				(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_2x2oo2_rx->p_mine_buf + s_OutnetHeart_Mine_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
				/*- 解锁接收通道 */
				ret = CM_Mutex_Unlock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_6);
				s_OutnetHeart_Mine_AppReadIndex += (CM_UINT32)msgLen + 4u;
			}
			/*- 邻机通道是否有数据未取走 */
			else if ((s_OutnetHeart_Peer_AppReadIndex + 4u) < (CM_UINT32)p_2x2oo2_rx->peer_len)
			{
				msgLen = CM_LongFromChar(p_2x2oo2_rx->p_peer_buf + s_OutnetHeart_Peer_AppReadIndex);
				CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_7);
				CM_RE_ASSERT((s_OutnetHeart_Peer_AppReadIndex + 4u + msgLen) <= (CM_UINT32)p_2x2oo2_rx->peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_8);
				CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_9);
				rt = msgLen;
				/*- 锁定接收通道 */
				ret = CM_Mutex_Lock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_10);
				/*- 拷贝数据到输出缓冲区 */
				(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_2x2oo2_rx->p_peer_buf + s_OutnetHeart_Peer_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
				/*- 解锁接收通道 */
				ret = CM_Mutex_Unlock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_11);
				s_OutnetHeart_Peer_AppReadIndex += (CM_UINT32)msgLen + 4u;
			}
			else
			{
				/*- 双网都取完了，返回true */
				MSCP_LOG_MSG("Heart_AppRecv_MM_cpu:%d M_len:%d,P_len:%d\n",g_PFM_Cfg.CPU_ID,s_OutnetHeart_Mine_AppReadIndex,s_OutnetHeart_Peer_AppReadIndex);
			}
		}
		else
		{
			/*- 邻机通道是否有数据未取走 */
			if ((s_OutnetHeart_Peer_AppReadIndex + 4u) < (CM_UINT32)p_2x2oo2_rx->peer_len)
			{
				msgLen = CM_LongFromChar(p_2x2oo2_rx->p_peer_buf + s_OutnetHeart_Peer_AppReadIndex);
				CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_12);
				CM_RE_ASSERT((s_OutnetHeart_Peer_AppReadIndex + 4u + msgLen) <= (CM_UINT32)p_2x2oo2_rx->peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_13);
				CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_14);
				rt = msgLen;
				/*- 锁定接收通道 */
				ret = CM_Mutex_Lock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_15);
				/*- 拷贝数据到输出缓冲区 */
				(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_2x2oo2_rx->p_peer_buf + s_OutnetHeart_Peer_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
				/*- 解锁接收通道 */
				ret = CM_Mutex_Unlock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_16);
				s_OutnetHeart_Peer_AppReadIndex += (CM_UINT32)msgLen + 4u;
			}
			/*- 本机通道是否有数据未取走 */
			else if ((s_OutnetHeart_Mine_AppReadIndex + 4u) <= (CM_UINT32)(p_2x2oo2_rx->mine_len))
			{
				msgLen = CM_LongFromChar(p_2x2oo2_rx->p_mine_buf + s_OutnetHeart_Mine_AppReadIndex);
				CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_17);
				CM_RE_ASSERT((s_OutnetHeart_Mine_AppReadIndex + 4u + msgLen) <= (CM_UINT32)p_2x2oo2_rx->mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_18);
				CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_19);
				rt = msgLen;
				/*- 锁定接收通道 */
				ret = CM_Mutex_Lock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_20);
				/*- 拷贝数据到输出缓冲区 */
				(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_2x2oo2_rx->p_mine_buf + s_OutnetHeart_Mine_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
				/*- 解锁接收通道 */
				ret = CM_Mutex_Unlock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_21);
				s_OutnetHeart_Mine_AppReadIndex += (CM_UINT32)msgLen + 4u;
			}
			else
			{
				/*- 双网都取完了，返回true */
				MSCP_LOG_MSG("Heart_AppRecv_MM_cpu:%d M_len:%d,P_len:%d\n",g_PFM_Cfg.CPU_ID,s_OutnetHeart_Mine_AppReadIndex,s_OutnetHeart_Peer_AppReadIndex);
			}
		}
    }
    /*- 对系是否是主系 */
    else if(ENUM_2x2_MASTER == SFM_2x2_GetLastPartner2x2State())
    {
    	/*- 自己是否是CPU1 */
		if (1u == g_PFM_Cfg.CPU_ID)
		{
			/*- 本机通道是否有数据未取走 */
			if ((s_OutnetHeart_Mine_AppReadIndex + 4u) <= (CM_UINT32)(p_2x2oo2_rx->rmt_mine_len))
			{
				msgLen = CM_LongFromChar(p_2x2oo2_rx->p_rmt_mine_buf + s_OutnetHeart_Mine_AppReadIndex);
				CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_22);
				CM_RE_ASSERT((s_OutnetHeart_Mine_AppReadIndex + 4u + msgLen) <= (CM_UINT32)p_2x2oo2_rx->rmt_mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_23);
				CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_24);
				rt = msgLen;
				/*- 锁定接收通道 */
				ret = CM_Mutex_Lock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_25);
				/*- 拷贝数据到输出缓冲区 */
				(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_2x2oo2_rx->p_rmt_mine_buf + s_OutnetHeart_Mine_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
				/*- 解锁接收通道 */
				ret = CM_Mutex_Unlock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_26);
				s_OutnetHeart_Mine_AppReadIndex += (CM_UINT32)msgLen + 4u;
			}
			/*- 邻机通道是否有数据未取走 */
			else if ((s_OutnetHeart_Peer_AppReadIndex + 4u) < (CM_UINT32)p_2x2oo2_rx->rmt_peer_len)
			{
				msgLen = CM_LongFromChar(p_2x2oo2_rx->p_rmt_peer_buf + s_OutnetHeart_Peer_AppReadIndex);
				CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_27);
				CM_RE_ASSERT((s_OutnetHeart_Peer_AppReadIndex + 4u + msgLen) <= (CM_UINT32)p_2x2oo2_rx->rmt_peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_28);
				CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_29);
				rt = msgLen;
				/*- 锁定接收通道 */
				ret = CM_Mutex_Lock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_30);
				/*- 拷贝数据到输出缓冲区 */
				(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_2x2oo2_rx->p_rmt_peer_buf + s_OutnetHeart_Peer_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
				/*- 解锁接收通道 */
				ret = CM_Mutex_Unlock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_31);
				s_OutnetHeart_Peer_AppReadIndex += (CM_UINT32)msgLen + 4u;
			}
			else
			{
				/*- 双网都取完了，返回true */
				MSCP_LOG_MSG("Heart_AppRecv_PM_cpu:%d M_len:%d,P_len:%d\n",g_PFM_Cfg.CPU_ID,s_OutnetHeart_Mine_AppReadIndex,s_OutnetHeart_Peer_AppReadIndex);
			}
		}
		else
		{
			/*- 邻机通道是否有数据未取走 */
			if ((s_OutnetHeart_Peer_AppReadIndex + 4u) < (CM_UINT32)p_2x2oo2_rx->rmt_peer_len)
			{
				msgLen = CM_LongFromChar(p_2x2oo2_rx->p_rmt_peer_buf + s_OutnetHeart_Peer_AppReadIndex);
				CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_32);
				CM_RE_ASSERT((s_OutnetHeart_Peer_AppReadIndex + 4u + msgLen) <= (CM_UINT32)p_2x2oo2_rx->rmt_peer_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_33);
				CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_34);
				rt = msgLen;
				/*- 锁定接收通道 */
				ret = CM_Mutex_Lock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_35);
				/*- 拷贝数据到输出缓冲区 */
				(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_2x2oo2_rx->p_rmt_peer_buf + s_OutnetHeart_Peer_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
				/*- 解锁接收通道 */
				ret = CM_Mutex_Unlock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_36);
				s_OutnetHeart_Peer_AppReadIndex += (CM_UINT32)msgLen + 4u;
			}
			/*- 本机通道是否有数据未取走 */
			else if ((s_OutnetHeart_Mine_AppReadIndex + 4u) <= (CM_UINT32)(p_2x2oo2_rx->rmt_mine_len))
			{
				msgLen = CM_LongFromChar(p_2x2oo2_rx->p_rmt_mine_buf + s_OutnetHeart_Mine_AppReadIndex);
				CM_RE_ASSERT(msgLen > 0u, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_37);
				CM_RE_ASSERT((s_OutnetHeart_Mine_AppReadIndex + 4u + msgLen) <= (CM_UINT32)p_2x2oo2_rx->rmt_mine_len, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_38);
				CM_RE_ASSERT((msgLen) <= rxSize, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_39);
				rt = msgLen;
				/*- 锁定接收通道 */
				ret = CM_Mutex_Lock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_40);
				/*- 拷贝数据到输出缓冲区 */
				(void)CM_Memcpy((void*)rxBuf, (CM_SIZE_T)rxSize, (void*)(p_2x2oo2_rx->p_rmt_mine_buf + s_OutnetHeart_Mine_AppReadIndex + 4u), (CM_SIZE_T)(msgLen));
				/*- 解锁接收通道 */
				ret = CM_Mutex_Unlock(p_2x2oo2_rx->app_mutex);
				CM_RE_ASSERT(ENUM_CM_TRUE == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_17, TSCP_DARK_ASSERT_41);
				s_OutnetHeart_Mine_AppReadIndex += (CM_UINT32)msgLen + 4u;
			}
			else
			{
				/*- 双网都取完了，返回true */
				MSCP_LOG_MSG("Heart_AppRecv_PM_cpu:%d M_len:%d,P_len:%d\n",g_PFM_Cfg.CPU_ID,s_OutnetHeart_Mine_AppReadIndex,s_OutnetHeart_Peer_AppReadIndex);
			}
		}
    }
    else/*<	如果无主系 */
    {
    	/*-	无处理 */
    	MSCP_LOG_MSG("Heart_AppRecv Not Master\n");
    }

    /*- 返回接收结果 */
    return rt;
}
/**
* @brief 维护模式输入微周期处理(无宕机函数)
* @details
* 平台数据接收；
* 本地输入数据2oo2交换和比较；
* 交付协议适配层处理。
*/
void PFM_InputProc_Crash(void)
{
	CM_UINT8 data[1024*10] = {0u};
	CM_UINT8 pData[1024*10] = {0u};
	CM_UINT32 dataLen = 0u;
	CM_INT32 ret = 0;
    /************************平台数据接收*************************/
	g_PFM_Check = PFM_CFC_PROC_NUM + 2;
    /*- 内网安全数据接收 */
	dataLen = (CM_UINT32)SFM_RxInnetRemoteUpdate(data, sizeof(data));

    /*- 是否开启了2oo2功能 */
    if (0x55u == g_RMUP_Cfg.M_2oo2_Enable)
    {
        /*- 2oo2交换输出校验帧 */
        ret = SFM_2oo2_Exchange_FullDuplex_Crash(data, dataLen, pData, (CM_UINT32)1024u*10u, ENUM_2oo2_OUTPUT_EX);
    }
    else
    {
        /*- 无处理 */
    }
    g_PFM_Check = PFM_CFC_PROC_NUM + 3;
	MSCP_LOG_MSG("PFM_InputProc_Crash dataLen = %d\n",dataLen);
	if(2u == g_RMUP_Cfg.CPU_ID)
	{
		SFM_WriteInnetSafeRmInput(pData, ret, ENUM_INNET_GREEN);
		MSCP_LOG_DATALEN(pData, ret, "PFM_InputProc_Crash pData");
		SFM_WriteInnetSafeRmInput(data, dataLen, ENUM_INNET_PURPLE);
		MSCP_LOG_DATALEN(data, dataLen, "PFM_InputProc_Crash data");
	}
	else if(1u == g_RMUP_Cfg.CPU_ID)
	{
		SFM_WriteInnetSafeRmInput(data, dataLen, ENUM_INNET_GREEN);
		MSCP_LOG_DATALEN(data, dataLen, "PFM_InputProc_Crash data");
		SFM_WriteInnetSafeRmInput(pData, ret, ENUM_INNET_PURPLE);
		MSCP_LOG_DATALEN(pData, ret, "PFM_InputProc_Crash pData");
	}
	else
	{
		MSCP_LOG_MSG("Channel exception\n");
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_1));
	}
	g_PFM_Check = PFM_CFC_PROC_NUM + 4;
}

/**
* @brief 维护模式输出微周期处理(无宕机函数)
* @details
* 从协议适配层获取输出数据；
* 平台数据发送。
*/
void PFM_OutputProc_Crash(void)
{
    /*- 变量初始化 */
	CM_UINT8 data[1024*100] = {0u};
	CM_UINT32 dataLen = 0u;
	CM_UINT8 pData[1024*100] = {0u};
    CM_UINT32 ret = 0u;
    /*########################从协议适配层获取输出数据########################*/
    /*- 从协议适配层获取输出数据 */
	dataLen = SFM_ReadInnetCodedOutputCrash(data, sizeof(data));

    /*- 是否开启了2oo2功能 */
    if (0x55u == g_RMUP_Cfg.M_2oo2_Enable)
    {
        /*- 2oo2交换输出校验帧 */
        ret = SFM_2oo2_Exchange_FullDuplex_Crash(data, dataLen, pData, (CM_UINT32)1024u*100u, ENUM_2oo2_OUTPUT_EX);
        /*- 检查2oo2双机的输出校验帧是否一致 */
        CM_ASSERT_MAINTAIN(dataLen == ret);
        ret = CM_Memcmp(data, pData, (CM_SIZE_T)dataLen);

        CM_ASSERT_MAINTAIN(0u == ret);
    }
    else
    {
        /*- 无处理 */
    }

	/*- 发送内网安全输出数据 */
    SFM_TxInnetSafeRemoteUpdate(data, dataLen);
    MSCP_LOG_DATALEN(data, dataLen, "PFM_OutputProc_Crash data");
}


/**
* @brief 获取平台暂存的红蓝网设备信息
* @param RedBuf 红网缓冲区 取值范围:非空
* @param BlueBuf 篮网缓冲区 取值范围：非空
* @details RCI用于获取平台暂存的红蓝网设备信息
*/
void PFM_GetRciTempBuf(OUT CM_UINT16* RedBuf, OUT CM_UINT16* BlueBuf)
{
	/*- 入参是否非空 */
	if((RedBuf!=NULL) && (BlueBuf!=NULL))
	{
		/*- 红蓝网通信源设备信息 */
		(void)CM_Memcpy((void*)RedBuf,sizeof(CM_UINT16)*288u,s_rciRedTempBuf,sizeof(CM_UINT16)*288u);
		(void)CM_Memcpy((void*)BlueBuf,sizeof(CM_UINT16)*288u,s_rciBlueTempBuf,sizeof(CM_UINT16)*288u);
		(void)CM_Memset(s_rciRedTempBuf, 0u, sizeof(CM_UINT16)*288u, sizeof(CM_UINT16)*288u);
		(void)CM_Memset(s_rciBlueTempBuf, 0u, sizeof(CM_UINT16)*288u, sizeof(CM_UINT16)*288u);
		s_rciRedTempBufOffset = 0u;
		s_rciBlueTempBufOffset = 0u;
	}
	else
	{
		/*- 无处理 */
		(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_2));
		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};
    /*- 2oo2交换输出校验帧 */
    CM_ASSERT(NULL != check_2oo2_Buf, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_1);
    ret = SFM_2oo2_Exchange_Currency(check_2oo2_Buf, check_2oo2_Len, buf_peer, (CM_UINT32)check_2oo2_Len, ENUM_2oo2_OUTPUT_CHECK);

    /*- 检查2oo2双机的输出校验帧是否一致 */
    CM_RE_ASSERT(check_2oo2_Len == ret, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_2);
    ret = CM_Memcmp(check_2oo2_Buf, buf_peer, (CM_SIZE_T)check_2oo2_Len);
    if(0 != ret)
    {
        MSCP_LOG_DATALEN(check_2oo2_Buf,check_2oo2_Len,"Ouput check_2oo2_Buf");
        MSCP_LOG_DATALEN(buf_peer,check_2oo2_Len,"Ouput buf_peer");
        for (i = 1; i <= g_2x2oo2_data_num; i++)
        {
            if ((CM_UINT32)CM_TRUE == g_2x2oo2_tx[g_2x2oo2_base][i].b_2oo2_Enable)
            {
                ret = CM_Memcmp(check_2oo2_Buf + 4 + (i - 1) * 8, buf_peer + 4 + (i - 1) * 8, 8);
                if(ret != 0)
                {
                    MSCP_LOG_MSG("2oo2 output compare err, INDEX = %d, len = %d\n", i, (CM_SIZE_T)g_2x2oo2_tx[g_2x2oo2_base][i].buf_len);
                    MSCP_LOG_BIN(g_2x2oo2_tx[g_2x2oo2_base][i].p_buf, (CM_SIZE_T)g_2x2oo2_tx[g_2x2oo2_base][i].buf_len);
                }
            }
            else
            {
                /*二取标志未使能*/
            }
        }
        CM_RE_ASSERT(0, IN_OUT_MODE, DARK_FAULT_CODE_FUN_ORDER_15, TSCP_DARK_ASSERT_3);
    }
}

