仲裁版本开发,第一次提交,剩余状态转换功能

This commit is contained in:
lh
2026-08-19 19:47:55 +08:00
parent 6f48be84e9
commit c7c357249a
17 changed files with 2232 additions and 16 deletions
+4
View File
@@ -349,6 +349,7 @@ void APP_API_Data_Init()
.M_2oo2_Enable = 0x55, /**< 2oo2功能开关,开0x55,关0xAA */
.M_2x2_Enable = 0x55, /**< 2x2功能开关,开0x55,关0xAA*/
.M_4x2_Enable = 0x55, /**< 4x2功能开关,开0x55,关0xAA*/
.M_Arb_Enable = 0x55, /**< 仲裁功能开关 */
.M_2x2_Com_Cfg = 0x00, /**< 2x2通信功能配置,串口0x00,网卡0x01*/
.M_InnetSafe_Enable = 0x55, /**< 内网安全通信功能开关,开0x55,关0xAA */
.M_InnetRaw_Enable = 0x55, /**< 内网透传通信功能开关,开0x55,关0xAA */
@@ -529,6 +530,9 @@ void APP_API_Data_Init()
.INNET_COM_CFG[0].IP_P = (CM_UINT32)inet_addr("172.17.0.100"),/**< 紫网IP */
.INNET_COM_CFG[0].Port_Raw_P = 55003, /**< 紫网透传端口 */
.INNET_COM_CFG[0].Port_Safe_P = 55004, /**< 紫网安全端口 */
/*第三方仲裁通信配置*/
.Arb_CFG.IP_Arb_G = "10.3.1.200",
.Arb_CFG.IP_Arb_P = "10.4.1.200",
};
/*调用参数设置初始化接口*/
MSCP_Set_APP_ConfigData(&AppCfgInterface);
+832
View File
@@ -0,0 +1,832 @@
#include "Arb.h"
#include "Arb_Net.h"
#include "Arb_Pack.h"
#include "DFM_Time.h"
#include "CM_Memory.h"
#include "CM_CRC32.h"
#include "Area_2oo2.h"
#include "Arb_State.h"
#include "CFM_Sync.h"
/*===========↓↓↓↓↓全局变量声明&定义↓↓↓↓↓=============*/
STRU_AREA_WITH_ARB_CFG_ALL_T g_area_with_arb_cfg = {0};
/*===========↑↑↑↑↑全局变量声明&定义↑↑↑↑↑=============*/
/*===========↓↓↓↓↓宏定义↓↓↓↓↓=============*/
/**宏函数,支持不同帧结构体计算双CRC */
#define DOUBLE_CRC_GET(mypack, peerpack, tmp_buf, tmp_len) \
do { \
if (1 == AREA_BASIC_CFG_PTR->Cpuid) { \
(mypack).CRC1 = CM_Crc32_1(&(tmp_buf)[1], (tmp_len) - 9); \
} else { \
(mypack).CRC2 = CM_Crc32_2(&(tmp_buf)[1], (tmp_len) - 9); \
} \
\
tmp_len = Area_2oo2_Currency_NoSplit( \
&(mypack), sizeof(mypack), \
&(peerpack), sizeof(peerpack)); \
\
if (1 == AREA_BASIC_CFG_PTR->Cpuid) { \
(mypack).CRC2 = (peerpack).CRC2; \
} else { \
(mypack).CRC1 = (peerpack).CRC1; \
} \
} while (0)
/*===========↑↑↑↑↑宏定义↑↑↑↑↑=============*/
/*===========↓↓↓↓↓静态函数声明↓↓↓↓↓=============*/
/**
* @brief 区域工作线程(带仲裁)
*/
static CM_THREAD_FUNC_T s_Area_With_Arb_Work_Thread(IN CM_Thread_Arg_Struct_T* arg);
/**
* @brief 组播发送状态数据的处理
*/
static void s_Area_State_Multi_Process(void);
/**
* @brief 区域状态的请求发送处理
*/
static void s_Area_State_Req_Send_Process(void);
/**
* @brief 区域状态请求ACK的处理
*/
static void s_Area_State_Ack_Process(void);
/**
* @brief 区域状态的请求接收,发送ACK
*/
static void s_Area_State_Ack_Send_Process(void);
/**
* @brief 区域状态的应答ACK接收处理
*/
static void s_Area_State_Ack_Recv_Process(void);
/**
* @brief 仲裁处理
*/
static void s_Area_Arb_Process(void);
/**
* @brief 仲裁请求发送处理
*/
static void s_Area_Arb_Send_Process(void);
/**
* @brief 仲裁请求接收处理
*/
static void s_Area_Arb_Recv_Process(void);
/**
* @brief 状态转移处理
*/
static void s_Area_Arb_State_Transition(void);
/**
* @brief 主地主的组播发送状态数据处理
*/
static void s_Area_State_Multi_Send_Process(void);
/**
* @brief 非主地主接收组播状态数据处理
*/
static void s_Area_State_Multi_Recv_Process(void);
/**
* @brief 周期运行中的初始化,初始化接收状态和其他板卡状态
*/
static void s_Area_Cycle_Init(void);
/**
* @brief 根据ID设置接收状态
*/
static void s_Area_SetCommStatus_byID(CM_UINT8 ID, CM_UINT32 sn, CM_BOOL rcv_flag);
/**
* @brief 根据ID获取接收状态
*/
static void s_Area_GetCommStatus_byID(CM_UINT8 ID, CM_UINT32* SN, CM_UINT8* rcv_flag);
/**
* @brief 对接收到的区域状态请求进行2取同步
*/
static void s_Area_2oo2Sync_AfterStateRecv();
/**
* @brief 2取同步后,判断本周期是否收到请求,并进行回复组包发送
*/
static void s_Area_SendACK_After2oo2();
/*===========↑↑↑↑↑静态函数声明↑↑↑↑↑=============*/
/*===========↓↓↓↓↓函数定义↓↓↓↓↓↓=============*/
/**
* 区域初始化,包含第三方仲裁的初始化
*/
void Area_With_Arb_Init(void)
{
AREA_BASIC_CFG_PTR->BoardID = g_PFM_Cfg.BOARD_ID;/**< 板卡ID 插箱id */
AREA_BASIC_CFG_PTR->Cpuid = g_PFM_Cfg.CPU_ID;/**< cpu id */
AREA_BASIC_CFG_PTR->OutnetID = g_PFM_Cfg.BOARD_ID;/**< 外网ID */
/* 获取对系、对地板卡id*/
get_Other_BoardId(AREA_BASIC_CFG_PTR->BoardID, &(AREA_BASIC_CFG_PTR->Partner_BoardID), &(AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID), &(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID));
/* 网络初始化*/
Area_Arb_Net_Init();
/*信号量初始化*/
CM_Sem_Init(&(AREA_THREAD_CTRL_PTR->m_AreaWithArbStart));
CM_Sem_Init(&(AREA_THREAD_CTRL_PTR->m_AreaWithArbStop));
/**初始化板卡状态 */
AREA_STATE_CTRL_PTR->StateArea.Local_state = ENUM_AREA_UNKNOW;
s_Area_Cycle_Init();
/**创建区域工作线程 */
CM_Thread_Create(NULL, (CM_THREAD_FUNC_T)s_Area_With_Arb_Work_Thread, "Area_With_Arb_Work_Thread", 0, CM_TASK_PRIORITY_73, NULL);
}
/**
* @brief 区域工作线程(带仲裁)
*/
static CM_THREAD_FUNC_T s_Area_With_Arb_Work_Thread(IN CM_Thread_Arg_Struct_T* arg)
{
/* 绑定内核 */
void* pmask = NULL;
pmask = (void*)(0x01u|0x02u);
(void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
/* 情况缓冲区 */
Area_Arb_ClearMsgQ();
/* 线程循环 */
while(1)
{
Area_Arb_Wait_Start();
/**清空上周期的接收状态,并获取2乘线程中的最终状态 */
s_Area_Cycle_Init();
/**主地主组播发送状态帧,其余板卡接收 */
s_Area_State_Multi_Process();
/**主地双系/初始化阶段发送状态请求帧 */
s_Area_State_Req_Send_Process();
/**对应答帧的处理 */
s_Area_State_Ack_Process();
/**仲裁请求发送/接收的处理 */
s_Area_Arb_Process();
/**状态转移 */
s_Area_Arb_State_Transition();
Area_Arb_Stop();
}
return NULL;
}
/**
* @brief 区域开始
*
*/
void Area_Arb_Start()
{
/** 区域开始信号量 */
CM_Sem_Post(AREA_THREAD_CTRL_PTR->m_AreaWithArbStart);
AREA_LOG_MSG("*** Area Arb thread start \n");
}
/**
* @brief 等待区域开始
*
*/
void Area_Arb_Wait_Start()
{
/** 区域开始信号量 */
CM_Sem_Wait(AREA_THREAD_CTRL_PTR->m_AreaWithArbStart);
}
/**
* @brief 区域停止
*
*/
void Area_Arb_Stop()
{
/** 区域停止信号量 */
CM_Sem_Post(AREA_THREAD_CTRL_PTR->m_AreaWithArbStop);
}
/**
* @brief 等待区域停止
*
*/
void Area_Arb_Wait_Stop()
{
/** 区域停止信号量 */
CM_Sem_Wait(AREA_THREAD_CTRL_PTR->m_AreaWithArbStop);
}
/**
* @brief 组播发送状态数据的处理
*/
static void s_Area_State_Multi_Process(void)
{
if(ENUM_AREA_MASTER == AREA_STATE_CTRL_PTR->StateArea.Local_state &&
ENUM_2x2_MASTER == AREA_STATE_CTRL_PTR->State2x.LocalState)
{
/**主地主组播发送状态数据 */
s_Area_State_Multi_Send_Process();
CM_Sleep(10u);/*组播发送后等待10ms*/
}
else
{
/**非主地主接收组播状态数据 */
CM_Sleep(10u); /**等待10ms后接收组播数据 */
s_Area_State_Multi_Recv_Process();
}
}
/**
* @brief 区域状态的请求发送处理
*/
static void s_Area_State_Req_Send_Process(void)
{
STRU_AREA_WITH_ARB_STATE_PACK_T state_pack = {0}, peer_pack = {0};
CM_INT32 tmp_len = 0;
CM_UINT8 tmp_buf[1400] = {0u};
/**发送帧初始化 */
state_pack.Len = AREA_ARB_STATE_PACK_REAL_LEN - 1;
state_pack.MsgType = ENUM_AREA_MSG_STATE_REQ;
state_pack.SN = DFM_GetBirthCount();
state_pack.TimeSyncFlag = 1u; /**请求中的该字段不使用 */
state_pack.SrcID = AREA_BASIC_CFG_PTR->BoardID;
state_pack.StateArea = AREA_STATE_CTRL_PTR->StateArea.Local_state;
state_pack.State2x = AREA_STATE_CTRL_PTR->State2x.LocalState;
CM_Memset(&state_pack.Reserver[0], 0, AREA_ARB_RESERVER_LEN, AREA_ARB_RESERVER_LEN);
AREA_COMM_STATUS_PTR->LocalSN = DFM_GetBirthCount();
/**判断需要发送至哪一系 */
if(ENUM_AREA_UNKNOW == AREA_STATE_CTRL_PTR->StateArea.Local_state &&
ENUM_2x2_MASTER == AREA_STATE_CTRL_PTR->State2x.LocalState)
{
/**未知地主系,刚上电,向其他三系发送请求 */
/**发送至本地另一系 */
state_pack.DstID = AREA_BASIC_CFG_PTR->Partner_BoardID;
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
if(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len)
{
DOUBLE_CRC_GET(state_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
(void)Area_State_Send(AREA_BASIC_CFG_PTR->Partner_BoardID, &state_pack, sizeof(state_pack));
}
/**发送至另一地的A系 */
state_pack.DstID = AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID;
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
if(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len)
{
DOUBLE_CRC_GET(state_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID, &state_pack, sizeof(state_pack));
}
/**发送至另一地的B系 */
state_pack.DstID = AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID;
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
if(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len)
{
DOUBLE_CRC_GET(state_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID, &state_pack, sizeof(state_pack));
}
}
else if(ENUM_AREA_MASTER == AREA_STATE_CTRL_PTR->StateArea.Local_state &&
((ENUM_2x2_MASTER == AREA_STATE_CTRL_PTR->State2x.LocalState) || (ENUM_2x2_SLAVE == AREA_STATE_CTRL_PTR->State2x.LocalState)))
{
/**主地主备系,周期运行阶段,向另一地发送请求 */
/**发送至另一地的A系 */
state_pack.DstID = AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID;
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
if(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len)
{
DOUBLE_CRC_GET(state_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID, &state_pack, sizeof(state_pack));
}
/**发送至另一地的B系 */
state_pack.DstID = AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID;
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
if(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len)
{
DOUBLE_CRC_GET(state_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID, &state_pack, sizeof(state_pack));
}
}
else
{
}
}
/**
* @brief 区域状态请求ACK的处理
*/
static void s_Area_State_Ack_Process(void)
{
CM_UINT32 start_tick = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION);
CM_UINT32 used_time = 0u;
/**持续30ms */
do
{
/**接收请求进行回复发送 */
s_Area_State_Ack_Send_Process();
/**接收回复 */
s_Area_State_Ack_Recv_Process();
CM_Sleep(2u);
used_time = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION) - start_tick;
} while(used_time < 30000u);
}
/**
* @brief 区域状态的请求接收,发送ACK
*/
static void s_Area_State_Ack_Send_Process(void)
{
STRU_AREA_WITH_ARB_STATE_PACK_T state_pack = {0};
CM_UINT8 tmp_buf[1400] = {0};
CM_INT32 rcv_len = 0u;
CM_UINT32 crc1 = 0u, crc2 = 0u;
CM_UINT32 timeStamp = 0u, timeNow = 0u;
CM_UINT8 srcID = 0u, dstID = 0u;
/**接收请求 */
do
{
rcv_len = Area_State_Recv(&state_pack, sizeof(state_pack), &timeStamp);
timeNow = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION);
if(AREA_ARB_STATE_PACK_REAL_LEN == rcv_len &&
((timeNow - timeStamp) < g_PFM_Cfg.CYC_TIME))
{
/**接收到长度合法,并且接收时间合法 */
Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
crc1 = CM_Crc32_1(&tmp_buf[1], rcv_len - 9);
crc2 = CM_Crc32_2(&tmp_buf[1], rcv_len - 9);
srcID = state_pack.SrcID;
dstID = state_pack.DstID;
if(crc1 == state_pack.CRC1 && crc2 == state_pack.CRC2
&& dstID == AREA_BASIC_CFG_PTR->BoardID &&
ENUM_AREA_MSG_STATE_REQ == state_pack.MsgType)
{
/**CRC与目的ID校验通过*/
s_Area_SetCommStatus_byID(srcID, state_pack.SN, CM_TRUE);
Area_SetState_byID(srcID, state_pack.StateArea);
Area_Set2xState_byID(srcID, state_pack.State2x);
}
}
} while (0u < rcv_len);
/**进行2取同步 */
s_Area_2oo2Sync_AfterStateRecv();
/**进行ACK回复 */
s_Area_SendACK_After2oo2();
}
/**
* @brief 区域状态的应答ACK接收处理
*/
static void s_Area_State_Ack_Recv_Process(void)
{
STRU_AREA_WITH_ARB_STATE_PACK_T state_pack = {0};
CM_UINT8 tmp_buf[1400] = {0};
CM_INT32 rcv_len = 0u;
CM_UINT32 crc1 = 0u, crc2 = 0u;
CM_UINT32 timeStamp = 0u, timeNow = 0u;
CM_UINT8 srcID = 0u, dstID = 0u;
CM_UINT8 timeSyncFlag = CFM_GetTimeSyncFlag(); /**获取校时标志 */
CM_UINT32 localsn = AREA_COMM_STATUS_PTR->LocalSN;
do
{
rcv_len = Area_State_Recv(&state_pack, sizeof(state_pack), &timeStamp);
timeNow = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION);
if(AREA_ARB_STATE_PACK_REAL_LEN == rcv_len &&
((timeNow - timeStamp) < g_PFM_Cfg.CYC_TIME))
{
/**接收到长度合法,并且接收时间合法 */
Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
crc1 = CM_Crc32_1(&tmp_buf[1], rcv_len - 9);
crc2 = CM_Crc32_2(&tmp_buf[1], rcv_len - 9);
srcID = state_pack.SrcID;
dstID = state_pack.DstID;
if(crc1 == state_pack.CRC1 && crc2 == state_pack.CRC2
&& dstID == AREA_BASIC_CFG_PTR->BoardID &&
ENUM_AREA_MSG_STATE_ACK == state_pack.MsgType &&
(((1u == timeSyncFlag) && (state_pack.SN == localsn)) ||
((0u == timeSyncFlag) && (CM_ABS(localsn - state_pack.SN) <= 1))))
{
/**CRC与目的ID校验通过,并且是本周期接收到的回复(校时未完成时容忍一周期) */
s_Area_SetCommStatus_byID(srcID, state_pack.SN, CM_TRUE);
Area_SetState_byID(srcID, state_pack.StateArea);
Area_Set2xState_byID(srcID, state_pack.State2x);
}
}
} while (0u < rcv_len);
/**进行2取同步 */
s_Area_2oo2Sync_AfterStateRecv();
}
/**
* @brief 仲裁处理
*/
static void s_Area_Arb_Process(void)
{
s_Area_Arb_Send_Process();
/**等待20ms仲裁回复 */
CM_Sleep(20u);
s_Area_Arb_Recv_Process();
}
/**
* @brief 仲裁请求发送处理
*/
static void s_Area_Arb_Send_Process(void)
{
STRU_AREA_WITH_ARB_PACK_T arb_pack = {0}, peer_pack = {0};
CM_UINT32 tmp_len = 0u;
CM_UINT8 tmp_buf[1400] = 0u;
ENUM_AREA_STATE local_area_state = AREA_STATE_CTRL_PTR->StateArea.Local_state;
CM_UINT32 tolerate_arb = 0u; /**仲裁请求容忍 */
/**请求帧帧基础信息组包 */
arb_pack.Len = AREA_ARB_FRAME_PACK_REAL_LEN - 1u;
arb_pack.MsgType = ENUM_AREA_MSG_ARB_REQ;
arb_pack.ArbSN = DFM_GetBirthCount();
arb_pack.OutNet_ID = AREA_BASIC_CFG_PTR->OutnetID;
arb_pack.Board_ID = AREA_BASIC_CFG_PTR->BoardID;
arb_pack.ArbPayLoad = 0x55u; /**请求升主 */
CM_Memset(&arb_pack.Reserver[0], 0, AREA_ARB_RESERVER_LEN, AREA_ARB_RESERVER_LEN);
/**计算双CRC */
DOUBLE_CRC_GET(arb_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_FRAME_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
/**获取对应状态的板卡ID */
CM_UINT8 id_sm = Area_GetID_byState(ENUM_AREA_SLAVE, ENUM_2x2_MASTER); /**备地主的板卡ID */
CM_UINT8 id_mm = Area_GetID_byState(ENUM_AREA_MASTER, ENUM_2x2_MASTER); /**主地主的板卡ID */
/**获取通信中断标志 */
CM_UINT8 flag_comm_all_down = AREA_COMM_STATUS_PTR->Patner_RcvFlag | AREA_COMM_STATUS_PTR->Area_A_RcvFlag | AREA_COMM_STATUS_PTR->Area_B_RcvFlag;
/**判断是否发送仲裁请求 */
if(ENUM_2x2_MASTER == AREA_STATE_CTRL_PTR->State2x.LocalState)
{
/**主系判断是否发送仲裁请求 */
if(ENUM_AREA_MASTER == local_area_state && 0u == id_sm)
{
/**本地主地主,与备地主通信中断,发送仲裁请求 */
Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack));
}
else if(ENUM_AREA_SLAVE == local_area_state && 0u == id_mm)
{
/**本地备地主,与主地主通信中断,容忍一周期发送请求 */
if(tolerate_arb >= 1u)
{
Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack));
tolerate_arb = 0u;
}
else
{
tolerate_arb++;
}
}
else if(ENUM_AREA_UNKNOW == local_area_state && CM_FALSE == flag_comm_all_down)
{
/**未知地主系,与其他三系通信持续中断10周期,发送仲裁请求 */
if(tolerate_arb >= 10u)
{
Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack));
tolerate_arb = 0u;
}
else
{
tolerate_arb++;
}
}
else
{
/**不具备发送仲裁请求的条件,清空容忍次数 */
tolerate_arb = 0u;
}
}
else
{
/**非主系不能要仲裁 */
}
}
/**
* @brief 仲裁请求接收处理
*/
static void s_Area_Arb_Recv_Process(void)
{
STRU_AREA_WITH_ARB_PACK_T arb_pack = {0};
CM_INT32 rcv_len = 0;
CM_UINT8 tmp_buf[1400] = {0};
CM_UINT32 crc1 = 0u, crc2 = 0u;
CM_UINT32 local_sn = DFM_GetBirthCount();
CM_UINT16 local_outnetid = AREA_BASIC_CFG_PTR->OutnetID;
CM_UINT8 local_id = AREA_BASIC_CFG_PTR->BoardID;
/**清空仲裁状态 */
AREA_ARB_CTRL_PTR->Arb_Ack = 0x00u;
/**仲裁请求接收 */
rcv_len = Area_Arb_Ack_Recv(&arb_pack, sizeof(arb_pack));
/**解包处理 */
if(AREA_ARB_FRAME_PACK_REAL_LEN == rcv_len &&
((AREA_ARB_FRAME_PACK_REAL_LEN - 1) == arb_pack.Len))
{
rcv_len = Area_Arb_Frame_Pack(tmp_buf, sizeof(tmp_buf), &arb_pack);
crc1 = CM_Crc32_1(&tmp_buf[1], rcv_len - 9);
crc2 = CM_Crc32_2(&tmp_buf[1], rcv_len - 9);
if(crc1 == arb_pack.CRC1 && crc2 == arb_pack.CRC2 &&
local_sn == arb_pack.ArbSN && ENUM_AREA_MSG_ARB_ACK == arb_pack.MsgType &&
local_outnetid == arb_pack.OutNet_ID && local_id == arb_pack.Board_ID)
{
if(0x55 == arb_pack.ArbPayLoad)
{
/**允许升主 */
AREA_ARB_CTRL_PTR->Arb_Ack = 0x55u;
}
}
}
}
/**
* @brief 状态转移处理
*/
static void s_Area_Arb_State_Transition(void)
{
}
/**
* @brief 主地主的组播发送状态数据处理
*/
static void s_Area_State_Multi_Send_Process(void)
{
CM_UINT8 tmp_buf[1400]; /**< 临时缓冲区 */
CM_INT32 tmp_len = 0; /**< 临时数据长度 */
STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T multi_pack = {0}, peer_pack = {0}; /**< 待发送数据结构体 */
/** 填充结构体 */
multi_pack.Len = AREA_ARB_STATE_MULTI_PACK_REAL_LEN - 1;
multi_pack.MsgType = ENUM_AREA_MSG_STATE_MULTI;
multi_pack.SN = DFM_GetBirthCount();
multi_pack.SrcID = AREA_BASIC_CFG_PTR->BoardID;
multi_pack.StateArea = AREA_STATE_CTRL_PTR->StateArea.Local_state;
multi_pack.State2x = AREA_STATE_CTRL_PTR->State2x.LocalState;
CM_Memset(&multi_pack.Reserver[0], 0, AREA_ARB_RESERVER_LEN, AREA_ARB_RESERVER_LEN);
/**计算CRC */
tmp_len = Area_Arb_State_Multi_Pack(tmp_buf, sizeof(tmp_buf), &multi_pack);
if(AREA_ARB_STATE_MULTI_PACK_REAL_LEN == tmp_len)
{
DOUBLE_CRC_GET(multi_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
/**组播发送 */
Area_State_Multi_Send(&multi_pack, sizeof(multi_pack));
}
}
/**
* @brief 非主地主接收组播状态数据处理
*/
static void s_Area_State_Multi_Recv_Process(void)
{
CM_UINT32 crc1 = 0u, crc2 = 0u;
CM_UINT8 tmp_buf[1400] = {0u};
CM_INT32 tmp_len = 0;
STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T multi_pack = {0}; /**状态组播帧数据结构体 */
CM_UINT32 tickNow = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION);
CM_UINT32 tickRcv = 0u;
/*组播接收*/
tmp_len = Area_State_Multi_Recv(&multi_pack, sizeof(multi_pack), &tickRcv);
/*双CRC校验*/
tmp_len = Area_Arb_State_Multi_Pack(tmp_buf, sizeof(tmp_buf), &multi_pack);
if(AREA_ARB_STATE_MULTI_PACK_REAL_LEN == tmp_len &&
((tickNow - tickRcv) < g_PFM_Cfg.CYC_TIME))
{
crc1 = CM_Crc32_1(&tmp_buf[1], tmp_len - 9);
crc2 = CM_Crc32_2(&tmp_buf[1], tmp_len - 9);
if(crc1 == multi_pack.CRC1 && crc2 == multi_pack.CRC2 &&
ENUM_AREA_MSG_STATE_MULTI == multi_pack.MsgType)
{
s_Area_SetCommStatus_byID(multi_pack.SrcID, multi_pack.SN, CM_TRUE);
Area_SetState_byID(multi_pack.SrcID, multi_pack.StateArea);
Area_Set2xState_byID(multi_pack.SrcID, multi_pack.State2x);
}
else
{
AREA_LOG_MSG("Multi Recv Crc Fail %08x-%08x, %08x-%08x\n",crc1, multi_pack.CRC1, crc2, multi_pack.CRC2);
}
}
}
/**
* @brief 周期运行中的初始化,初始化接收状态和其他板卡状态
*/
static void s_Area_Cycle_Init(void)
{
/**每周期都要初始化其他板卡的地状态 */
AREA_STATE_CTRL_PTR->StateArea.Partner_state = ENUM_AREA_SHUTDOWN;
AREA_STATE_CTRL_PTR->StateArea.Partner_Area_A_state = ENUM_AREA_SHUTDOWN;
AREA_STATE_CTRL_PTR->StateArea.Partner_Area_B_state = ENUM_AREA_SHUTDOWN;
/**初始化另一地的两系2乘状态 */
AREA_STATE_CTRL_PTR->State2x.Area_A_State = ENUM_2x2_SHUTDOWN;
AREA_STATE_CTRL_PTR->State2x.Area_B_State = ENUM_2x2_SHUTDOWN;
/**从2乘线程获取地内的系状态 */
SFM_2x2_GetStateAfterStateChange(&(AREA_STATE_CTRL_PTR->State2x.LocalState), &(AREA_STATE_CTRL_PTR->State2x.PartnerState));
if(ENUM_2x2_OFFLINE == AREA_STATE_CTRL_PTR->State2x.LocalState &&
((ENUM_AREA_MASTER == AREA_STATE_CTRL_PTR->StateArea.Local_state) || (ENUM_AREA_SLAVE == AREA_STATE_CTRL_PTR->StateArea.Local_state)))
{
/**2乘离线系,置自己为离线地 */
AREA_STATE_CTRL_PTR->StateArea.Local_state = ENUM_AREA_OFFLINE;
}
/**每周期初始化接收标志 */
AREA_COMM_STATUS_PTR->Patner_RcvFlag = CM_FALSE;
AREA_COMM_STATUS_PTR->Area_A_RcvFlag = CM_FALSE;
AREA_COMM_STATUS_PTR->Area_B_RcvFlag = CM_FALSE;
}
/**
* @brief 根据ID设置接收状态
*/
static void s_Area_SetCommStatus_byID(CM_UINT8 ID, CM_UINT32 sn, CM_BOOL rcv_flag)
{
if(ID == AREA_BASIC_CFG_PTR->BoardID)
{
AREA_COMM_STATUS_PTR->LocalSN = sn;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_BoardID)
{
AREA_COMM_STATUS_PTR->PatnerSN = sn;
AREA_COMM_STATUS_PTR->Patner_RcvFlag = rcv_flag;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID)
{
AREA_COMM_STATUS_PTR->Area_A_SN = sn;
AREA_COMM_STATUS_PTR->Area_A_RcvFlag = rcv_flag;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID)
{
AREA_COMM_STATUS_PTR->Area_B_SN = sn;
AREA_COMM_STATUS_PTR->Area_B_RcvFlag = rcv_flag;
}
else
{
AREA_LOG_MSG("Cant Find ID:%d\n", ID);
}
}
/**
* @brief 根据ID获取接收状态
*/
static void s_Area_GetCommStatus_byID(CM_UINT8 ID, CM_UINT32* sn, CM_UINT8* rcv_flag)
{
CM_UINT32 sn = 0u;
if(ID == AREA_BASIC_CFG_PTR->BoardID)
{
if(NULL != sn)
{
*sn = AREA_COMM_STATUS_PTR->LocalSN;
}
if(NULL != rcv_flag)
{
*rcv_flag = CM_TRUE;
}
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_BoardID)
{
if(NULL != sn)
{
*sn = AREA_COMM_STATUS_PTR->PatnerSN;
}
if(NULL != rcv_flag)
{
*rcv_flag = AREA_COMM_STATUS_PTR->Patner_RcvFlag;
}
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID)
{
if(NULL != sn)
{
*sn = AREA_COMM_STATUS_PTR->Area_A_SN;
}
if(NULL != rcv_flag)
{
*rcv_flag = AREA_COMM_STATUS_PTR->Area_A_RcvFlag;
}
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID)
{
if(NULL != sn)
{
*sn = AREA_COMM_STATUS_PTR->Area_B_SN;
}
if(NULL != rcv_flag)
{
*rcv_flag = AREA_COMM_STATUS_PTR->Area_B_RcvFlag;
}
}
else
{
AREA_LOG_MSG("Cant Find ID:%d\n", ID);
}
return sn;
}
/**
* @brief 对接收到的区域状态请求进行2取同步
*/
static void s_Area_2oo2Sync_AfterStateRecv()
{
STRU_AREA_WITH_ARB_COMM_STATUS_T peer_comm_status = {0};
STRU_AREA_WITH_ARB_STATE_CTRL_T peer_state_ctrl = {0};
CM_UINT32 len_comm_status = sizeof(STRU_AREA_WITH_ARB_COMM_STATUS_T);
CM_UINT32 len_state_ctrl = sizeof(STRU_AREA_WITH_ARB_STATE_CTRL_T);
CM_UINT8 send_buf [1400] = {0}, rcv_buf[1400];
CM_INT32 send_len = 0u, rcv_len = 0u;
/**将接收状态进行组包2取 */
if(sizeof(send_buf) >= (len_comm_status + len_state_ctrl))
{
CM_Memcpy(send_buf, sizeof(send_buf), AREA_COMM_STATUS_PTR, len_comm_status);
send_len += len_comm_status;
CM_Memcpy(&send_buf[send_len], sizeof(send_buf) - send_len, AREA_STATE_CTRL_PTR, len_state_ctrl);
send_len += len_state_ctrl;
}
rcv_len = Area_2oo2_Currency_NoSplit(send_buf, send_len, rcv_buf, sizeof(rcv_buf));
CM_ASSERT(rcv_len == send_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
/**对另一CPU数据解析 */
CM_Memcpy(&peer_comm_status, len_comm_status,send_buf, len_comm_status);
CM_Memcpy(&peer_state_ctrl, len_state_ctrl,send_buf + len_comm_status, len_state_ctrl);
/**更新对系的接收序列号 */
if(AREA_COMM_STATUS_PTR->PatnerSN < peer_comm_status.PatnerSN && CM_TRUE == peer_comm_status.Patner_RcvFlag)
{
/**接收到的对系序列号不同,本CPU为旧数据,同步新数据 */
AREA_COMM_STATUS_PTR->PatnerSN = peer_comm_status.PatnerSN;
AREA_COMM_STATUS_PTR->Patner_RcvFlag = peer_comm_status.Patner_RcvFlag;
AREA_STATE_CTRL_PTR->StateArea.Partner_state = peer_state_ctrl.StateArea.Partner_state;
AREA_STATE_CTRL_PTR->State2x.PartnerState = peer_state_ctrl.State2x.PartnerState;
}
else
{
/**接收到的对系序列号相同,或者本CPU为新数据,无操作*/
}
/**更新另一地A系的接收序列号 */
if(AREA_COMM_STATUS_PTR->Area_A_SN < peer_comm_status.Area_A_SN && CM_TRUE == peer_comm_status.Area_A_RcvFlag)
{
/**接收到的对系序列号不同,本CPU为旧数据,同步新数据 */
AREA_COMM_STATUS_PTR->Area_A_SN = peer_comm_status.Area_A_SN;
AREA_COMM_STATUS_PTR->Area_A_RcvFlag = peer_comm_status.Area_A_RcvFlag;
AREA_STATE_CTRL_PTR->StateArea.Partner_Area_A_state = peer_state_ctrl.StateArea.Partner_Area_A_state;
AREA_STATE_CTRL_PTR->State2x.Area_A_State = peer_state_ctrl.State2x.Area_A_State;
}
else
{
/**接收到的对系序列号相同,或者本CPU为新数据,无操作*/
}
/**更新另一地B系的接收序列号 */
if(AREA_COMM_STATUS_PTR->Area_B_SN < peer_comm_status.Area_B_SN && CM_TRUE == peer_comm_status.Area_B_RcvFlag)
{
/**接收到的对系序列号不同,本CPU为旧数据,同步新数据 */
AREA_COMM_STATUS_PTR->Area_B_SN = peer_comm_status.Area_B_SN;
AREA_COMM_STATUS_PTR->Area_B_RcvFlag = peer_comm_status.Area_B_RcvFlag;
AREA_STATE_CTRL_PTR->StateArea.Partner_Area_B_state = peer_state_ctrl.StateArea.Partner_Area_B_state;
AREA_STATE_CTRL_PTR->State2x.Area_B_State = peer_state_ctrl.State2x.Area_B_State;
}
else
{
/**接收到的对系序列号相同,或者本CPU为新数据,无操作*/
}
}
/**
* @brief 2取同步后,判断本周期是否收到请求,并进行回复组包发送
*/
static void s_Area_SendACK_After2oo2()
{
STRU_AREA_WITH_ARB_STATE_PACK_T state_pack = {0}, peer_pack = {0};
CM_UINT8 tmp_buf[1400] = {0};
CM_INT32 tmp_len = 0;
/**发送帧初始化 */
state_pack.Len = AREA_ARB_STATE_PACK_REAL_LEN - 1;
state_pack.MsgType = ENUM_AREA_MSG_STATE_ACK;
state_pack.TimeSyncFlag = CFM_GetTimeSyncFlag(); /**获取校时标志 */
state_pack.SrcID = AREA_BASIC_CFG_PTR->BoardID;
state_pack.StateArea = AREA_STATE_CTRL_PTR->StateArea.Local_state;
state_pack.State2x = AREA_STATE_CTRL_PTR->State2x.LocalState;
CM_Memset(&state_pack.Reserver[0], 0, AREA_ARB_RESERVER_LEN, AREA_ARB_RESERVER_LEN);
/**判断请求的接收情况 */
if(CM_TRUE == AREA_COMM_STATUS_PTR->Patner_RcvFlag)
{
/**接收到了对系的请求,组包回复 */
state_pack.DstID = AREA_BASIC_CFG_PTR->Partner_BoardID;
state_pack.SN = AREA_COMM_STATUS_PTR->PatnerSN;
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
DOUBLE_CRC_GET(state_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID, &state_pack, sizeof(state_pack));
}
if(CM_TRUE == AREA_COMM_STATUS_PTR->Area_A_RcvFlag)
{
/**接收到了另一地A系的请求,组包回复 */
state_pack.DstID = AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID;
state_pack.SN = AREA_COMM_STATUS_PTR->Area_A_SN;
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
DOUBLE_CRC_GET(state_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID, &state_pack, sizeof(state_pack));
}
if(CM_TRUE == AREA_COMM_STATUS_PTR->Area_B_RcvFlag)
{
/**接收到了另一地A系的请求,组包回复 */
state_pack.DstID = AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID;
state_pack.SN = AREA_COMM_STATUS_PTR->Area_B_SN;
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
DOUBLE_CRC_GET(state_pack, peer_pack, tmp_buf, tmp_len);
CM_ASSERT(AREA_ARB_STATE_PACK_REAL_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID, &state_pack, sizeof(state_pack));
}
}
+115
View File
@@ -0,0 +1,115 @@
#ifndef AREA_H_
#define AREA_H_
#include "Area.h"
#include "Area_Net.h"
#include "Arb_Net.h"
#include "SFM_2x2.h"
#define AREA_BASIC_CFG_PTR (&g_area_with_arb_cfg.Basic_CFG) /**< 仲裁模式下使用,区域模块的基本配置(ID) */
#define AREA_THREAD_CTRL_PTR (&g_area_with_arb_cfg.Thread_CTRL) /**< 仲裁模式下使用,区域模块的线程控制(信号量) */
#define AREA_STATE_CTRL_PTR (&g_area_with_arb_cfg.State_CTRL) /**< 仲裁模式下使用,区域模块的状态控制 */
#define AREA_COMM_STATUS_PTR (&g_area_with_arb_cfg.Comm_Status) /**< 仲裁模式下使用,区域模块的通信状态记录 */
#define AREA_ARB_CTRL_PTR (&g_area_with_arb_cfg.Arb_CTRL) /**< 仲裁模式下使用,区域模块的仲裁控制 */
/*仲裁模式下,区域间所有通信相关配置*/
typedef struct
{
STR_Area_IP_Cfg COMM_CFG_AREA;
STRU_ARB_COMM_CFG_T COMM_CFG_ARB;
STRU_AREA_MULTICAST_COMM_T COMM_CFG_AREA_MULTICAST;
}STRU_AREA_WITH_ARB_COMM_CFG_T;
/*仲裁模式下,区域间通信状态记录(接收到的SN号/周期号) */
typedef struct
{
CM_UINT32 LocalSN; /**< 本地周期号 */
CM_UINT32 PatnerSN; /**< 接收的对系周期号 */
CM_BOOL Patner_RcvFlag; /**< 本周期是否接收到了对系的数据包,CM_TRUE接收到,CM_FALSE未接收到 */
CM_UINT32 Area_A_SN; /**< 接收的另一地A系周期号 */
CM_BOOL Area_A_RcvFlag; /**< 本周期是否接收到了另一地A系的数据包,CM_TRUE接收到,CM_FALSE未接收到 */
CM_UINT32 Area_B_SN; /**< 接收的另一地B系周期号 */
CM_BOOL Area_B_RcvFlag; /**< 本周期是否接收到了另一地B系的数据包,CM_TRUE接收到,CM_FALSE未接收到 */
}STRU_AREA_WITH_ARB_COMM_STATUS_T;
/*仲裁模式下,记录仲裁的回复*/
typedef struct
{
CM_UINT8 Arb_Ack; /**< 记录仲裁的回复 */
}STRU_AREA_WITH_ARB_REQ_T;
/*仲裁模式下,区域线程控制*/
typedef struct
{
CM_SEM_T m_AreaWithArbStart;
CM_SEM_T m_AreaWithArbStop;
}STRU_AREA_WITH_ARB_THREAD_CTRL_T;
/*仲裁模式下,区域间所有的基础配置(ID)*/
typedef struct
{
CM_UINT8 BoardID; /**< 板卡ID 插箱id */
CM_UINT8 Cpuid; /**< cpu id */
CM_UINT8 Partner_BoardID; /**< 对系板卡id */
CM_UINT8 Partner_Area_A_BoardID; /**< 对系id */
CM_UINT8 Partner_Area_B_BoardID; /**< 对系id */
CM_UINT16 OutnetID; /**<外网ID */
}STRU_AREA_WITH_ARB_BASIC_CFG_T;
/*仲裁模式下,记录2乘状态结构体*/
typedef struct
{
ENUM_2x2_STATE_T LocalState; /**< 本系2x状态*/
ENUM_2x2_STATE_T PartnerState; /**< 对系2x状态 */
ENUM_2x2_STATE_T Area_A_State; /**< 另一地A系2x状态 */
ENUM_2x2_STATE_T Area_B_State; /**< 另一地B系2x状态 */
}STRU_AREA_2X_STATE_T;
/*仲裁模式下,区域状态控制结构体*/
typedef struct
{
STR_Area_State StateArea; /**< 区域状态汇总 */
STRU_AREA_2X_STATE_T State2x; /**< 2x状态汇总 */
}STRU_AREA_WITH_ARB_STATE_CTRL_T;
/**仲裁模式下,区域模块的所有配置与控制汇总 */
typedef struct
{
STRU_AREA_WITH_ARB_BASIC_CFG_T Basic_CFG; /**< 基础配置(ID) */
STRU_AREA_WITH_ARB_COMM_CFG_T COMM_CFG; /**< 通信配置 */
STRU_AREA_WITH_ARB_THREAD_CTRL_T Thread_CTRL; /**< 线程状态控制 */
STRU_AREA_WITH_ARB_STATE_CTRL_T State_CTRL; /**<状态控制 */
STRU_AREA_WITH_ARB_COMM_STATUS_T Comm_Status; /**<通信状态记录 */
STRU_AREA_WITH_ARB_REQ_T Arb_CTRL; /**< 与仲裁的交互 */
}STRU_AREA_WITH_ARB_CFG_ALL_T;
extern STRU_AREA_WITH_ARB_CFG_ALL_T g_area_with_arb_cfg;
/**
* @brief 区域初始化,包含第三方仲裁的初始化(仲裁模式使用)
*/
void Area_With_Arb_Init(void);
/**
* @brief 区域开始
*
*/
void Area_Arb_Start();
/**
* @brief 等待区域开始
*
*/
void Area_Arb_Wait_Start();
/**
* @brief 区域停止
*
*/
void Area_Arb_Stop();
/**
* @brief 等待区域停止
*
*/
void Area_Arb_Wait_Stop();
#endif
+600
View File
@@ -0,0 +1,600 @@
#include "CM_Types.h"
#include "CM_Memory.h"
#include "CM_Socket.h"
#include "CM_UDP.h"
#include "CM_Convert.h"
#include "PFM_Cfg.h"
#include "CM_Sem.h"
#include "CM_MultiThread.h"
#include "CM_MultiThread_Priority.h"
#include "CM_Time.h"
#include "DFM_Time.h"
#include "MSCP_Define.h"
#include "PFM_LOG.h"
#include "MSCP_APP_Interface.h"
#include "CM_MQ.h"
#include "stdarg.h"
#include "Arb.h"
#include "Arb_Net.h"
/*===========↓↓↓↓↓宏定义↓↓↓↓↓=============*/
#define ARB_MSG_NUM_MAX 20 /*仲裁应答接收队列最大数量*/
#define ARB_RAW_MSG_SIZE 1400 /*仲裁应答接收数据包最大长度*/
/*区域单播通信配置指针*/
#define AREA_UNI_COMM_CFG_PTR (&g_area_with_arb_cfg.COMM_CFG.COMM_CFG_AREA)
/*仲裁通信配置指针*/
#define ARB_COMM_CFG_PTR (&g_area_with_arb_cfg.COMM_CFG.COMM_CFG_ARB)
/*区域组播通信配置指针*/
#define AREA_MULTI_COMM_CFG_PTR (&g_area_with_arb_cfg.COMM_CFG.COMM_CFG_AREA_MULTICAST)
/*===========↑↑↑↑↑宏定义↑↑↑↑↑=============*/
/*===========↓↓↓↓↓全局变量声明&定义↓↓↓↓↓=============*/
/*===========↑↑↑↑↑全局变量声明&定义↑↑↑↑↑=============*/
/*===========↓↓↓↓↓静态函数声明↓↓↓↓↓=============*/
/**
* @brief 仲裁接收线程
* @param STRU_ARB_IP_CFG_T-仲裁相关通信配置
*/
static CM_THREAD_FUNC_T t_Area_Arb_UdpRecvThread(IN STRU_ARB_COMM_CFG_T *arg);
/**
* @brief 区域间组播接收线程
* @param
*/
static CM_THREAD_FUNC_T t_Area_Multi_UdpRecvThread(IN STRU_AREA_MULTICAST_COMM_T *arg);
/**
* @brief 区域间但播接收线程
*/
static CM_THREAD_FUNC_T t_Area_Uni_UdpRecvThread(IN STR_Area_IP_Cfg* arg);
/**
* @brief 从配置中读取仲裁模式下使用的IP
*/
static void s_Area_Arb_IP_Init(void);
/*===========↑↑↑↑↑静态函数声明↑↑↑↑↑=============*/
/*===========↓↓↓↓↓函数定义↓↓↓↓↓↓=============*/
/**
* @brief 仲裁模式下的网络初始化
*/
void Area_Arb_Net_Init(void)
{
CM_UINT32 val = 0u;
ENUM_CM_RETURN rt = ENUM_CM_FALSE;
CM_BOOL rtCheck = CM_FALSE;
/**日志队列初始化 */
Area_LogMQ_Init();
/**2取初始化 */
Area_2oo2_Init();
/*获取IP配置*/
s_Area_Arb_IP_Init();
/** 初始化区域网络通信 */
rt = CM_UDP_Socket_Create(&(AREA_UNI_COMM_CFG_PTR->Socket), CM_FALSE, (CM_UINT32)inet_addr(AREA_UNI_COMM_CFG_PTR->IP_Local), AREA_UNI_COMM_CFG_PTR->port, 0u, (CM_UINT8)1);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
val = (CM_INT32)NET_UDP_BUF_MAX;
(void)setsockopt(AREA_UNI_COMM_CFG_PTR->Socket, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));
rt = CM_MQ_Init(&(AREA_UNI_COMM_CFG_PTR->MsgQ), (CM_UINT16)Area_MSG_NUM_MAX, (CM_UINT16)Area_RAW_MSG_SIZE);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_Area_Uni_UdpRecvThread, "Area_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)AREA_UNI_COMM_CFG_PTR);
CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);
/*初始化仲裁通信*/
rt = CM_UDP_Socket_Create(&(ARB_COMM_CFG_PTR->Socket), CM_FALSE, (CM_UINT32)inet_addr(ARB_COMM_CFG_PTR->IP_Local), ARB_COMM_CFG_PTR->port, 0u, (CM_UINT8)1);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
val = (CM_INT32)NET_UDP_BUF_MAX;
(void)setsockopt(ARB_COMM_CFG_PTR->Socket, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));
rt = CM_MQ_Init(&(ARB_COMM_CFG_PTR->MsgQ), (CM_UINT16)ARB_MSG_NUM_MAX, (CM_UINT16)ARB_RAW_MSG_SIZE);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_Area_Arb_UdpRecvThread, "Arb_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)ARB_COMM_CFG_PTR);
CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);
/** 初始化区域组播网络通信 */
rt = CM_UDP_Socket_Create(&(AREA_MULTI_COMM_CFG_PTR->Socket_Send), CM_FALSE, (CM_UINT32)inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Local), AREA_MULTI_COMM_CFG_PTR->Port_Send, (CM_UINT32)inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Multicast),ENUM_MULTICAST_SEND);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rt = CM_UDP_Socket_Create(&AREA_MULTI_COMM_CFG_PTR->Socket_Recv, CM_FALSE, (CM_UINT32)inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Local), AREA_MULTI_COMM_CFG_PTR->Port_Recv, (CM_UINT32)inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Multicast),ENUM_MULTICAST_RCV);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rt = CM_MQ_Init(&(AREA_MULTI_COMM_CFG_PTR->MsgQ), (CM_UINT16)Area_MSG_NUM_MAX, (CM_UINT16)Area_RAW_MSG_SIZE);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_Area_Multi_UdpRecvThread, "Area_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)AREA_MULTI_COMM_CFG_PTR);
CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);
}
/**
* @brief 第三方仲裁请求发送
* @param pBuf 发送报文指针 取值范围:非空
* @param BufLen 发送报文长度 取值范围:0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_Arb_Req_Send(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
/*- 变量初始化 */
ENUM_CM_RETURN rt = ENUM_CM_FALSE;
/*- 入参指针防空 */
if(NULL != pBuf)
{
/*- 向第三方仲裁发送 */
rt = CM_UDP_Send_Msg(ARB_COMM_CFG_PTR->Socket, pBuf, BufLen, inet_addr(ARB_COMM_CFG_PTR->IP_Arb),ARB_COMM_CFG_PTR->port);
}
else
{
/*空指针返回失败*/
}
/*- 返回发送结果 */
return rt;
}
/**
* @brief 第三方仲裁请求发送接收
* @param pBuf 接收报文指针 取值范围:非空
* @param BufLen 接收报文缓冲区大小 取值范围:0~0xFFFFFFFF
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_Arb_Ack_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
/*- 变量初始化 */
CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
ENUM_CM_RETURN rt = ENUM_CM_FALSE;
/*- 指针防空*/
/*- 从接收线程获取输入报文 */
rt = CM_MQ_Read(&(ARB_COMM_CFG_PTR->MsgQ), pBuf, &len);
/*- 是否获取成功 */
if (ENUM_CM_TRUE == rt)
{
/*- 输出接收数据 */
}
else
{
/*- 接收长度为0 */
len = 0u;
}
/*- 返回接收长度 */
return (CM_INT32)len;
}
/**
* @brief 区域状态请求单播发送
* @param dstID 发送的目的ID
* @param pBuf 发送报文指针 取值范围:非空
* @param BufLen 发送报文长度 取值范围:0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_State_Send(IN CM_UINT8 dstID, IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
/*- 变量初始化 */
ENUM_CM_RETURN rt = ENUM_CM_FALSE;
/*- 入参指针防空 */
if(NULL != pBuf)
{
/*- 向目的ID发送 */
if(dstID == AREA_BASIC_CFG_PTR->Partner_BoardID)
{
rt = CM_UDP_Send_Msg(AREA_UNI_COMM_CFG_PTR->Socket, pBuf, BufLen, inet_addr(AREA_UNI_COMM_CFG_PTR->IP_Partner),AREA_UNI_COMM_CFG_PTR->port);
}
else if(dstID == AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID)
{
rt = CM_UDP_Send_Msg(AREA_UNI_COMM_CFG_PTR->Socket, pBuf, BufLen, inet_addr(AREA_UNI_COMM_CFG_PTR->IP_Partner_Area_A),AREA_UNI_COMM_CFG_PTR->port);
}
else if(dstID == AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID)
{
rt = CM_UDP_Send_Msg(AREA_UNI_COMM_CFG_PTR->Socket, pBuf, BufLen, inet_addr(AREA_UNI_COMM_CFG_PTR->IP_Partner_Area_B),AREA_UNI_COMM_CFG_PTR->port);
}
else
{
/**ID查询失败 */
rt = ENUM_CM_FALSE;
}
}
else
{
/*空指针返回失败*/
}
/*- 返回发送结果 */
return rt;
}
/**
* @brief 区域状态请求单播接收(仲裁模式使用)
* @param pBuf 接收报文指针 取值范围:非空
* @param BufLen 接收报文缓冲区大小 取值范围:0~0xFFFFFFFF
* @param timeRcv 接收时的时间戳,单位ms
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_State_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* timeRcv)
{
/*- 变量初始化 */
CM_UINT8 buf[65535] = {0};
CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
ENUM_CM_RETURN rt = ENUM_CM_FALSE;
/*- 指针防空*/
/*- 从接收线程获取输入报文 */
rt = CM_MQ_Read(&(AREA_UNI_COMM_CFG_PTR->MsgQ), buf, &len);
/*- 是否获取成功 */
if (ENUM_CM_TRUE == rt && len > 4u)
{
/*- 输出接收数据 */
if(NULL != timeRcv)
{
*timeRcv = CM_LongFromChar(buf);
}
CM_Memcpy(pBuf, BufSize, &buf[4], len - 4);
}
else
{
/*- 接收长度为0 */
len = 0u;
}
/*- 返回接收长度 */
return (CM_INT32)len;
}
/**
* @brief 区域状态请求组播发送
* @param pBuf 发送报文指针 取值范围:非空
* @param BufLen 发送报文长度 取值范围:0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_State_Multi_Send(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
/*- 变量初始化 */
ENUM_CM_RETURN rt = ENUM_CM_FALSE;
/*- 入参指针防空 */
if(NULL != pBuf)
{
/*- 组播发送 */
rt = CM_UDP_Send_Msg(AREA_MULTI_COMM_CFG_PTR->Socket_Send, pBuf, BufLen, inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Multicast),AREA_MULTI_COMM_CFG_PTR->Port_Send);
}
else
{
/*空指针返回失败*/
}
/*- 返回发送结果 */
return rt;
}
/**
* @brief 区域状态请求组播接收
* @param pBuf 接收报文指针 取值范围:非空
* @param BufLen 接收报文缓冲区大小 取值范围:0~0xFFFFFFFF
* @param timeRcv 接收时的时间戳,单位ms
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_State_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* timeRcv)
{
/*- 变量初始化 */
CM_UINT8 buf[65535] = {0};
CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
ENUM_CM_RETURN rt = ENUM_CM_FALSE;
/*- 指针防空*/
/*- 从接收线程获取输入报文 */
rt = CM_MQ_Read(&(AREA_MULTI_COMM_CFG_PTR->MsgQ), buf, &len);
/*- 是否获取成功 */
if (ENUM_CM_TRUE == rt && len > 4u)
{
/*- 输出接收数据 */
if(NULL != timeRcv)
{
*timeRcv = CM_LongFromChar(buf);
}
CM_Memcpy(pBuf, BufSize, &buf[4], len - 4);
}
else
{
/*- 接收长度为0 */
len = 0u;
}
/*- 返回接收长度 */
return (CM_INT32)len;
}
/**
* @brief 清空接收缓冲区
*/
void Area_Arb_ClearMsgQ(void)
{
(void)CM_MQ_Flush(&(AREA_UNI_COMM_CFG_PTR->MsgQ));
(void)CM_MQ_Flush(&(ARB_COMM_CFG_PTR->MsgQ));
(void)CM_MQ_Flush(&(AREA_MULTI_COMM_CFG_PTR->MsgQ));
}
/**
* @brief 仲裁接收线程
* @param STRU_ARB_IP_CFG_T-仲裁相关通信配置
*/
static CM_THREAD_FUNC_T t_Area_Arb_UdpRecvThread(IN STRU_ARB_COMM_CFG_T *arg)
{
/*- 变量初始化 */
STRU_ARB_COMM_CFG_T *pCtrl = (STRU_ARB_COMM_CFG_T *)arg; /* 线程控制信息 */
ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */
CM_UINT8 *rcvBuf = NULL;
CM_INT32 len; /* 报文长度 */
CM_UINT32 srcIP; /* 源IP */
CM_UINT16 srcPort; /* 源端口 */
CM_SOCKADDR_T addr; /* 地址转换*/
void* pmask = NULL;
pmask = (void*)(0x01u|0x02u);
(void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
MSCP_LOG_MSG("IP:%s:%d UDP recv Start\n", pCtrl->IP_Local, pCtrl->port);
/*- 循环接收UDP数据 */
while (1)
{
/*- UDP阻塞接收 */
rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
if (NULL != rcvBuf)
{
len = CM_UDP_Recv_Msg(pCtrl->Socket, &rcvBuf[0u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize), &srcIP, &srcPort);
/*- 是否收到有效数据 */
if (len > 0)
{
/*- 源IP端口是否合法 */
if ((srcIP != 0) && (srcPort != 0))
{
/*- @alias 将收到的报文写入线程接收队列 */
// MSCP_LOG_MSG("!!! area recv len = %d \r\n",len);
/*- 保存通信数据 */
rt = CM_MQ_UpData(&pCtrl->MsgQ, (CM_UINT16)CM_SIGNED_INT_EXP(len));
/*- 数据保存是否成功 */
if (ENUM_CM_TRUE == rt)
{
/*成功无操作*/
}
else
{
/*- 防御性清空*/
rt = CM_MQ_Clear(&pCtrl->MsgQ);
CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
}
}
else
{
/*- 来自非预期IP端口的数据*/
addr.sin_addr.s_addr = srcIP;
CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
}
}
else
{
/*- 接收出错 */
MSCP_LOG_MSG("warning ASSERT1103: port %d rx err(len=%d)\n", pCtrl->port, len);
(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1));
}
}
else
{
/*获取队列指针失败,清空队列*/
rt = CM_MQ_Clear(&pCtrl->MsgQ);
MSCP_LOG_MSG("buf clear\n");
CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_4);
}
}
return NULL;
}
/**
* @brief 区域间组播接收线程
* @param
*/
static CM_THREAD_FUNC_T t_Area_Multi_UdpRecvThread(IN STRU_AREA_MULTICAST_COMM_T *arg)
{
/*- 变量初始化 */
STRU_AREA_MULTICAST_COMM_T *pCtrl = (STRU_AREA_MULTICAST_COMM_T *)arg; /* 线程控制信息 */
ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */
CM_UINT8 *rcvBuf = NULL;
CM_INT32 len; /* 报文长度 */
CM_UINT32 srcIP; /* 源IP */
CM_UINT16 srcPort; /* 源端口 */
CM_SOCKADDR_T addr; /* 地址转换*/
void* pmask = NULL;
pmask = (void*)(0x01u|0x02u);
(void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
MSCP_LOG_MSG("IP:%s:%d UDP recv Start\n", pCtrl->IP_Multicast, pCtrl->Port_Recv);
/*- 循环接收UDP数据 */
while (1)
{
/*- UDP阻塞接收 */
rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
if (NULL != rcvBuf)
{
len = CM_UDP_Recv_Msg(pCtrl->Socket_Recv, &rcvBuf[0u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize), &srcIP, &srcPort);
/*- 是否收到有效数据 */
if (len > 0)
{
/*- 源IP端口是否合法 */
if ((srcIP != 0) && (srcPort != 0))
{
/*- @alias 将收到的报文写入线程接收队列 */
// MSCP_LOG_MSG("!!! area recv len = %d \r\n",len);
/*- 保存通信数据 */
rt = CM_MQ_UpData(&pCtrl->MsgQ, (CM_UINT16)CM_SIGNED_INT_EXP(len));
/*- 数据保存是否成功 */
if (ENUM_CM_TRUE == rt)
{
/*成功无操作*/
}
else
{
/*- 防御性清空*/
rt = CM_MQ_Clear(&pCtrl->MsgQ);
CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
}
}
else
{
/*- 来自非预期IP端口的数据*/
addr.sin_addr.s_addr = srcIP;
CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
}
}
else
{
/*- 接收出错 */
MSCP_LOG_MSG("warning ASSERT1103: port %d rx err(len=%d)\n", pCtrl->Port_Recv, len);
(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1));
}
}
else
{
/*获取队列指针失败,清空队列*/
rt = CM_MQ_Clear(&pCtrl->MsgQ);
MSCP_LOG_MSG("buf clear\n");
CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_4);
}
}
return NULL;
}
/**
* @brief 初始化仲裁模式下使用的IP
*/
static void s_Area_Arb_IP_Init(void)
{
ENUM_CM_RETURN rt = ENUM_CM_FALSE;
/** 获取区域网络配置(状态请求) */
rt = CM_Memcpy(AREA_UNI_COMM_CFG_PTR->IP_Local, 32, g_PFM_Cfg.Local_Cfg.IP_4x2,32);/**< 本地通信IP */
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rt = CM_Memcpy(AREA_UNI_COMM_CFG_PTR->IP_Partner, 32, g_PFM_Cfg.Partner_Cfg.IP_4x2,32);/**< 对系通信IP */
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rt = CM_Memcpy(AREA_UNI_COMM_CFG_PTR->IP_Partner_Area_A, 32, g_PFM_Cfg.Partner_Area_A_Cfg.IP_4x2,32);/**< 对地通信IP */
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rt = CM_Memcpy(AREA_UNI_COMM_CFG_PTR->IP_Partner_Area_B, 32, g_PFM_Cfg.Partner_Area_B_Cfg.IP_4x2,32);/**< 对地通信IP */
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
AREA_UNI_COMM_CFG_PTR->port = g_PFM_Cfg.Local_Cfg.Port_Area_State;/**< 端口号 */
AREA_LOG_MSG("AREA CFG %s, %s %s %s \r\n",g_PFM_Cfg.Local_Cfg.IP_4x2, g_PFM_Cfg.Partner_Cfg.IP_4x2,
g_PFM_Cfg.Partner_Area_A_Cfg.IP_4x2, g_PFM_Cfg.Partner_Area_B_Cfg.IP_4x2);
/*获取仲裁网络配置*/
rt = CM_Memcpy(ARB_COMM_CFG_PTR->IP_Local, 32, g_PFM_Cfg.Local_Cfg.IP_4x2,32);/**< 对地通信IP */
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rt = CM_Memcpy(ARB_COMM_CFG_PTR->IP_Arb, 32, g_PFM_Cfg.Arb_CFG.IP_Arb,32);/**< 对地通信IP */
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
ARB_COMM_CFG_PTR->port = g_PFM_Cfg.Arb_CFG.Port_Arb;
MSCP_LOG_MSG("ARB CFG %s:%d->%s:%d\n", ARB_COMM_CFG_PTR->IP_Local,
ARB_COMM_CFG_PTR->port,ARB_COMM_CFG_PTR->IP_Arb,ARB_COMM_CFG_PTR->port);
/*获取区域间组播通信配置(主地主组播状态)*/
rt = CM_Memcpy(AREA_MULTI_COMM_CFG_PTR->IP_Local, 32, g_PFM_Cfg.Local_Cfg.IP_4x2,32);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
rt = CM_Memcpy(AREA_MULTI_COMM_CFG_PTR->IP_Multicast, 32, g_PFM_Cfg.Local_Cfg.IP_Area_Multicast, 32);
CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
AREA_MULTI_COMM_CFG_PTR->Port_Recv = g_PFM_Cfg.Local_Cfg.Port_Area_Recv;
AREA_MULTI_COMM_CFG_PTR->Port_Send = g_PFM_Cfg.Local_Cfg.Port_Area_Send;
MSCP_LOG_MSG("AREA MULTICAST CFG %s:%d->%s:%d\n", AREA_MULTI_COMM_CFG_PTR->IP_Local, AREA_MULTI_COMM_CFG_PTR->Port_Send,
AREA_MULTI_COMM_CFG_PTR->IP_Multicast,AREA_MULTI_COMM_CFG_PTR->Port_Recv);
}
/**
* @brief 区域间但播接收线程
*/
static CM_THREAD_FUNC_T t_Area_Uni_UdpRecvThread(IN STR_Area_IP_Cfg *arg)
{
/*- 变量初始化 */
STR_Area_IP_Cfg *pCtrl = (STR_Area_IP_Cfg *)arg; /* 线程控制信息 */
ENUM_CM_RETURN rt = ENUM_CM_FALSE; /* 函数返回值 */
CM_UINT8 *rcvBuf = NULL;
CM_INT32 len; /* 报文长度 */
CM_UINT32 srcIP; /* 源IP */
CM_UINT16 srcPort; /* 源端口 */
CM_SOCKADDR_T addr; /* 地址转换*/
CM_UINT32 cpu_mask = 0;
/*- 本线程锁定在 A53 core 1 */
cpu_mask = (0x04u);
set_thread_affinity(cpu_mask);
MSCP_LOG_MSG("IP:%s:%d UDP recv Start\n", pCtrl->IP_Local, pCtrl->port);
/*- 循环接收UDP数据 */
while (1)
{
/*- UDP阻塞接收 */
rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
if (NULL != rcvBuf)
{
len = CM_UDP_Recv_Msg(pCtrl->Socket, &rcvBuf[4u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize), &srcIP, &srcPort);
/*- 是否收到有效数据 */
if (len > 0)
{
/*- 源IP端口是否合法 */
if ((srcIP != 0) && (srcPort != 0))
{
/*- @alias 将收到的报文写入线程接收队列 */
CM_LongToChar((CM_UINT32)(CM_GetTick()/CM_UNSIGNED_MILLION), rcvBuf);
/*- 保存通信数据 */
rt = CM_MQ_UpData(&pCtrl->MsgQ, (CM_UINT16)CM_SIGNED_INT_EXP(len));
/*- 数据保存是否成功 */
if (ENUM_CM_TRUE == rt)
{
/*成功无操作*/
}
else
{
/*- 防御性清空*/
rt = CM_MQ_Clear(&pCtrl->MsgQ);
CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
}
}
else
{
/*- 来自非预期IP端口的数据*/
addr.sin_addr.s_addr = srcIP;
CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
}
}
else
{
/*- 接收出错 */
MSCP_LOG_MSG("warning ASSERT1103: port %d rx err(len=%d)\n", pCtrl->port, len);
(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1));
}
}
else
{
/*获取队列指针失败,清空队列*/
rt = CM_MQ_Clear(&pCtrl->MsgQ);
MSCP_LOG_MSG("buf clear\n");
CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_4);
}
}
return NULL;
}
+99
View File
@@ -0,0 +1,99 @@
#ifndef ARB_NET_H_
#define ARB_NET_H_
/*区域间的组播配置*/
typedef struct
{
CM_CHAR IP_Local[32]; /**< 本地IP */
CM_CHAR IP_Multicast[32]; /**< 组播域*/
CM_UINT16 Port_Send; /**< 组播发送接口 */
CM_UINT16 Port_Recv; /**< 组播接收接口 */
CM_SOCKET Socket_Send; /**< 组播发送socket */
CM_SOCKET Socket_Recv; /**< 组播接收socket */
CM_MQ_Struct_T MsgQ; /**< 接收消息队列 */
} STRU_AREA_MULTICAST_COMM_T;
/*与第三方仲裁通信的配置*/
typedef struct
{
CM_CHAR IP_Local[32];
CM_CHAR IP_Arb[32];
CM_SOCKET Socket;
CM_UINT16 port; /**< 端口号 */
CM_MQ_Struct_T MsgQ; /**< 接收消息队列 */
} STRU_ARB_COMM_CFG_T;
/**
* @brief 仲裁模式下的网络初始化
*/
void Area_Arb_Net_Init(void);
/**
* @brief 第三方仲裁请求发送(仲裁模式使用)
* @param pBuf 发送报文指针 取值范围:非空
* @param BufLen 发送报文长度 取值范围:0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_Arb_Req_Send(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen);
/**
* @brief 第三方仲裁请求应答接收(仲裁模式使用)
* @param pBuf 接收报文指针 取值范围:非空
* @param BufLen 接收报文缓冲区大小 取值范围:0~0xFFFFFFFF
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_Arb_Ack_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize);
/**
* @brief 区域状态请求单播发送
* @param dstID 发送的目的ID
* @param pBuf 发送报文指针 取值范围:非空
* @param BufLen 发送报文长度 取值范围:0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_State_Send(IN CM_UINT8 dstID, IN const CM_UINT8* pBuf, IN CM_INT32 BufLen);
/**
* @brief 区域状态请求单播接收(仲裁模式使用)
* @param pBuf 接收报文指针 取值范围:非空
* @param BufLen 接收报文缓冲区大小 取值范围:0~0xFFFFFFFF
* @param timeRcv 接收时的时间戳,单位ms(为空指针时不读取)
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_State_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* timeRcv);
/**
* @brief 区域状态请求组播发送(仲裁模式使用)
* @param pBuf 发送报文指针 取值范围:非空
* @param BufLen 发送报文长度 取值范围:0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_State_Multi_Send(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen);
/**
* @brief 区域状态请求组播接收(仲裁模式使用)
* @param pBuf 接收报文指针 取值范围:非空
* @param BufLen 接收报文缓冲区大小 取值范围:0~0xFFFFFFFF
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_State_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* timeRcv);
/**
* @brief 仲裁模式下所有的接收缓冲区
*/
void Area_Arb_ClearMsgQ(void);
#endif
+203
View File
@@ -0,0 +1,203 @@
#include "Arb_Pack.h"
#include "CM_Convert.h"
/* 各类报文在线路上的固定长度。枚举类型按1字节消息类型进行传输。 */
#define AREA_ARB_FRAME_PACK_LEN (26u)
#define AREA_ARB_STATE_MULTI_PACK_LEN (25u)
#define AREA_ARB_STATE_PACK_LEN (27u)
/**
* @brief 打包仲裁请求/应答帧
* @return 成功返回固定报文长度26,入参非法或缓冲区不足返回0。
*/
CM_INT32 Area_Arb_Frame_Pack(OUT CM_UINT8* buf, IN CM_UINT32 buf_size,
IN STRU_AREA_WITH_ARB_PACK_T* pack)
{
CM_UINT32 index = 0u;
if ((NULL == buf) || (NULL == pack) || (buf_size < AREA_ARB_FRAME_PACK_LEN))
{
return 0;
}
/* 按协议字段顺序写入;多字节整数统一使用大端转换函数。 */
buf[index++] = pack->Len;
buf[index++] = (CM_UINT8)pack->MsgType;
CM_LongToChar(pack->ArbSN, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
CM_ShortToChar(pack->OutNet_ID, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT16);
buf[index++] = pack->Board_ID;
buf[index++] = pack->ArbPayLoad;
/* 预留区为字节数组,直接复制到报文缓冲区。 */
(void)memcpy(&buf[index], pack->Reserver, AREA_ARB_RESERVER_LEN);
index += AREA_ARB_RESERVER_LEN;
CM_LongToChar(pack->CRC1, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
CM_LongToChar(pack->CRC2, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
return (CM_INT32)index;
}
/**
* @brief 解包仲裁请求/应答帧
* @note 入参非法或报文长度不足时不修改输出结构体。
*/
void Area_Arb_Frame_UnPack(OUT STRU_AREA_WITH_ARB_PACK_T* pack,
IN CM_UINT8* buf, IN CM_UINT32 buf_len)
{
CM_UINT32 index = 0u;
if ((NULL == pack) || (NULL == buf) || (buf_len < AREA_ARB_FRAME_PACK_LEN))
{
return;
}
/* 按打包时相同的字段顺序读取,多字节整数按大端还原。 */
pack->Len = buf[index++];
pack->MsgType = (ENUM_AREA_ARB_MSG_TYPE_T)buf[index++];
pack->ArbSN = CM_LongFromChar(&buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
pack->OutNet_ID = CM_ShortFromChar(&buf[index]);
index += (CM_UINT32)sizeof(CM_UINT16);
pack->Board_ID = buf[index++];
pack->ArbPayLoad = buf[index++];
/* 预留区为字节数组,直接复制到输出结构体。 */
(void)memcpy(pack->Reserver, &buf[index], AREA_ARB_RESERVER_LEN);
index += AREA_ARB_RESERVER_LEN;
pack->CRC1 = CM_LongFromChar(&buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
pack->CRC2 = CM_LongFromChar(&buf[index]);
}
/**
* @brief 打包区域状态组播帧
* @return 成功返回固定报文长度25,入参非法或缓冲区不足返回0。
*/
CM_INT32 Area_Arb_State_Multi_Pack(OUT CM_UINT8* buf, IN CM_UINT32 buf_size,
IN STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T* pack)
{
CM_UINT32 index = 0u;
if ((NULL == buf) || (NULL == pack) || (buf_size < AREA_ARB_STATE_MULTI_PACK_LEN))
{
return 0;
}
/* 按协议字段顺序写入;多字节整数统一使用大端转换函数。 */
buf[index++] = pack->Len;
buf[index++] = (CM_UINT8)pack->MsgType;
CM_LongToChar(pack->SN, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
buf[index++] = pack->SrcID;
buf[index++] = pack->StateArea;
buf[index++] = pack->State2x;
/* 预留区为字节数组,直接复制到报文缓冲区。 */
(void)memcpy(&buf[index], pack->Reserver, AREA_ARB_RESERVER_LEN);
index += AREA_ARB_RESERVER_LEN;
CM_LongToChar(pack->CRC1, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
CM_LongToChar(pack->CRC2, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
return (CM_INT32)index;
}
/**
* @brief 解包区域状态组播帧
* @note 入参非法或报文长度不足时不修改输出结构体。
*/
void Area_Arb_State_Multi_UnPack(OUT STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T* pack,
IN CM_UINT8* buf, IN CM_UINT32 buf_len)
{
CM_UINT32 index = 0u;
if ((NULL == pack) || (NULL == buf) || (buf_len < AREA_ARB_STATE_MULTI_PACK_LEN))
{
return;
}
/* 按打包时相同的字段顺序读取,多字节整数按大端还原。 */
pack->Len = buf[index++];
pack->MsgType = (ENUM_AREA_ARB_MSG_TYPE_T)buf[index++];
pack->SN = CM_LongFromChar(&buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
pack->SrcID = buf[index++];
pack->StateArea = buf[index++];
pack->State2x = buf[index++];
/* 预留区为字节数组,直接复制到输出结构体。 */
(void)memcpy(pack->Reserver, &buf[index], AREA_ARB_RESERVER_LEN);
index += AREA_ARB_RESERVER_LEN;
pack->CRC1 = CM_LongFromChar(&buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
pack->CRC2 = CM_LongFromChar(&buf[index]);
}
/**
* @brief 打包地间状态请求/应答帧
* @return 成功返回固定报文长度27,入参非法或缓冲区不足返回0。
*/
CM_INT32 Area_Arb_State_Pack(OUT CM_UINT8* buf, IN CM_UINT32 buf_size,
IN STRU_AREA_WITH_ARB_STATE_PACK_T* pack)
{
CM_UINT32 index = 0u;
if ((NULL == buf) || (NULL == pack) || (buf_size < AREA_ARB_STATE_PACK_LEN))
{
return 0;
}
/* 按协议字段顺序写入;多字节整数统一使用大端转换函数。 */
buf[index++] = pack->Len;
buf[index++] = (CM_UINT8)pack->MsgType;
CM_LongToChar(pack->SN, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
buf[index++] = pack->TimeSyncFlag;
buf[index++] = pack->SrcID;
buf[index++] = pack->DstID;
buf[index++] = pack->StateArea;
buf[index++] = pack->State2x;
/* 预留区为字节数组,直接复制到报文缓冲区。 */
(void)memcpy(&buf[index], pack->Reserver, AREA_ARB_RESERVER_LEN);
index += AREA_ARB_RESERVER_LEN;
CM_LongToChar(pack->CRC1, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
CM_LongToChar(pack->CRC2, &buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
return (CM_INT32)index;
}
/**
* @brief 解包地间状态请求/应答帧
* @note 入参非法或报文长度不足时不修改输出结构体。
*/
void Area_Arb_State_UnPack(OUT STRU_AREA_WITH_ARB_STATE_PACK_T* pack,
IN CM_UINT8* buf, IN CM_UINT32 buf_len)
{
CM_UINT32 index = 0u;
if ((NULL == pack) || (NULL == buf) || (buf_len < AREA_ARB_STATE_PACK_LEN))
{
return;
}
/* 按打包时相同的字段顺序读取,多字节整数按大端还原。 */
pack->Len = buf[index++];
pack->MsgType = (ENUM_AREA_ARB_MSG_TYPE_T)buf[index++];
pack->SN = CM_LongFromChar(&buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
pack->TimeSyncFlag = buf[index++];
pack->SrcID = buf[index++];
pack->DstID = buf[index++];
pack->StateArea = buf[index++];
pack->State2x = buf[index++];
/* 预留区为字节数组,直接复制到输出结构体。 */
(void)memcpy(pack->Reserver, &buf[index], AREA_ARB_RESERVER_LEN);
index += AREA_ARB_RESERVER_LEN;
pack->CRC1 = CM_LongFromChar(&buf[index]);
index += (CM_UINT32)sizeof(CM_UINT32);
pack->CRC2 = CM_LongFromChar(&buf[index]);
}
+130
View File
@@ -0,0 +1,130 @@
#ifndef AREA_PACK_H_
#define AREA_PACK_H_
#include "CM_Types.h"
#include "SFM_2x2.h"
#include "Area.h"
/* 结构体的真实大小,如果有结构体对齐,可能和所有成员长度相加不同 */
#define AREA_ARB_FRAME_PACK_REAL_LEN (sizeof(STRU_AREA_WITH_ARB_PACK_T))
#define AREA_ARB_STATE_MULTI_PACK_REAL_LEN (sizeof(STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T))
#define AREA_ARB_STATE_PACK_REAL_LEN (sizeof(STRU_AREA_WITH_ARB_STATE_PACK_T))
#define AREA_ARB_RESERVER_LEN (8u)
/**< 仲裁模式下,区域通信的消息类型 */
typedef enum
{
ENUM_AREA_MSG_ARB_REQ = 0x01, /**< 仲裁请求帧 */
ENUM_AREA_MSG_ARB_ACK = 0x81, /**< 仲裁应答帧 */
ENUM_AREA_MSG_STATE_REQ = 0x02, /**< 区域状态请求帧 */
ENUM_AREA_MSG_STATE_ACK = 0x82, /**< 区域状态应答帧 */
ENUM_AREA_MSG_STATE_MULTI = 0x03, /**< 区域状态组播帧 */
}ENUM_AREA_ARB_MSG_TYPE_T;
/* 仲裁模式下,仲裁请求与回复的帧格式 */
typedef struct
{
CM_UINT8 Len; /**< 数据包长度 */
ENUM_AREA_ARB_MSG_TYPE_T MsgType; /**< 消息类型 */
CM_UINT32 ArbSN; /**< 仲裁请求/应答序列号 */
CM_UINT16 OutNet_ID; /**< 外网ID */
CM_UINT8 Board_ID; /**< 板卡ID */
CM_UINT8 ArbPayLoad; /**< 仲裁请求/回复的具体内容 */
CM_UINT8 Reserver[AREA_ARB_RESERVER_LEN]; /**< 预留8字节 */
CM_UINT32 CRC1; /**< CRC1 */
CM_UINT32 CRC2; /**< CRC2 */
}STRU_AREA_WITH_ARB_PACK_T;
/* 仲裁模式下,组播状态帧格式 */
typedef struct
{
CM_UINT8 Len; /**< 数据包长度 */
ENUM_AREA_ARB_MSG_TYPE_T MsgType; /**< 消息类型 */
CM_UINT32 SN; /**< 消息SN号(周期号) */
CM_UINT8 SrcID; /**< 源ID(板卡ID) */
ENUM_AREA_STATE StateArea; /**< 区域状态 */
ENUM_2x2_STATE_T State2x; /**< 2x状态 */
CM_UINT8 Reserver[AREA_ARB_RESERVER_LEN]; /**< 预留8字节 */
CM_UINT32 CRC1; /**< CRC1 */
CM_UINT32 CRC2; /**< CRC2 */
}STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T;
/**仲裁模式下,地间状态请求与回复帧格式 */
typedef struct
{
CM_UINT8 Len; /**< 数据包长度 */
ENUM_AREA_ARB_MSG_TYPE_T MsgType; /**< 消息类型 */
CM_UINT32 SN; /**< 消息SN号(周期号) */
CM_UINT8 TimeSyncFlag; /**< 校时标志(用于判断是否需要容忍接收) */
CM_UINT8 SrcID; /**< 源ID(板卡ID) */
CM_UINT8 DstID; /**< 目的ID(板卡ID) */
ENUM_AREA_STATE StateArea; /**< 区域状态 */
ENUM_2x2_STATE_T State2x; /**< 2x状态 */
CM_UINT8 Reserver[AREA_ARB_RESERVER_LEN]; /**< 预留8字节 */
CM_UINT32 CRC1; /**< CRC1 */
CM_UINT32 CRC2; /**< CRC2 */
}STRU_AREA_WITH_ARB_STATE_PACK_T;
/**
* @brief 将仲裁请求结构体的内容写入缓冲区
* @param pack 请求结构体
* @param buf 缓冲区
* @param buf_size 缓冲区大小
* @return CM_INT32 写入的长度
* @note 如果使用该打包函数,解包时也必须使用对应解包函数,避免因为结构体对齐出现问题
*/
CM_INT32 Area_Arb_Frame_Pack(OUT CM_UINT8* buf, IN CM_UINT32 buf_size, IN STRU_AREA_WITH_ARB_PACK_T* pack);
/**
* @brief 将缓冲区写入仲裁请求结构体的内容
* @param pack 请求结构体
* @param buf 缓冲区
* @param buf_len 缓冲区大小
* @return CM_INT32 写入的长度
* @note 仅对打包函数处理后的数据进行解包
*/
void Area_Arb_Frame_UnPack(OUT STRU_AREA_WITH_ARB_PACK_T* pack, IN CM_UINT8* buf, IN CM_UINT32 buf_len);
/**
* @brief 将组播状态帧结构体的内容写入缓冲区
* @param pack 请求结构体
* @param buf 缓冲区
* @param buf_size 缓冲区大小
* @return CM_INT32 写入的长度
* @note 如果使用该打包函数,解包时也必须使用对应解包函数,避免因为结构体对齐出现问题
*/
CM_INT32 Area_Arb_State_Multi_Pack(OUT CM_UINT8* buf, IN CM_UINT32 buf_size, IN STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T* pack);
/**
* @brief 将缓冲区写入组播状态帧结构体
* @param pack 请求结构体
* @param buf 缓冲区
* @param buf_len 缓冲区大小
* @return CM_INT32 写入的长度
* @note 仅对打包函数处理后的数据进行解包
*/
void Area_Arb_State_Multi_UnPack(OUT STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T* pack, IN CM_UINT8* buf, IN CM_UINT32 buf_len);
/**
* @brief 将地间状态请求结构体的内容写入缓冲区
* @param pack 请求结构体
* @param buf 缓冲区
* @param buf_size 缓冲区大小
* @return CM_INT32 写入的长度
* @note 如果使用该打包函数,解包时也必须使用对应解包函数,避免因为结构体对齐出现问题
*/
CM_INT32 Area_Arb_State_Pack(OUT CM_UINT8* buf, IN CM_UINT32 buf_size, IN STRU_AREA_WITH_ARB_STATE_PACK_T* pack);
/**
* @brief 将缓冲区写入地间状态请求结构体
* @param pack 请求结构体
* @param buf 缓冲区
* @param buf_len 缓冲区大小
* @return CM_INT32 写入的长度
* @note 仅对打包函数处理后的数据进行解包
*/
void Area_Arb_State_UnPack(OUT STRU_AREA_WITH_ARB_STATE_PACK_T* pack, IN CM_UINT8* buf, IN CM_UINT32 buf_len);
#endif
+144
View File
@@ -0,0 +1,144 @@
#include "Arb_State.h"
#include "Arb.h"
/**
* @brief 通过ID获取对应板卡区域状态
*/
ENUM_AREA_STATE Area_GetState_byID(CM_UINT8 ID)
{
ENUM_AREA_STATE state = ENUM_AREA_SHUTDOWN;
if(ID == AREA_BASIC_CFG_PTR->BoardID)
{
state = AREA_STATE_CTRL_PTR->StateArea.Local_state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_BoardID)
{
state = AREA_STATE_CTRL_PTR->StateArea.Partner_state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID)
{
state = AREA_STATE_CTRL_PTR->StateArea.Partner_Area_A_state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID)
{
state = AREA_STATE_CTRL_PTR->StateArea.Partner_Area_B_state;
}
else
{
AREA_LOG_MSG("Cant Find ID:%d\n", ID);
}
return state;
}
/**
* @brief 通过ID设置对应板卡区域状态
*/
void Area_SetState_byID(CM_UINT8 ID, ENUM_AREA_STATE state)
{
if(ID == AREA_BASIC_CFG_PTR->BoardID)
{
AREA_STATE_CTRL_PTR->StateArea.Local_state = state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_BoardID)
{
AREA_STATE_CTRL_PTR->StateArea.Partner_state = state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID)
{
AREA_STATE_CTRL_PTR->StateArea.Partner_Area_A_state = state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID)
{
AREA_STATE_CTRL_PTR->StateArea.Partner_Area_B_state = state;
}
else
{
AREA_LOG_MSG("Cant Find ID:%d\n", ID);
}
}
/**
* @brief 通过ID获取对应板卡2x状态
*/
ENUM_2x2_STATE_T Area_Get2xState_byID(CM_UINT8 ID)
{
ENUM_2x2_STATE_T state = ENUM_2x2_SHUTDOWN;
if(ID == AREA_BASIC_CFG_PTR->BoardID)
{
state = AREA_STATE_CTRL_PTR->State2x.LocalState;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_BoardID)
{
state = AREA_STATE_CTRL_PTR->State2x.PartnerState;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID)
{
state = AREA_STATE_CTRL_PTR->State2x.Area_A_State;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID)
{
state = AREA_STATE_CTRL_PTR->State2x.Area_B_State;
}
else
{
AREA_LOG_MSG("Cant Find ID:%d\n", ID);
}
return state;
}
/**
* @brief 通过ID设置对应板卡2x状态
*/
void Area_Set2xState_byID(CM_UINT8 ID, ENUM_2x2_STATE_T state)
{
if(ID == AREA_BASIC_CFG_PTR->BoardID)
{
AREA_STATE_CTRL_PTR->State2x.LocalState = state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_BoardID)
{
AREA_STATE_CTRL_PTR->State2x.PartnerState = state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID)
{
AREA_STATE_CTRL_PTR->State2x.Area_A_State = state;
}
else if(ID == AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID)
{
AREA_STATE_CTRL_PTR->State2x.Area_B_State = state;
}
else
{
AREA_LOG_MSG("Cant Find ID:%d\n", ID);
}
}
/**
* @brief 通过状态获取某个板卡ID
*/
CM_UINT8 Area_GetID_byState(ENUM_AREA_STATE* state_area, ENUM_2x2_STATE_T* state_2x)
{
CM_UINT8 boardID = 0u;
if(AREA_STATE_CTRL_PTR->StateArea.Local_state == state_area && AREA_STATE_CTRL_PTR->State2x.LocalState == state_2x)
{
boardID = AREA_BASIC_CFG_PTR->BoardID;
}
else if(AREA_STATE_CTRL_PTR->StateArea.Partner_state == state_area && AREA_STATE_CTRL_PTR->State2x.PartnerState == state_2x)
{
boardID = AREA_BASIC_CFG_PTR->Partner_BoardID;
}
else if(AREA_STATE_CTRL_PTR->StateArea.Partner_Area_A_state == state_area && AREA_STATE_CTRL_PTR->State2x.Area_A_State == state_2x)
{
boardID = AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID;
}
else if(AREA_STATE_CTRL_PTR->StateArea.Partner_Area_B_state == state_area && AREA_STATE_CTRL_PTR->State2x.Area_B_State == state_2x)
{
boardID = AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID;
}
else
{
AREA_LOG_MSG("Cant Find State:%d-%d\n", state_area, state_2x);
}
return boardID;
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef ARB_STATE_H_
#define ARB_STATE_H_
#include "SFM_2x2.h"
/**
* @brief 通过ID获取对应板卡区域状态
*/
ENUM_AREA_STATE Area_GetState_byID(CM_UINT8 ID);
/**
* @brief 通过ID设置对应板卡区域状态
*/
void Area_SetState_byID(CM_UINT8 ID, ENUM_AREA_STATE state);
/**
* @brief 通过ID获取对应板卡2x状态
*/
ENUM_2x2_STATE_T Area_Get2xState_byID(CM_UINT8 ID);
/**
* @brief 通过ID设置对应板卡2x状态
*/
void Area_Set2xState_byID(CM_UINT8 ID, ENUM_2x2_STATE_T state);
/**
* @brief 通过状态获取某个板卡ID
* @return 0表示无该板卡
*/
CM_UINT8 Area_GetID_byState(ENUM_AREA_STATE* state_area, ENUM_2x2_STATE_T* state_2x);
#endif
+6 -10
View File
@@ -28,18 +28,15 @@
#define MSCP_MSG_AREA_RSP_TYPE 0x02 /**< 区域通信响应消息类型 */
#define MSCP_MSG_DEST_ALL 0xFF /**< 所有设备接收消息类型 */
#define Area_MSG_NUM_MAX (200u)
#define Area_RAW_MSG_SIZE (2048u)
#define AREA_TIME_MAX 30u
typedef struct
{
CM_UINT32 BoardID; /**< 板卡ID 插箱id */
CM_UINT32 Cpuid; /**< cpu id */
CM_UINT32 Partner_BoardID; /**< 对系板卡id */
CM_UINT32 Partner_Area_A_BoardID; /**< 对系id */
CM_UINT32 Partner_Area_B_BoardID; /**< 对系id */
CM_UINT8 BoardID; /**< 板卡ID 插箱id */
CM_UINT8 Cpuid; /**< cpu id */
CM_UINT8 Partner_BoardID; /**< 对系板卡id */
CM_UINT8 Partner_Area_A_BoardID; /**< 对系id */
CM_UINT8 Partner_Area_B_BoardID; /**< 对系id */
STR_Area_IP_Cfg IP_Cfg_Area_A; /**< IP配置 */
STR_Area_IP_Cfg IP_Cfg_Area_B; /**< IP配置 */
}STR_Area_Cfg;
@@ -80,7 +77,6 @@ void net_state_cal();
*/
void Area_Req_Pack(STR_Area_Req *p_Area_Req, CM_UINT8 *p_buf, CM_UINT16 BufSize, CM_UINT16 *p_len);
void get_Other_BoardId(CM_UINT32 local_Board_Id, CM_UINT32 *partner_Board_Id, CM_UINT32 *partner_Area_A_Board_Id, CM_UINT32 *partner_Area_B_Board_Id);
STR_Area_State_Ctl g_Area_Status_Ctl[8] = {0};
static STR_Area_Ctl g_Area_Ctl ={0};
@@ -121,7 +117,7 @@ void Area_init()
CM_Thread_Create(NULL, (CM_THREAD_FUNC_T)Area_Work_Thread, "Area_Work_Thread", 4096*100, CM_TASK_PRIORITY_73, NULL);
}
void get_Other_BoardId(CM_UINT32 local_Board_Id, CM_UINT32 *partner_Board_Id, CM_UINT32 *partner_Area_A_Board_Id, CM_UINT32 *partner_Area_B_Board_Id)
void get_Other_BoardId(CM_UINT8 local_Board_Id, CM_UINT8 *partner_Board_Id, CM_UINT8 *partner_Area_A_Board_Id, CM_UINT8 *partner_Area_B_Board_Id)
{
if(NULL == partner_Board_Id || NULL == partner_Area_A_Board_Id || NULL == partner_Area_B_Board_Id)
{
+6 -4
View File
@@ -13,10 +13,10 @@
typedef struct
{
ENUM_AREA_STATE Local_state;/**< 区域状态*/
ENUM_AREA_STATE Partner_state;/**< 区域状态*/
ENUM_AREA_STATE Partner_Area_A_state;/**< 区域状态*/
ENUM_AREA_STATE Partner_Area_B_state;/**< 区域状态*/
ENUM_AREA_STATE Local_state;/**< 本系区域状态*/
ENUM_AREA_STATE Partner_state;/**< 对系区域状态*/
ENUM_AREA_STATE Partner_Area_A_state;/**< 另一地A区域状态*/
ENUM_AREA_STATE Partner_Area_B_state;/**< 另一地B区域状态*/
}STR_Area_State;
/**
* @brief 区域开始
@@ -68,6 +68,8 @@ CM_UINT32 Area_GetArea_A_ID(void);
CM_UINT32 Area_GetArea_B_ID(void);
void get_Other_BoardId(CM_UINT8 local_Board_Id, CM_UINT8 *partner_Board_Id, CM_UINT8 *partner_Area_A_Board_Id, CM_UINT8 *partner_Area_B_Board_Id);
/*日志转换*/
void Area_LOG_Transition(void);
#endif /* AREA_AREA_H_ */
+4
View File
@@ -1,9 +1,12 @@
#include "CM_Types.h"
#include "CFM_Net.h"
#include "CM_MQ.h"
#include "PFM_Log.h"
#include "CM_MultiThread.h"
#define NET_UDP_BUF_MAX ((1024*256) - (1)) /*UDP协议栈缓冲区大小(用于接收代码)*/
#define Area_MSG_NUM_MAX (200u)
#define Area_RAW_MSG_SIZE (2048u)
typedef struct
{
@@ -25,6 +28,7 @@
CM_UINT16 port; /**< 端口号 */
CM_MQ_Struct_T MsgQ; /**< 接收消息队列 */
}STR_Area_IP_Cfg;
CM_THREAD_FUNC_T t_Area_2oo2_UdpRecvThread(IN CM_Thread_Arg_Struct_T* arg);
CM_THREAD_FUNC_T t_Area_UdpRecvThread(IN STR_Area_IP_Cfg* arg);
+3
View File
@@ -180,6 +180,7 @@ ENUM_CM_RETURN CM_UDP_Socket_Create(OUT CM_SOCKET* pSock, IN CM_BOOL isNonBlockM
ENUM_CM_RETURN retError = ENUM_CM_FALSE; /* 临时返回值 */
struct ip_mreq multiCast; /* 组播配置 */
CM_INT32 bCast = 1;
CM_UINT8 loop; /* 0 = disable, 1 = enable (default) */
/*- 是否UDP服务未初始化或输入非法 */
if ((CM_TRUE != s_UDP_Initialized) || (NULL == pSock))
{
@@ -209,6 +210,8 @@ ENUM_CM_RETURN CM_UDP_Socket_Create(OUT CM_SOCKET* pSock, IN CM_BOOL isNonBlockM
/*组播发送*/
addrHost.sin_addr.s_addr = addrIP;
(void)setsockopt(*pSock, IPPROTO_IP, IP_MULTICAST_IF, &addrHost.sin_addr, sizeof(addrHost.sin_addr));
loop = 0u;
(void)setsockopt(*pSock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
break;
case ENUM_MULTICAST_RCV:
/*组播接收*/
+10 -2
View File
@@ -203,6 +203,8 @@ void PFM_CFG_Init(void)
(void)strcpy(g_PFM_Cfg.CPU_CFG[cpuID].IP_Area,g_AppCfgInterface.CPU[cpuID-1].IP_Area);
g_PFM_Cfg.CPU_CFG[cpuID].Port_Area_State = 52010;/*4x2区域通信端口,双网卡共用*/
g_PFM_Cfg.CPU_CFG[cpuID].Port_Area_Send = 52011;/*主地组播发送端口*/
g_PFM_Cfg.CPU_CFG[cpuID].Port_Area_Recv = 52012;/*主地组播接收端口*/
(void)strcpy(g_PFM_Cfg.CPU_CFG[cpuID].IP_Sync_Time_A, g_AppCfgInterface.CPU[cpuID-1].IP_Sync_Time_A);
(void)strcpy(g_PFM_Cfg.CPU_CFG[cpuID].IP_Sync_Time_B, g_AppCfgInterface.CPU[cpuID-1].IP_Sync_Time_B);
@@ -310,6 +312,7 @@ void PFM_CFG_Init(void)
(void)strcpy(g_PFM_Cfg.CC_B_IP,g_AppCfgInterface.OutNetBlue.CC_G_IP_A);
(void)strcpy(g_PFM_Cfg.EXTEND_R_IP,g_AppCfgInterface.OutNetRed.EXTEND_G_IP_A);
(void)strcpy(g_PFM_Cfg.EXTEND_B_IP,g_AppCfgInterface.OutNetBlue.EXTEND_G_IP_A);
(void)strcpy(g_PFM_Cfg.Arb_CFG.IP_Arb,g_AppCfgInterface.Arb_CFG.IP_Arb_G);
}
else if(((CM_UINT8)2u == g_PFM_Cfg.CPU_ID) && (((CM_UINT8)1u == g_PFM_Cfg.BOARD_ID) || ((CM_UINT8)2u == g_PFM_Cfg.BOARD_ID)))
@@ -320,6 +323,7 @@ void PFM_CFG_Init(void)
(void)strcpy(g_PFM_Cfg.CC_B_IP,g_AppCfgInterface.OutNetBlue.CC_P_IP_A);
(void)strcpy(g_PFM_Cfg.EXTEND_R_IP,g_AppCfgInterface.OutNetRed.EXTEND_P_IP_A);
(void)strcpy(g_PFM_Cfg.EXTEND_B_IP,g_AppCfgInterface.OutNetBlue.EXTEND_P_IP_A);
(void)strcpy(g_PFM_Cfg.Arb_CFG.IP_Arb,g_AppCfgInterface.Arb_CFG.IP_Arb_P);
}
else if(((CM_UINT8)1u == g_PFM_Cfg.CPU_ID) && (((CM_UINT8)3u == g_PFM_Cfg.BOARD_ID) || ((CM_UINT8)4u == g_PFM_Cfg.BOARD_ID)))
{
@@ -329,6 +333,7 @@ void PFM_CFG_Init(void)
(void)strcpy(g_PFM_Cfg.CC_B_IP,g_AppCfgInterface.OutNetBlue.CC_G_IP_B);
(void)strcpy(g_PFM_Cfg.EXTEND_R_IP,g_AppCfgInterface.OutNetRed.EXTEND_G_IP_B);
(void)strcpy(g_PFM_Cfg.EXTEND_B_IP,g_AppCfgInterface.OutNetBlue.EXTEND_G_IP_B);
(void)strcpy(g_PFM_Cfg.Arb_CFG.IP_Arb,g_AppCfgInterface.Arb_CFG.IP_Arb_G);
}
else if(((CM_UINT8)2u == g_PFM_Cfg.CPU_ID) && (((CM_UINT8)3u == g_PFM_Cfg.BOARD_ID) || ((CM_UINT8)4u == g_PFM_Cfg.BOARD_ID)))
{
@@ -338,14 +343,15 @@ void PFM_CFG_Init(void)
(void)strcpy(g_PFM_Cfg.CC_B_IP,g_AppCfgInterface.OutNetBlue.CC_P_IP_B);
(void)strcpy(g_PFM_Cfg.EXTEND_R_IP,g_AppCfgInterface.OutNetRed.EXTEND_P_IP_B);
(void)strcpy(g_PFM_Cfg.EXTEND_B_IP,g_AppCfgInterface.OutNetBlue.EXTEND_P_IP_B);
(void)strcpy(g_PFM_Cfg.Arb_CFG.IP_Arb,g_AppCfgInterface.Arb_CFG.IP_Arb_P);
}
else
{
MSCP_LOG_MSG("PFM Get Logger and CC IP fail\n");
CM_ASSERT(0,0,0,0);
}
MSCP_LOG_MSG("Logger_IP:%s\n CC_R_IP:%s\n CC_B_IP:%s\n EXTEND_R_IP:%s\n EXTEND_B_IP:%s",g_PFM_Cfg.Logger_IP,\
g_PFM_Cfg.CC_R_IP, g_PFM_Cfg.CC_B_IP, g_PFM_Cfg.EXTEND_R_IP, g_PFM_Cfg.EXTEND_B_IP);
MSCP_LOG_MSG("Logger_IP:%s\n CC_R_IP:%s\n CC_B_IP:%s\n EXTEND_R_IP:%s\n EXTEND_B_IP:%s\n, ARB_IP:%s",g_PFM_Cfg.Logger_IP,\
g_PFM_Cfg.CC_R_IP, g_PFM_Cfg.CC_B_IP, g_PFM_Cfg.EXTEND_R_IP, g_PFM_Cfg.EXTEND_B_IP, g_PFM_Cfg.Arb_CFG.IP_Arb);
/*- 读取通控的端口配置 */
g_PFM_Cfg.CC_R_OutnetSafe_Port = g_AppCfgInterface.OutNetRed.OutnetSafe_Port;
@@ -357,6 +363,7 @@ void PFM_CFG_Init(void)
g_PFM_Cfg.CC_B_OutnetRaw_Port = g_AppCfgInterface.OutNetBlue.OutnetRaw_Port;
g_PFM_Cfg.CC_B_InnetRaw_Port = g_AppCfgInterface.OutNetBlue.InnetRaw_Port;
g_PFM_Cfg.CC_B_Heart_Port = 53003;
g_PFM_Cfg.Arb_CFG.Port_Arb = 56001;
MSCP_LOG_MSG("CC_R_IP:%s\n",g_PFM_Cfg.CC_R_IP);
MSCP_LOG_MSG("CC_B_IP:%s\n",g_PFM_Cfg.CC_B_IP);
MSCP_LOG_MSG("EXTEND_R_IP:%s\n",g_PFM_Cfg.EXTEND_R_IP);
@@ -367,6 +374,7 @@ void PFM_CFG_Init(void)
MSCP_LOG_MSG("CC_B_OutnetSafe_Port:%d\n",g_PFM_Cfg.CC_B_OutnetSafe_Port);
MSCP_LOG_MSG("CC_B_OutnetRaw_Port:%d\n",g_PFM_Cfg.CC_B_OutnetRaw_Port);
MSCP_LOG_MSG("CC_B_InnetRaw_Port:%d\n",g_PFM_Cfg.CC_B_InnetRaw_Port);
MSCP_LOG_MSG("ARB_Port:%d\n", g_PFM_Cfg.Arb_CFG.Port_Arb);
(void)CFM_DarkLog_Multiple(DARK_LOG_HEX, TSCP_DARK_PFMCFG_INIT3, 8, \
sizeof(CM_UINT16),g_PFM_Cfg.CC_R_OutnetSafe_Port,
+21
View File
@@ -93,6 +93,8 @@ extern CM_UINT8 TSCP_QNX_VERION[10]; /** 操作系统版本号 */
CM_CHAR IP_Area[32]; /**< 区域通信IP */
CM_UINT16 Port_Area_State; /**< 4x2区域状态交互端口 */
CM_UINT16 Port_Area_Send; /**< 组播发送端口 */
CM_UINT16 Port_Area_Recv; /**< 组播接收端口 */
CM_CHAR IP_Sync_Time_A[32]; /**< 校时A通信IP */
CM_CHAR IP_Sync_Time_B[32]; /**< 校时B通信IP */
@@ -119,6 +121,18 @@ extern CM_UINT8 TSCP_QNX_VERION[10]; /** 操作系统版本号 */
CM_UINT16 Port_Remote_Update; /**< 远程部署通信端口 */
}STRU_PFM_CPU_CFG_T;
typedef struct
{
CM_CHAR IP_Arb_G[32];
CM_CHAR IP_Arb_P[32];
}STRU_APP_ARB_CFG_T;
typedef struct
{
CM_CHAR IP_Arb[32];
CM_UINT16 Port_Arb;
}STRU_PFM_ARB_CFG_T;
/** 内网通信配置 */
typedef struct
{
@@ -161,6 +175,7 @@ extern CM_UINT8 TSCP_QNX_VERION[10]; /** 操作系统版本号 */
CM_UINT32 M_OutnetRaw_Enable;/**< 外网透传通信功能开关 */
CM_UINT8 M_CpuUsageGet_Enable; /**< CPU使用率获取功能开关 */
CM_UINT32 M_RemoteUpdate_Enable; /**< 远程部署内网安全通信功能开关 */
CM_UINT8 M_Arb_Enable; /**< 仲裁功能开关 */
CM_CHAR Start_Path[32]; /**< 程序启动路径 */
CM_INT32 reboot_replycount; /**< 重启确认报文回复次数 */
CM_UINT8 M_AutoReboot_Count; /**< 自动重启次数 */
@@ -186,6 +201,8 @@ extern CM_UINT8 TSCP_QNX_VERION[10]; /** 操作系统版本号 */
CM_UINT16 CC_B_InnetRaw_Port; /**< 蓝网CC的内网透传通信端口 */
CM_UINT16 CC_B_Heart_Port; /**< 蓝网CC的内网透传通信端口 */
STRU_PFM_ARB_CFG_T Arb_CFG;
CM_CHAR Logger_IP[32]; /**< 日志记录IP */
CM_UINT16 Logger_PortBase; /**< 明文日志对端端口 */
CM_UINT16 Logger_PortCiphertext; /**< 暗文日志对端端口 */
@@ -259,6 +276,7 @@ extern CM_UINT8 TSCP_QNX_VERION[10]; /** 操作系统版本号 */
CM_UINT32 M_2oo2_Enable; /**< 2oo2功能开关 */
CM_UINT32 M_2x2_Enable; /**< 2x2功能开关*/
CM_UINT32 M_4x2_Enable; /**< 4x2功能开关*/
CM_UINT8 M_Arb_Enable; /**< 仲裁功能开关 */
CM_UINT32 M_2x2_Com_Cfg; /**< 2x2配置功能开关*/
CM_UINT32 M_InnetSafe_Enable; /**< 内网安全通信功能开关 */
CM_UINT32 M_InnetRaw_Enable; /**< 内网透传通信功能开关 */
@@ -293,6 +311,9 @@ extern CM_UINT8 TSCP_QNX_VERION[10]; /** 操作系统版本号 */
CM_CHAR Logger_G_IP_B[32]; /**< B地绿网日志记录IP */
CM_CHAR Logger_P_IP_B[32]; /**< B地紫网日志记录IP */
/* 第三方仲裁通信配置*/
STRU_APP_ARB_CFG_T Arb_CFG;
/*内网通信设备注册最大支持0-254*/
CM_UINT16 INNET_COM_NUM; /**< 内网通信设备数量 */
STRU_PFM_INNET_CFG_T INNET_COM_CFG[255]; /**< 内网通信设备通信配置(数组0-254有效) */
+16
View File
@@ -3612,5 +3612,21 @@ CM_UINT8 SFM_GetLocalCCHealth(void)
{
return s_2x2_state_Ctrl.LocalCC_Health;
}
/**
* @brief 获取2乘线程中的(s_2x2_state_ctrl)中的2乘状态
* @param localstate 获取到的本系状态
* @param partnerstate 获取到的另一系状态
*/
void SFM_2x2_GetStateAfterStateChange(OUT ENUM_2x2_STATE_T *localstate, OUT ENUM_2x2_STATE_T *partnerstate)
{
if(NULL != localstate)
{
*localstate = s_2x2_state_Ctrl.LocalState;
}
if(NULL != partnerstate)
{
*partnerstate = s_2x2_state_Ctrl.PartnerState;
}
}
+7
View File
@@ -561,6 +561,13 @@ extern CM_UINT32 g_MSCP_SysCount;
/*获取通控健康度 >0 为健康*/
CM_UINT8 SFM_GetLocalCCHealth(void);
/**
* @brief 获取2乘线程中的(s_2x2_state_ctrl)中的2乘状态
* @param localstate 获取到的本系状态
* @param partnerstate 获取到的另一系状态
*/
void SFM_2x2_GetStateAfterStateChange(OUT ENUM_2x2_STATE_T *localstate, OUT ENUM_2x2_STATE_T *partnerstate);
#ifdef __cplusplus
}