4 Commits

Author SHA1 Message Date
lh 2b9c6c8c83 1.4线模式和仲裁模式的通用接口封装
2.离线系拉低主地/备地为离线地
3.修复仲裁IP配置错误
2026-08-27 14:46:23 +08:00
lh ca6366a59b 组播接收后做2取交互,组播接收的数据不作用于通信状态判断 2026-08-25 20:05:05 +08:00
lh f70644f743 等待时间使用宏定义 2026-08-24 17:14:17 +08:00
lh 2bd874bd40 1.增加阶段时间打印
2.修改超时接收逻辑
3.增加未知地->离线地逻辑
2026-08-24 16:25:16 +08:00
13 changed files with 411 additions and 266 deletions
+219 -213
View File
@@ -8,16 +8,32 @@
#include "Arb_State.h"
#include "CFM_Sync.h"
#include "Arb_State_Vote.h"
#include "CM_Convert.h"
/*===========↓↓↓↓↓全局变量声明&定义↓↓↓↓↓=============*/
STRU_AREA_WITH_ARB_CFG_ALL_T g_area_with_arb_cfg = {0};
static CM_UINT64 s_area_arb_start_time = 0u;
STRU_AREA_WITH_ARB_CFG_ALL_T g_area_with_arb_cfg = {0}; /**区域控制信息汇总 */
/*===========↑↑↑↑↑全局变量声明&定义↑↑↑↑↑=============*/
/*===========↓↓↓↓↓宏定义↓↓↓↓↓=============*/
#define AREA_ARB_NOW_USED_TIME ((CM_GetTick() - s_area_arb_start_time) / CM_UNSIGNED_MILLION) /**记录区域线程耗时 */
#define AREA_STATE_WAITE_TIME (30u - 7u) /**区域状态请求/应答接收超时时间,30ms减去一次2取耗时 */
#define AREA_ARB_WAITE_TIME (20u) /**仲裁应答时间 */
#define AREA_MULTI_WAITE_TIME (10u) /**组播等待时间 */
/*===========↑↑↑↑↑宏定义↑↑↑↑↑=============*/
/*===========↓↓↓↓↓静态函数声明↓↓↓↓↓=============*/
/**
* @brief 根据已打包的线路报文计算并同步双CRC
*/
static void s_Area_DoubleCRC_Get(IN const CM_UINT8* buf, IN CM_UINT32 len,
OUT CM_UINT32* crc1, OUT CM_UINT32* crc2);
/**
* @brief 地间状态帧组包、计算CRC并发送
*/
static ENUM_CM_RETURN s_Area_State_Pack_Send(INOUT STRU_AREA_WITH_ARB_STATE_PACK_T* state_pack);
/**
* @brief 区域工作线程(带仲裁)
*/
@@ -72,18 +88,13 @@ 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取同步
* @param ack_flags 记录是否需要进行ACK回复
* @param time 记录当前所用时间,2取后双CPU同时退出循环
* @return 2取另一CPU所用时间
*/
static void s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5]);
static CM_UINT32 s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5], CM_UINT32 time);
/**
* @brief 2取同步后,判断本周期是否收到请求,并进行回复组包发送
* @param ack_partner 是否需要向对系回复ACK
@@ -99,47 +110,7 @@ static void s_Area_2oo2Sync_AfterArbRecv();
/*===========↓↓↓↓↓函数定义↓↓↓↓↓↓=============*/
/**
* @brief 根据已打包的线路报文计算并同步双CRC
*/
static void s_Area_DoubleCRC_Get(IN const CM_UINT8* buf, IN CM_UINT32 len,
OUT CM_UINT32* crc1, OUT CM_UINT32* crc2)
{
CM_UINT32 local_crc[2] = {0u, 0u};
CM_UINT32 peer_crc[2] = {0u, 0u};
CM_INT32 rcv_len = 0;
if((NULL == buf) || (NULL == crc1) || (NULL == crc2) || (len < 9u))
{
CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
return;
}
if(1u == AREA_BASIC_CFG_PTR->Cpuid)
{
local_crc[0] = CM_Crc32_1(&buf[1], len - 9u);
}
else
{
local_crc[1] = CM_Crc32_2(&buf[1], len - 9u);
}
rcv_len = Area_2oo2_Currency_NoSplit((const CM_UINT8*)local_crc,
sizeof(local_crc), (CM_UINT8*)peer_crc, sizeof(peer_crc));
CM_ASSERT(rcv_len == sizeof(local_crc), NET_MODE,
DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
if(1u == AREA_BASIC_CFG_PTR->Cpuid)
{
local_crc[1] = peer_crc[1];
}
else
{
local_crc[0] = peer_crc[0];
}
*crc1 = local_crc[0];
*crc2 = local_crc[1];
}
/**
* 区域初始化,包含第三方仲裁的初始化
@@ -190,37 +161,51 @@ static CM_THREAD_FUNC_T s_Area_With_Arb_Work_Thread(IN CM_Thread_Arg_Struct_T* a
{
/* 绑定内核 */
void* pmask = NULL;
CM_UINT64 stage_start = 0u;
pmask = (void*)(0x01u|0x02u);
(void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
/* 情况缓冲区 */
/* 清空缓冲区 */
Area_Arb_ClearMsgQ();
/* 线程循环 */
while(1)
{
Area_Arb_Wait_Start();
s_area_arb_start_time = CM_GetTick();
/**清空上周期的接收状态,并获取2乘线程中的最终状态 */
s_Area_Cycle_Init();
AREA_LOG_MSG("AREA_ARB:Cycle start, BoardID:%d SN:%u State:%d 2x2:%d\n",
AREA_LOG_MSG("AREA_ARB:Cycle start, BoardID:%d SN:%u State:%d 2x2:%d, NOW_USED_TIME:%llums\n",
AREA_BASIC_CFG_PTR->BoardID, DFM_GetBirthCount(),
AREA_STATE_CTRL_PTR->StateArea.Local_state,
AREA_STATE_CTRL_PTR->State2x.LocalState);
AREA_STATE_CTRL_PTR->State2x.LocalState,NOW_USED_TIME / 1000u);
/**主地主组播发送状态帧,其余板卡接收 */
stage_start = CM_GetTick();
s_Area_State_Multi_Process();
AREA_LOG_MSG("AREA_ARB:State multicast stage cost:%llums, AREA_ARB_NOW_USED_TIME:%llums\n",
(CM_GetTick() - stage_start) / CM_UNSIGNED_MILLION, AREA_ARB_NOW_USED_TIME);
/**主地双系/初始化阶段发送状态请求帧 */
stage_start = CM_GetTick();
s_Area_State_Req_Send_Process();
AREA_LOG_MSG("AREA_ARB:State request send stage cost:%llums, AREA_ARB_NOW_USED_TIME:%llums\n",
(CM_GetTick() - stage_start) / CM_UNSIGNED_MILLION, AREA_ARB_NOW_USED_TIME);
/**对应答帧的处理 */
stage_start = CM_GetTick();
s_Area_State_Ack_Process();
AREA_LOG_MSG("AREA_ARB:State request/ACK stage cost:%llums, AREA_ARB_NOW_USED_TIME:%llums\n",
(CM_GetTick() - stage_start) / CM_UNSIGNED_MILLION, AREA_ARB_NOW_USED_TIME);
/**仲裁请求发送/接收的处理 */
stage_start = CM_GetTick();
s_Area_Arb_Process();
AREA_LOG_MSG("AREA_ARB:Arbitration request/ACK stage cost:%llums, AREA_ARB_NOW_USED_TIME:%llums\n",
(CM_GetTick() - stage_start) / CM_UNSIGNED_MILLION, AREA_ARB_NOW_USED_TIME);
/**状态转移 */
s_Area_Arb_State_Transition();
AREA_LOG_MSG("AREA_ARB:Cycle end, SN:%u State:%d 2x2:%d RcvFlag:%d-%d-%d Arb:%d-0x%x\n",
AREA_LOG_MSG("AREA_ARB:Cycle end, SN:%u State:%d 2x2:%d RcvFlag:%d-%d-%d Arb:%d-0x%x, AREA_ARB_USED_TIME:%llums, NOW_USED_TIME:%llums\n",
AREA_COMM_STATUS_PTR->LocalSN, AREA_STATE_CTRL_PTR->StateArea.Local_state,
AREA_STATE_CTRL_PTR->State2x.LocalState,
AREA_COMM_STATUS_PTR->Patner_RcvFlag, AREA_COMM_STATUS_PTR->Area_A_RcvFlag,
AREA_COMM_STATUS_PTR->Area_B_RcvFlag, AREA_ARB_CTRL_PTR->Arb_Send_Flag,
AREA_ARB_CTRL_PTR->Arb_Ack);
AREA_ARB_CTRL_PTR->Arb_Ack, AREA_ARB_NOW_USED_TIME, NOW_USED_TIME / 1000u);
Area_Arb_Stop();
}
@@ -289,9 +274,7 @@ static void s_Area_State_Multi_Process(void)
static void s_Area_State_Req_Send_Process(void)
{
STRU_AREA_WITH_ARB_STATE_PACK_T state_pack = {0};
CM_INT32 tmp_len = 0;
ENUM_CM_RETURN send_rt = ENUM_CM_FALSE;
CM_UINT8 tmp_buf[1400] = {0u};
/**发送帧初始化 */
state_pack.Len = AREA_ARB_STATE_PACK_LEN - 1u;
state_pack.MsgType = ENUM_AREA_MSG_STATE_REQ;
@@ -310,57 +293,21 @@ static void s_Area_State_Req_Send_Process(void)
/**未知地主系(仅A地),刚上电,向其他三系发送请求 */
/**发送至本地另一系 */
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_LEN == tmp_len)
{
s_Area_DoubleCRC_Get(tmp_buf, (CM_UINT32)tmp_len, &state_pack.CRC1, &state_pack.CRC2);
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
send_rt = Area_State_Send(AREA_BASIC_CFG_PTR->Partner_BoardID, tmp_buf, tmp_len);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
}
else
{
AREA_LOG_MSG("AREA_ARB:State request pack failed, DstID:%d Len:%d\n",
state_pack.DstID, tmp_len);
}
send_rt = s_Area_State_Pack_Send(&state_pack);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
/**发送至另一地的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_LEN == tmp_len)
{
s_Area_DoubleCRC_Get(tmp_buf, (CM_UINT32)tmp_len, &state_pack.CRC1, &state_pack.CRC2);
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
send_rt = Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID, tmp_buf, tmp_len);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
}
else
{
AREA_LOG_MSG("AREA_ARB:State request pack failed, DstID:%d Len:%d\n",
state_pack.DstID, tmp_len);
}
send_rt = s_Area_State_Pack_Send(&state_pack);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
/**发送至另一地的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_LEN == tmp_len)
{
s_Area_DoubleCRC_Get(tmp_buf, (CM_UINT32)tmp_len, &state_pack.CRC1, &state_pack.CRC2);
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
send_rt = Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID, tmp_buf, tmp_len);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
}
else
{
AREA_LOG_MSG("AREA_ARB:State request pack failed, DstID:%d Len:%d\n",
state_pack.DstID, tmp_len);
}
send_rt = s_Area_State_Pack_Send(&state_pack);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
}
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)))
@@ -368,39 +315,15 @@ static void s_Area_State_Req_Send_Process(void)
/**主地主备系,周期运行阶段,向另一地发送请求 */
/**发送至另一地的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_LEN == tmp_len)
{
s_Area_DoubleCRC_Get(tmp_buf, (CM_UINT32)tmp_len, &state_pack.CRC1, &state_pack.CRC2);
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
send_rt = Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID, tmp_buf, tmp_len);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
}
else
{
AREA_LOG_MSG("AREA_ARB:State request pack failed, DstID:%d Len:%d\n",
state_pack.DstID, tmp_len);
}
send_rt = s_Area_State_Pack_Send(&state_pack);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
/**发送至另一地的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_LEN == tmp_len)
{
s_Area_DoubleCRC_Get(tmp_buf, (CM_UINT32)tmp_len, &state_pack.CRC1, &state_pack.CRC2);
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
send_rt = Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID, tmp_buf, tmp_len);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
}
else
{
AREA_LOG_MSG("AREA_ARB:State request pack failed, DstID:%d Len:%d\n",
state_pack.DstID, tmp_len);
}
send_rt = s_Area_State_Pack_Send(&state_pack);
AREA_LOG_MSG("AREA_ARB:State request send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
}
else
{
@@ -426,10 +349,11 @@ static void s_Area_State_Ack_Process(void)
CM_UINT8 area_b_id = AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID;
CM_UINT8 timeSyncFlag = AREA_FLAGS_CTRL_PTR->Time_Sync_Flag;
CM_BOOL ack_flags[5] = {CM_FALSE, CM_FALSE, CM_FALSE, CM_FALSE, CM_FALSE};
CM_UINT32 peer_time = 0u;
CM_UINT32 i = 0u;
/**持续30ms */
for(i = 0u;i<10;i++)
do
{
/**REQ与ACK共用一个FIFO,每条报文只读取一次并按类型分发。 */
do
@@ -465,13 +389,13 @@ static void s_Area_State_Ack_Process(void)
} while(0 < rcv_len);
/**同步接收状态和本周期ACK目标,再统一回复。 */
s_Area_2oo2Sync_AfterStateRecv(ack_flags);
used_time = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION) - start_tick;
peer_time = s_Area_2oo2Sync_AfterStateRecv(ack_flags, used_time);
s_Area_SendACK_After2oo2(ack_flags[partner_id], ack_flags[area_a_id], ack_flags[area_b_id]);
CM_Memset(ack_flags, 0, sizeof(ack_flags), sizeof(ack_flags));
CM_Sleep(2u);
used_time = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION) - start_tick;
}
CM_Sleep(1u);
}while(AREA_STATE_WAITE_TIME > peer_time && AREA_STATE_WAITE_TIME > used_time);
}
static void s_Area_State_Req_Recv_Process(IN const STRU_AREA_WITH_ARB_STATE_PACK_T* state_pack,
@@ -484,15 +408,15 @@ static void s_Area_State_Req_Recv_Process(IN const STRU_AREA_WITH_ARB_STATE_PACK
return;
}
s_Area_GetCommStatus_byID(state_pack->SrcID, &last_sn, NULL);
if(state_pack->SN >= last_sn)
AreaArb_GetCommStatus_byID(state_pack->SrcID, &last_sn, NULL);
if(state_pack->SN > last_sn)
{
ack_flags[state_pack->SrcID] = CM_TRUE;
s_Area_SetCommStatus_byID(state_pack->SrcID, state_pack->SN, CM_TRUE);
AreaArb_SetCommStatus_byID(state_pack->SrcID, state_pack->SN, CM_TRUE);
AreaArb_SetState_byID(state_pack->SrcID, state_pack->StateArea);
AreaArb_Set2xState_byID(state_pack->SrcID, state_pack->State2x);
AREA_LOG_MSG("AREA_ARB:State request received, SrcID:%d SN:%u State:%d 2x2:%d\n",
state_pack->SrcID, state_pack->SN, state_pack->StateArea, state_pack->State2x);
AREA_LOG_MSG("AREA_ARB:State request received, SrcID:%d SN:%u State:%d 2x2:%d, AREA_ARB_NOW_USED_TIME:%llums\n",
state_pack->SrcID, state_pack->SN, state_pack->StateArea, state_pack->State2x, AREA_ARB_NOW_USED_TIME);
}
}
@@ -513,16 +437,16 @@ static void s_Area_State_Ack_Recv_Process(IN const STRU_AREA_WITH_ARB_STATE_PACK
if(((1u == time_sync_flag) && (state_pack->SN == local_sn)) ||
((0u == time_sync_flag) && (sn_diff <= 1u)))
{
s_Area_SetCommStatus_byID(state_pack->SrcID, state_pack->SN, CM_TRUE);
AreaArb_SetCommStatus_byID(state_pack->SrcID, state_pack->SN, CM_TRUE);
AreaArb_SetState_byID(state_pack->SrcID, state_pack->StateArea);
AreaArb_Set2xState_byID(state_pack->SrcID, state_pack->State2x);
AREA_LOG_MSG("AREA_ARB:State ACK received, SrcID:%d SN:%u State:%d 2x2:%d\n",
state_pack->SrcID, state_pack->SN, state_pack->StateArea, state_pack->State2x);
AREA_LOG_MSG("AREA_ARB:State ACK received, SrcID:%d SN:%u State:%d 2x2:%d, AREA_ARB_NOW_USED_TIME:%llums\n",
state_pack->SrcID, state_pack->SN, state_pack->StateArea, state_pack->State2x, AREA_ARB_NOW_USED_TIME);
}
else
{
AREA_LOG_MSG("AREA_ARB:State ACK recv failed, SrcID:%d SN:%u State:%d 2x2:%d\n",
state_pack->SrcID, state_pack->SN, state_pack->StateArea, state_pack->State2x);
AREA_LOG_MSG("AREA_ARB:State ACK recv failed, SrcID:%d SN:%u State:%d 2x2:%d, AREA_ARB_NOW_USED_TIME:%llums\n",
state_pack->SrcID, state_pack->SN, state_pack->StateArea, state_pack->State2x, AREA_ARB_NOW_USED_TIME);
}
}
@@ -533,7 +457,6 @@ static void s_Area_Arb_Process(void)
{
s_Area_Arb_Send_Process();
/**等待20ms仲裁回复 */
CM_Sleep(20u);
s_Area_Arb_Recv_Process();
}
/**
@@ -547,6 +470,7 @@ static void s_Area_Arb_Send_Process(void)
ENUM_AREA_STATE local_area_state = AREA_STATE_CTRL_PTR->StateArea.Local_state;
static CM_UINT32 tolerate_arb = 0u; /**仲裁请求容忍 */
ENUM_CM_RETURN send_rt = ENUM_CM_FALSE;
CM_BOOL flag_comm_mm_status = CM_FALSE;
/**请求帧帧基础信息组包 */
arb_pack.Len = AREA_ARB_FRAME_PACK_LEN - 1u;
arb_pack.MsgType = ENUM_AREA_MSG_ARB_REQ;
@@ -567,6 +491,8 @@ static void s_Area_Arb_Send_Process(void)
/**获取通信中断标志 */
CM_BOOL flag_comm_all_down = AREA_COMM_STATUS_PTR->Area_A_RcvFlag | AREA_COMM_STATUS_PTR->Area_B_RcvFlag; /**用于判断通信是否完全中断 */
CM_BOOL flag_comm_all_up = AREA_COMM_STATUS_PTR->Area_A_RcvFlag & AREA_COMM_STATUS_PTR->Area_B_RcvFlag; /**用于判断通信是否完全正常 */
/**获取主地主通信状态标志 */
AreaArb_GetCommStatus_byID(id_mm, NULL, &flag_comm_mm_status);
/**重置仲裁请求发送标志 */
AREA_ARB_CTRL_PTR->Arb_Send_Flag = 0u;
@@ -582,7 +508,7 @@ static void s_Area_Arb_Send_Process(void)
AREA_LOG_MSG("AREA_ARB:Request arbitration, master lost slave, BoardID:%d SN:%u Result:0x%x\n",
AREA_BASIC_CFG_PTR->BoardID, arb_pack.ArbSN, send_rt);
}
else if(ENUM_AREA_SLAVE == local_area_state && 0u == id_mm)
else if(ENUM_AREA_SLAVE == local_area_state && CM_FALSE == flag_comm_mm_status)
{
/**本地备地主,与主地主通信中断,容忍一周期发送请求 */
if(tolerate_arb >= 1u)
@@ -598,7 +524,7 @@ static void s_Area_Arb_Send_Process(void)
tolerate_arb++;
}
}
else if(ENUM_AREA_UNKNOW == local_area_state && CM_FALSE == flag_comm_all_down)
else if(ENUM_AREA_UNKNOW == local_area_state && CM_FALSE == flag_comm_all_up)
{
/**未知地主系,与另一地通信持续中断10周期,发送仲裁请求 */
if(tolerate_arb >= 10u)
@@ -633,45 +559,52 @@ 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_UINT8 tmp_buf[AREA_ARB_FRAME_PACK_LEN] = {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;
CM_UINT32 tick_now = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION);
CM_UINT32 tick_start = tick_now, used_time = 0u;
/**清空仲裁状态 */
AREA_ARB_CTRL_PTR->Arb_Ack = 0x00u;
/**仲裁请求接收 */
rcv_len = Area_Arb_Ack_Recv(tmp_buf, sizeof(tmp_buf));
/**解包处理 */
if(AREA_ARB_FRAME_PACK_LEN == rcv_len)
/**持续20ms循环接收仲裁应答 */
do
{
Area_Arb_Frame_UnPack(&arb_pack, tmp_buf, (CM_UINT32)rcv_len);
crc1 = CM_Crc32_1(&tmp_buf[1], (CM_UINT32)rcv_len - 9u);
crc2 = CM_Crc32_2(&tmp_buf[1], (CM_UINT32)rcv_len - 9u);
if(crc1 == arb_pack.CRC1 && crc2 == arb_pack.CRC2 &&
((AREA_ARB_FRAME_PACK_LEN - 1u) == arb_pack.Len) &&
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)
rcv_len = Area_Arb_Ack_Recv(tmp_buf, sizeof(tmp_buf));
/**解包处理 */
if(AREA_ARB_FRAME_PACK_LEN == rcv_len)
{
if(0x55 == arb_pack.ArbPayLoad)
Area_Arb_Frame_UnPack(&arb_pack, tmp_buf, (CM_UINT32)rcv_len);
crc1 = CM_Crc32_1(&tmp_buf[1], (CM_UINT32)rcv_len - 9u);
crc2 = CM_Crc32_2(&tmp_buf[1], (CM_UINT32)rcv_len - 9u);
if(crc1 == arb_pack.CRC1 && crc2 == arb_pack.CRC2 &&
((AREA_ARB_FRAME_PACK_LEN - 1u) == arb_pack.Len) &&
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)
{
/**允许升主 */
AREA_ARB_CTRL_PTR->Arb_Ack = 0x55u;
AREA_LOG_MSG("AREA_ARB:Arbitration ACK accepted, BoardID:%d SN:%d Payload:0x%x\n",
local_id, arb_pack.ArbSN, arb_pack.ArbPayLoad);
if(0x55 == arb_pack.ArbPayLoad)
{
/**允许升主 */
AREA_ARB_CTRL_PTR->Arb_Ack = 0x55u;
AREA_LOG_MSG("AREA_ARB:Arbitration ACK accepted, BoardID:%d SN:%d Payload:0x%x\n",
local_id, arb_pack.ArbSN, arb_pack.ArbPayLoad);
}
}
else
{
AREA_LOG_MSG("AREA_ARB:Invalid arbitration ACK, BoardID:%d SN:%d CRC:%08x-%08x/%08x-%08x\n",
arb_pack.Board_ID, arb_pack.ArbSN, crc1, arb_pack.CRC1, crc2, arb_pack.CRC2);
}
}
else
{
AREA_LOG_MSG("AREA_ARB:Invalid arbitration ACK, BoardID:%d SN:%d CRC:%08x-%08x/%08x-%08x\n",
arb_pack.Board_ID, arb_pack.ArbSN, crc1, arb_pack.CRC1, crc2, arb_pack.CRC2);
CM_Sleep(1u);
}
}
else if(0 < rcv_len)
{
AREA_LOG_MSG("AREA_ARB:Invalid arbitration ACK length, RecvLen:%d FrameLen:%d\n",
rcv_len, arb_pack.Len);
}
tick_now = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION);
used_time = tick_now - tick_start;
} while(AREA_ARB_WAITE_TIME > used_time);
s_Area_2oo2Sync_AfterArbRecv();
}
/**
@@ -748,6 +681,7 @@ static void s_Area_State_Multi_Recv_Process(void)
CM_UINT32 tickNow = (CM_UINT32)(CM_GetTick() / CM_UNSIGNED_MILLION);
CM_UINT32 tickStart = tickNow, usedTime = 0u;
CM_UINT32 tickRcv = 0u;
STRU_AREA_WITH_ARB_STATE_MULTI_PACK_T peer_pack = {0};
/*组播接收*/
/*双CRC校验*/
@@ -765,7 +699,7 @@ static void s_Area_State_Multi_Recv_Process(void)
((AREA_ARB_STATE_MULTI_PACK_LEN - 1u) == multi_pack.Len) &&
ENUM_AREA_MSG_STATE_MULTI == multi_pack.MsgType)
{
s_Area_SetCommStatus_byID(multi_pack.SrcID, multi_pack.SN, CM_TRUE);
/**此处仅设置主地主的状态,不作为与主地主通信状态的判断依据 */
AreaArb_SetState_byID(multi_pack.SrcID, multi_pack.StateArea);
AreaArb_Set2xState_byID(multi_pack.SrcID, multi_pack.State2x);
AREA_LOG_MSG("AREA_ARB:Multicast state received, SrcID:%d SN:%u State:%d 2x2:%d\n",
@@ -773,18 +707,26 @@ static void s_Area_State_Multi_Recv_Process(void)
}
else
{
/**接收失败清空结构体,等待2取同步 */
CM_Memset(&multi_pack, 0, sizeof(multi_pack), sizeof(multi_pack));
AREA_LOG_MSG("Multi Recv Crc Fail %08x-%08x, %08x-%08x\n",crc1, multi_pack.CRC1, crc2, multi_pack.CRC2);
}
}
else
{
AREA_LOG_MSG("AREA_ARB:Multicast state received, tickNow - tickRcv = %llums\n", tickNow - tickRcv);
CM_Sleep(1u);
}
usedTime = tickNow - tickStart;
CM_Sleep(1u);
} while (usedTime < 10u);
} while (AREA_MULTI_WAITE_TIME > usedTime);
/**对组播接收进行2取同步 */
Area_2oo2_Currency_NoSplit(&multi_pack, sizeof(multi_pack), &peer_pack, sizeof(peer_pack));
if(peer_pack.SN > multi_pack.SN)
{
/**邻机有最新数据 */
AREA_LOG_MSG("AREA_ARB: Multi Recv 2oo2 Sync, Peer-Mine:%d-%d\n", peer_pack.SN, multi_pack.SN);
AreaArb_SetState_byID(peer_pack.SrcID, peer_pack.StateArea);
AreaArb_Set2xState_byID(peer_pack.SrcID, peer_pack.State2x);
}
}
/**
@@ -826,7 +768,7 @@ 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)
void AreaArb_SetCommStatus_byID(CM_UINT8 ID, CM_UINT32 sn, CM_BOOL rcv_flag)
{
if(ID == AREA_BASIC_CFG_PTR->BoardID)
{
@@ -855,7 +797,7 @@ static void s_Area_SetCommStatus_byID(CM_UINT8 ID, CM_UINT32 sn, CM_BOOL rcv_fla
/**
* @brief 根据ID获取接收状态
*/
static void s_Area_GetCommStatus_byID(CM_UINT8 ID, CM_UINT32* sn, CM_UINT8* rcv_flag)
void AreaArb_GetCommStatus_byID(CM_UINT8 ID, CM_UINT32* sn, CM_BOOL* rcv_flag)
{
if(ID == AREA_BASIC_CFG_PTR->BoardID)
{
@@ -910,7 +852,7 @@ static void s_Area_GetCommStatus_byID(CM_UINT8 ID, CM_UINT32* sn, CM_UINT8* rcv_
/**
* @brief 对接收到的区域状态请求进行2取同步
*/
static void s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5])
static CM_UINT32 s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5], CM_UINT32 used_time)
{
STRU_AREA_WITH_ARB_COMM_STATUS_T peer_comm_status = {0};
STRU_AREA_WITH_ARB_STATE_CTRL_T peer_state_ctrl = {0};
@@ -921,6 +863,8 @@ static void s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5])
CM_UINT8 id = 0u;
CM_UINT8 send_buf [1400] = {0}, rcv_buf[1400];
CM_INT32 send_len = 0u, rcv_len = 0u;
CM_UINT32 rcv_offset = 0u;
CM_UINT32 peer_time = 0u;
/**将接收状态进行组包2取 */
if((NULL != ack_flags) &&
@@ -932,6 +876,8 @@ static void s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5])
send_len += len_state_ctrl;
CM_Memcpy(&send_buf[send_len], sizeof(send_buf) - send_len, ack_flags, len_ack_flags);
send_len += len_ack_flags;
CM_LongToChar(used_time, &send_buf[send_len]);
send_len += 4u;
}
rcv_len = Area_2oo2_Currency_NoSplit(send_buf, send_len, rcv_buf, sizeof(rcv_buf));
if(rcv_len != send_len)
@@ -941,9 +887,14 @@ static void s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5])
}
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,rcv_buf, len_comm_status);
CM_Memcpy(&peer_state_ctrl, len_state_ctrl,rcv_buf + len_comm_status, len_state_ctrl);
CM_Memcpy(peer_ack_flags, len_ack_flags, rcv_buf + len_comm_status + len_state_ctrl, len_ack_flags);
rcv_offset = 0u;
CM_Memcpy(&peer_comm_status, len_comm_status,&rcv_buf[rcv_offset], len_comm_status);
rcv_offset += len_comm_status;
CM_Memcpy(&peer_state_ctrl, len_state_ctrl,&rcv_buf[rcv_offset], len_state_ctrl);
rcv_offset += len_state_ctrl;
CM_Memcpy(peer_ack_flags, len_ack_flags, &rcv_buf[rcv_offset], len_ack_flags);
rcv_offset += len_ack_flags;
peer_time = CM_LongFromChar(&rcv_buf[rcv_offset]);
/**任一CPU收到请求,两个CPU都使用相同的ACK目标。 */
for(id = MSCP_AREA_A_BOARD_ID_A; id <= MSCP_AREA_B_BOARD_ID_B; id++)
@@ -1013,6 +964,8 @@ static void s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5])
{
/**接收到的对系序列号相同,或者本CPU为新数据,无操作*/
}
return peer_time;
}
/**
* @brief 2取同步后,判断本周期是否收到请求,并进行回复组包发送
@@ -1020,8 +973,6 @@ static void s_Area_2oo2Sync_AfterStateRecv(CM_BOOL ack_flags[5])
static void s_Area_SendACK_After2oo2(CM_BOOL ack_partner, CM_BOOL ack_area_a, CM_BOOL ack_area_b)
{
STRU_AREA_WITH_ARB_STATE_PACK_T state_pack = {0};
CM_UINT8 tmp_buf[1400] = {0};
CM_INT32 tmp_len = 0;
ENUM_CM_RETURN send_rt = ENUM_CM_FALSE;
/**发送帧初始化 */
state_pack.Len = AREA_ARB_STATE_PACK_LEN - 1u;
@@ -1038,42 +989,27 @@ static void s_Area_SendACK_After2oo2(CM_BOOL ack_partner, CM_BOOL ack_area_a, CM
/**接收到了对系的请求,组包回复 */
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);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
s_Area_DoubleCRC_Get(tmp_buf, (CM_UINT32)tmp_len, &state_pack.CRC1, &state_pack.CRC2);
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
send_rt = Area_State_Send(AREA_BASIC_CFG_PTR->Partner_BoardID, tmp_buf, tmp_len);
AREA_LOG_MSG("AREA_ARB:State ACK send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
send_rt = s_Area_State_Pack_Send(&state_pack);
AREA_LOG_MSG("AREA_ARB:State ACK send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x, AREA_ARB_NOW_USED_TIME:%llums\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt, AREA_ARB_NOW_USED_TIME);
}
if(CM_TRUE == AREA_COMM_STATUS_PTR->Area_A_RcvFlag && CM_TRUE == ack_area_a)
{
/**接收到了另一地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);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
s_Area_DoubleCRC_Get(tmp_buf, (CM_UINT32)tmp_len, &state_pack.CRC1, &state_pack.CRC2);
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
send_rt = Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID, tmp_buf, tmp_len);
AREA_LOG_MSG("AREA_ARB:State ACK send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
send_rt = s_Area_State_Pack_Send(&state_pack);
AREA_LOG_MSG("AREA_ARB:State ACK send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x, AREA_ARB_NOW_USED_TIME:%llums\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt, AREA_ARB_NOW_USED_TIME);
}
if(CM_TRUE == AREA_COMM_STATUS_PTR->Area_B_RcvFlag && CM_TRUE == ack_area_b)
{
/**接收到了另一地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);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
s_Area_DoubleCRC_Get(tmp_buf, (CM_UINT32)tmp_len, &state_pack.CRC1, &state_pack.CRC2);
tmp_len = Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), &state_pack);
CM_ASSERT(AREA_ARB_STATE_PACK_LEN == tmp_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
send_rt = Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID, tmp_buf, tmp_len);
AREA_LOG_MSG("AREA_ARB:State ACK send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt);
send_rt = s_Area_State_Pack_Send(&state_pack);
AREA_LOG_MSG("AREA_ARB:State ACK send, DstID:%d SN:%u State:%d 2x2:%d Result:0x%x, AREA_ARB_NOW_USED_TIME:%llums\n",
state_pack.DstID, state_pack.SN, state_pack.StateArea, state_pack.State2x, send_rt, AREA_ARB_NOW_USED_TIME);
}
}
/**
@@ -1101,3 +1037,73 @@ static void s_Area_2oo2Sync_AfterArbRecv()
peer_ctrl.Arb_Ack);
}
}
/**
* @brief 地间状态帧组包、计算CRC并发送
*/
static ENUM_CM_RETURN s_Area_State_Pack_Send(INOUT STRU_AREA_WITH_ARB_STATE_PACK_T* state_pack)
{
CM_UINT8 tmp_buf[AREA_ARB_STATE_PACK_LEN] = {0u};
/**第一次打包用于计算双CRC */
(void)Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), state_pack);
s_Area_DoubleCRC_Get(tmp_buf, AREA_ARB_STATE_PACK_LEN, &state_pack->CRC1, &state_pack->CRC2);
/**第二次打包用于发送 */
(void)Area_Arb_State_Pack(tmp_buf, sizeof(tmp_buf), state_pack);
return Area_State_Send(state_pack->DstID, tmp_buf, AREA_ARB_STATE_PACK_LEN);
}
/**
* @brief 根据已打包的线路报文计算并同步双CRC
*/
static void s_Area_DoubleCRC_Get(IN const CM_UINT8* buf, IN CM_UINT32 len,
OUT CM_UINT32* crc1, OUT CM_UINT32* crc2)
{
CM_UINT32 local_crc[2] = {0u, 0u};
CM_UINT32 peer_crc[2] = {0u, 0u};
CM_INT32 rcv_len = 0;
if((NULL == buf) || (NULL == crc1) || (NULL == crc2) || (len < 9u))
{
CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
return;
}
if(1u == AREA_BASIC_CFG_PTR->Cpuid)
{
local_crc[0] = CM_Crc32_1(&buf[1], len - 9u);
}
else
{
local_crc[1] = CM_Crc32_2(&buf[1], len - 9u);
}
rcv_len = Area_2oo2_Currency_NoSplit((const CM_UINT8*)local_crc,
sizeof(local_crc), (CM_UINT8*)peer_crc, sizeof(peer_crc));
CM_ASSERT(rcv_len == sizeof(local_crc), NET_MODE,
DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
if(1u == AREA_BASIC_CFG_PTR->Cpuid)
{
local_crc[1] = peer_crc[1];
}
else
{
local_crc[0] = peer_crc[0];
}
*crc1 = local_crc[0];
*crc2 = local_crc[1];
}
/**
* @brief 获取另一地A系的ID
*/
CM_UINT8 AreaArb_GetArea_A_ID(void)
{
return AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID;
}
/**
* @brief 获取另一地B系的ID
*/
CM_UINT8 AreaArb_GetArea_B_ID(void)
{
return AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID;
}
+16 -1
View File
@@ -123,5 +123,20 @@ void Area_Arb_Stop();
*
*/
void Area_Arb_Wait_Stop();
/**
* @brief 根据ID设置接收状态
*/
void AreaArb_SetCommStatus_byID(CM_UINT8 ID, CM_UINT32 sn, CM_BOOL rcv_flag);
/**
* @brief 根据ID获取接收状态
*/
void AreaArb_GetCommStatus_byID(CM_UINT8 ID, CM_UINT32* SN, CM_BOOL* rcv_flag);
/**
* @brief 获取另一地A系的ID
*/
CM_UINT8 AreaArb_GetArea_A_ID(void);
/**
* @brief 获取另一地B系的ID
*/
CM_UINT8 AreaArb_GetArea_B_ID(void);
#endif
+1 -1
View File
@@ -509,7 +509,7 @@ static void s_Area_Arb_IP_Init(void)
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 */
rt = CM_Memcpy(ARB_COMM_CFG_PTR->IP_Local, 32, g_PFM_Cfg.Local_Cfg.IP_Area,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 */
+17
View File
@@ -169,3 +169,20 @@ void AreaArb_Get_All_State(STR_Area_State *p_all_State)
p_all_State->Partner_Area_B_state = AREA_STATE_CTRL_PTR->StateArea.Partner_Area_B_state;
}
}
/**
* @brief 判断是否存在备地
*/
CM_BOOL AreaArb_Slave_Is_Exist()
{
CM_BOOL rt = CM_FALSE;
if((ENUM_AREA_SLAVE == AREA_STATE_CTRL_PTR->StateArea.Local_state) || (ENUM_AREA_SLAVE == AREA_STATE_CTRL_PTR->StateArea.Partner_state)
|| (ENUM_AREA_SLAVE == AREA_STATE_CTRL_PTR->StateArea.Partner_Area_A_state) || (ENUM_AREA_SLAVE == AREA_STATE_CTRL_PTR->StateArea.Partner_Area_B_state))
{
rt = CM_TRUE;
}
else
{
}
return rt;
}
+4
View File
@@ -33,5 +33,9 @@ CM_UINT8 AreaArb_GetID_byState(ENUM_AREA_STATE state_area, ENUM_2x2_STATE_T stat
* @brief 仲裁模式下使用,获取所有区域状态
*/
void AreaArb_Get_All_State(STR_Area_State *p_all_State);
/**
* @brief 判断是否存在备地
*/
CM_BOOL AreaArb_Slave_Is_Exist();
#endif
+32 -28
View File
@@ -65,6 +65,7 @@ void s_Shutdown_vote(void)
*/
void s_Unknown_vote(void)
{
CM_BOOL Sync_Health_Flag = AREA_FLAGS_CTRL_PTR->Sync_Health_Flag; /**同步成功标志 */
/**获取另外三系状态 */
ENUM_AREA_STATE Partner_State = VOTE_STATE_CTRL->Partner_state;
ENUM_AREA_STATE Area_A_State = VOTE_STATE_CTRL->Partner_Area_A_state;
@@ -81,8 +82,16 @@ void s_Unknown_vote(void)
else if(ENUM_AREA_MASTER == Partner_State)
{
/**和主地在同一地 */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_MASTER;
AREA_LOG_MSG("AREA_STATE_VOTE:Unknow>>>>>Master, Partner is Master\n");
if(CM_TRUE == Sync_Health_Flag)
{
VOTE_STATE_CTRL->Local_state = ENUM_AREA_MASTER;
AREA_LOG_MSG("AREA_STATE_VOTE:Unknow>>>>>Master, Partner is Master, Sync Sucess\n");
}
else
{
VOTE_STATE_CTRL->Local_state = ENUM_AREA_OFFLINE;
AREA_LOG_MSG("AREA_STATE_VOTE:Unknow>>>>>Offline, Partner is Master, Sync Fail\n");
}
}
else if((ENUM_AREA_UNKNOW == Area_A_State || ENUM_AREA_UNKNOW == Area_B_State)
&& (MSCP_AREA_ID_B == AREA_BASIC_CFG_PTR->AreaID))
@@ -173,6 +182,8 @@ void s_Offline_vote(void)
*/
void s_Master_vote(void)
{
ENUM_2x2_STATE_T state2x = AREA_STATE_CTRL_PTR->State2x.LocalState;
if(ENUM_AREA_MASTER == VOTE_STATE_CTRL->Partner_Area_A_state || ENUM_AREA_MASTER == VOTE_STATE_CTRL->Partner_Area_B_state)
{
/**双主宕机 */
@@ -180,42 +191,40 @@ void s_Master_vote(void)
VOTE_STATE_CTRL->Partner_Area_A_state, VOTE_STATE_CTRL->Partner_Area_B_state);
CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
}
else if(ENUM_2x2_OFFLINE == state2x)
{
/**与主地主同步失败 */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_OFFLINE;
AREA_LOG_MSG("AREA_STATE_VOTE:Master>>>>>Offline, Sync failed\n");
}
else
{
}
}
/**
* @brief 备地状态转换
*/
void s_Slave_vote(void)
{
static CM_UINT32 s_slave_cnt = 0u; /**备系降离线容忍计数 */
CM_BOOL flag_comm_mm_status = CM_FALSE; /**与主地主的通信状态 */
CM_UINT8 id_mm = AreaArb_GetID_byState(ENUM_AREA_MASTER, ENUM_2x2_MASTER); /**主地主的ID */
CM_BOOL Sync_Fail_Flag = AREA_FLAGS_CTRL_PTR->Sync_Fail_Flag; /**同步失败标志 */
AreaArb_GetCommStatus_byID(id_mm, NULL, &flag_comm_mm_status);
ENUM_2x2_STATE_T state2x = AREA_STATE_CTRL_PTR->State2x.LocalState;
if(0x55u == AREA_ARB_CTRL_PTR->Arb_Ack)
{
/**收到仲裁升主回复 */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_MASTER;
AREA_LOG_MSG("AREA_STATE_VOTE:Slave>>>>>Master, Arbitration ACK received\n");
}
else if(CM_FALSE == Sync_Fail_Flag)
else if(ENUM_2x2_OFFLINE == state2x)
{
/**同步失败 */
if(0u != id_mm)
{
/**主地主存活,降离线 */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_OFFLINE;
AREA_LOG_MSG("AREA_STATE_VOTE:Slave>>>>>Offline, Sync failed and Master ID:%d exists\n",
id_mm);
}
else
{
/**主地主ID不存在,认为主地主宕机,容忍一周期降离线 */
s_slave_cnt++;
if(s_slave_cnt > MSCP_AREA_SLAVE_TOLERATE_COUNT)
{
s_slave_cnt = 0u;
VOTE_STATE_CTRL->Local_state = ENUM_AREA_OFFLINE;
AREA_LOG_MSG("AREA_STATE_VOTE:Slave>>>>>Offline, Sync failed and Master is lost\n");
}
}
VOTE_STATE_CTRL->Local_state = ENUM_AREA_OFFLINE;
AREA_LOG_MSG("AREA_STATE_VOTE:Slave>>>>>Offline, Sync failed and Master ID:%d exists\n",
id_mm);
}
else if(ENUM_AREA_MASTER == VOTE_STATE_CTRL->Partner_state)
{
@@ -227,9 +236,4 @@ void s_Slave_vote(void)
{
}
/**离开备地,清空计数 */
if(ENUM_AREA_SLAVE != VOTE_STATE_CTRL->Local_state)
{
s_slave_cnt = 0u;
}
}
+78
View File
@@ -0,0 +1,78 @@
#include "Area_Arb_Common.h"
/**
* @brief 执行初始化,4线与仲裁模式根据配置区分
*/
void Area_Arb_Common_Init(void)
{
if(0x55u == g_PFM_Cfg.M_Arb_Enable)
{
Area_With_Arb_Init();
}
else
{
Area_init();//区域初始化
}
}
/**
* @brief 获取所有板卡区域状态,4线与仲裁模式根据配置开关从不同结构体获取
*/
void Area_Arb_Common_Get_All_State(STR_Area_State *p_all_State)
{
if(0x55u == g_PFM_Cfg.M_Arb_Enable)
{
AreaArb_Get_All_State(p_all_State);
}
else
{
Area_Get_All_State(p_all_State);
}
}
/**
* @brief 获取另一地A系的ID
*/
CM_UINT32 Area_Arb_Common_GetArea_A_ID(void)
{
CM_UINT32 id = 0u;
if(0x55u == g_PFM_Cfg.M_Arb_Enable)
{
id = (CM_UINT32)AreaArb_GetArea_A_ID();
}
else
{
id = Area_GetArea_A_ID();
}
return id;
}
/**
* @brief 获取另一地B系的ID
*/
CM_UINT32 Area_Arb_Common_GetArea_B_ID(void)
{
CM_UINT32 id = 0u;
if(0x55u == g_PFM_Cfg.M_Arb_Enable)
{
id = (CM_UINT32)AreaArb_GetArea_B_ID();
}
else
{
id = Area_GetArea_B_ID();
}
return id;
}
/**
* @brief 判断是否存在备地
*/
CM_BOOL Area_Arb_Common_Slave_Is_Exist(void)
{
CM_BOOL rt = ENUM_CM_FALSE;
if(0x55u == g_PFM_Cfg.M_Arb_Enable)
{
rt = Area_Slave_Is_Exist();
}
else
{
rt = AreaArb_Slave_Is_Exist();
}
return rt;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef AREA_ARB_H_
#define AREA_ARB_H_
#include "Area.h"
#include "Arb.h"
#include "Arb_State.h"
/**
* 该文件为4线模式和仲裁模式的共用头文件,用于对其他模块的通用接口
*/
/**
* @brief 执行初始化,4线与仲裁模式根据配置区分
*/
void Area_Arb_Common_Init(void);
/**
* @brief 获取所有板卡区域状态,4线与仲裁模式根据配置开关从不同结构体获取
*/
void Area_Arb_Common_Get_All_State(STR_Area_State *p_all_State);
/**
* @brief 获取另一地A系的ID,执行初始化,4线与仲裁模式根据配置区分
*/
CM_UINT32 Area_Arb_Common_GetArea_A_ID(void);
/**
* @brief 获取另一地B系的ID,执行初始化,4线与仲裁模式根据配置区分
*/
CM_UINT32 Area_Arb_Common_GetArea_B_ID(void);
/**
* @brief 判断是否存在备地
*/
CM_BOOL Area_Arb_Common_Slave_Is_Exist(void);
#endif
-1
View File
@@ -26,7 +26,6 @@
#define MSCP_AREA_B_BOARD_ID_B 0x04
#define MSCP_AREA_UNKNOW_COUNT_MAX 0x0au
#define MSCP_AREA_SLAVE_TOLERATE_COUNT (1u) /**< 备地降离线容忍次数 */
#define MSCP_MSG_BUF_MAX 1024u /**< 区域通信消息最大缓冲区大小 */
+1 -1
View File
@@ -36,7 +36,7 @@
#define TIME_OFFSET_PEER (1) //对端时间偏移量
static STRU_CFM_TIME_CTRL_T s_TimeCtrl[10] = {0};
#define SFM_2oo2_TM_FIX_VAL_NS (3 * CM_MILLION) /* 2oo2校时门限,单位:ns */
#define SFM_2x2_TM_FIX_VAL_NS (10 * CM_MILLION) /* 2x最小调整偏差,单位:ns */
#define SFM_2x2_TM_FIX_VAL_NS (5 * CM_MILLION) /* 2x最小调整偏差,单位:ns */
#define SFM_TIME_SYNC_TOLERANCE_COUNT (5u) /* 时间同步切换, 丢失容忍次数*/
static CM_THREAD_FUNC_T t_Sync_TimeThread(IN CM_Thread_Arg_Struct_T* arg);
+3 -9
View File
@@ -41,6 +41,7 @@
#include "PFM_RemoteUpdate.h"
#include "CFM_Sync.h"
#include "Arb.h"
#include "Area_Arb_Common.h"
#if QNX
#include <sys/neutrino.h>
#include <sys/trace.h>
@@ -243,15 +244,8 @@ static void MSCP_Init(void)
PFM_LOG_SET_INIT_STAGE(ENUM_INIT_APP_CTRL);
PFM_LOG_SET_INIT_STAGE(ENUM_INIT_2X2USART);
CFM_TimeSync_Init(2);//时间同步初始化
if(0x55u == g_PFM_Cfg.M_Arb_Enable)
{
Area_With_Arb_Init();
}
else
{
Area_init();//区域初始化
}
/* 区域初始化*/
Area_Arb_Common_Init();
/*- 是否开启2oo2功能 */
if (0x55u == g_PFM_Cfg.M_2oo2_Enable)
+6 -12
View File
@@ -35,6 +35,7 @@
#include "Area_state.h"
#include "Arb_State.h"
#include "Arb.h"
#include "Area_Arb_Common.h"
/*通信中断时间和同步超时时间可以相同,此时优先执行通信中断切系*/
@@ -1176,7 +1177,6 @@ void SFM_4x2_ChangeState(void)
Area_Wait_Stop();
}
Area_LOG_Transition();
MSCP_LOG_MSG("SFM_4x2_ChangeState start\n");
/*- 执行最后的切系逻辑*/
s_2x2_Ctrl.MineComState = MSCP_Get_2X_VagueCom_State(&s_2x2_state_Ctrl.MineComOKCount[0]); /**< 本机通信状态,2oo2交换 */
@@ -1184,14 +1184,7 @@ void SFM_4x2_ChangeState(void)
s_2x2_Ctrl.MineExtendState = MSCP_Get_2X_VagueCom_State(&s_2x2_state_Ctrl.MineExtendOKCount[0]); /**< 本机串口通信状态,2oo2交换 */
s_2x2_Ctrl.PeerExtendState = MSCP_Get_2X_VagueCom_State(&s_2x2_state_Ctrl.PeerExtendOKCount[0]); /**< 邻机串口通信状态,2oo2交换 */
/**获取区域状态 */
if(0x55u == g_PFM_Cfg.M_Arb_Enable)
{
AreaArb_Get_All_State(&Area_State);
}
else
{
Area_Get_All_State(&Area_State);
}
Area_Arb_Common_Get_All_State(&Area_State);
/*- 切系完成*/
if(ENUM_2x2_AIDSWITCH_OVER == s_2x2_state_Ctrl.LocalAIDSwitchState)
@@ -1277,7 +1270,7 @@ void SFM_4x2_ChangeState(void)
MSCP_LOG_MSG("s_2x2_state_Ctrl.LocalAreaState = %d 2x2 = %d\n",Area_State.Local_state, s_2x2_state_Ctrl.LocalState);
printf("AreaState = %d 2x2 = %d\n",Area_State.Local_state, s_2x2_state_Ctrl.LocalState);
/**<是否存在区域备地*/
s_2x2_state_Ctrl.Area_Slave_Is_Exist = Area_Slave_Is_Exist();
s_2x2_state_Ctrl.Area_Slave_Is_Exist = Area_Arb_Common_Slave_Is_Exist();
/*- 2x线程->更新主线程热备状态*/
s_2x2_Ctrl.LocalState = SFM_2x2_StateDecision(s_2x2_state_Ctrl.LocalAreaState,s_2x2_state_Ctrl.LocalState);
/* 判断3乘是离线则将地状态设置为离线,
@@ -1342,6 +1335,7 @@ void SFM_4x2_ChangeState(void)
(void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_PARTNER, 1U, &s_2x2_Ctrl.PartnerState);
SFM_2x2_LOG_Transition();
Area_LOG_Transition();
MSCP_LOG_MSG("timecurr 16.0.4 = %lld us\n", NOW_USED_TIME);
MSCP_LOG_MSG("SFM_4x2_ChangeState stop\n");
}
@@ -1417,12 +1411,12 @@ ENUM_4x2_STATE_T SFM_2x2_AreaDecision(ENUM_AREA_STATE PartnerAreaState,CM_BOOL i
if (isA == CM_TRUE)
{
// A系主备配对:0x01<->0x03
rtn_state = (masterHighByte == Area_GetArea_A_ID())? ENUM_4x2_MASTER : ENUM_4x2_SLAVE;
rtn_state = (masterHighByte == Area_Arb_Common_GetArea_A_ID())? ENUM_4x2_MASTER : ENUM_4x2_SLAVE;
}
else
{
// B系主备配对:0x02<->0x04
rtn_state = (masterHighByte == Area_GetArea_B_ID())? ENUM_4x2_MASTER : ENUM_4x2_SLAVE;
rtn_state = (masterHighByte == Area_Arb_Common_GetArea_B_ID())? ENUM_4x2_MASTER : ENUM_4x2_SLAVE;
}
break;
default:
BIN
View File
Binary file not shown.