状态转换开发中

This commit is contained in:
lh
2026-08-20 18:54:04 +08:00
parent c7c357249a
commit eb5bdc8177
4 changed files with 219 additions and 3 deletions
+53 -3
View File
@@ -7,6 +7,7 @@
#include "Area_2oo2.h" #include "Area_2oo2.h"
#include "Arb_State.h" #include "Arb_State.h"
#include "CFM_Sync.h" #include "CFM_Sync.h"
#include "Arb_State_Vote.h"
/*===========↓↓↓↓↓全局变量声明&定义↓↓↓↓↓=============*/ /*===========↓↓↓↓↓全局变量声明&定义↓↓↓↓↓=============*/
STRU_AREA_WITH_ARB_CFG_ALL_T g_area_with_arb_cfg = {0}; STRU_AREA_WITH_ARB_CFG_ALL_T g_area_with_arb_cfg = {0};
/*===========↑↑↑↑↑全局变量声明&定义↑↑↑↑↑=============*/ /*===========↑↑↑↑↑全局变量声明&定义↑↑↑↑↑=============*/
@@ -105,6 +106,10 @@ static void s_Area_2oo2Sync_AfterStateRecv();
* @brief 2取同步后,判断本周期是否收到请求,并进行回复组包发送 * @brief 2取同步后,判断本周期是否收到请求,并进行回复组包发送
*/ */
static void s_Area_SendACK_After2oo2(); static void s_Area_SendACK_After2oo2();
/**
* @brief 对接收到的仲裁应答进行2取同步
*/
static void s_Area_2oo2Sync_AfterArbRecv();
/*===========↑↑↑↑↑静态函数声明↑↑↑↑↑=============*/ /*===========↑↑↑↑↑静态函数声明↑↑↑↑↑=============*/
@@ -119,6 +124,15 @@ void Area_With_Arb_Init(void)
AREA_BASIC_CFG_PTR->OutnetID = g_PFM_Cfg.BOARD_ID;/**< 外网ID */ AREA_BASIC_CFG_PTR->OutnetID = g_PFM_Cfg.BOARD_ID;/**< 外网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)); 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));
/**获取自身所在地(A地/B地) */
if((MSCP_AREA_A_BOARD_ID_A == AREA_BASIC_CFG_PTR->BoardID ) || (MSCP_AREA_A_BOARD_ID_B == AREA_BASIC_CFG_PTR->BoardID ))
{
AREA_BASIC_CFG_PTR->AreaID = MSCP_AREA_ID_A;
}
else
{
AREA_BASIC_CFG_PTR->AreaID = MSCP_AREA_ID_B;
}
/* 网络初始化*/ /* 网络初始化*/
Area_Arb_Net_Init(); Area_Arb_Net_Init();
/*信号量初始化*/ /*信号量初始化*/
@@ -378,7 +392,7 @@ static void s_Area_State_Ack_Recv_Process(void)
CM_UINT32 crc1 = 0u, crc2 = 0u; CM_UINT32 crc1 = 0u, crc2 = 0u;
CM_UINT32 timeStamp = 0u, timeNow = 0u; CM_UINT32 timeStamp = 0u, timeNow = 0u;
CM_UINT8 srcID = 0u, dstID = 0u; CM_UINT8 srcID = 0u, dstID = 0u;
CM_UINT8 timeSyncFlag = CFM_GetTimeSyncFlag(); /**获取校时标志 */ CM_UINT8 timeSyncFlag = AREA_FLAGS_CTRL_PTR->Time_Sync_Flag; /**获取校时标志 */
CM_UINT32 localsn = AREA_COMM_STATUS_PTR->LocalSN; CM_UINT32 localsn = AREA_COMM_STATUS_PTR->LocalSN;
do do
{ {
@@ -446,6 +460,8 @@ static void s_Area_Arb_Send_Process(void)
CM_UINT8 id_mm = Area_GetID_byState(ENUM_AREA_MASTER, 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; 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;
/**重置仲裁请求发送标志 */
AREA_ARB_CTRL_PTR->Arb_Send_Flag = 0u;
/**判断是否发送仲裁请求 */ /**判断是否发送仲裁请求 */
if(ENUM_2x2_MASTER == AREA_STATE_CTRL_PTR->State2x.LocalState) if(ENUM_2x2_MASTER == AREA_STATE_CTRL_PTR->State2x.LocalState)
@@ -454,6 +470,7 @@ static void s_Area_Arb_Send_Process(void)
if(ENUM_AREA_MASTER == local_area_state && 0u == id_sm) if(ENUM_AREA_MASTER == local_area_state && 0u == id_sm)
{ {
/**本地主地主,与备地主通信中断,发送仲裁请求 */ /**本地主地主,与备地主通信中断,发送仲裁请求 */
AREA_ARB_CTRL_PTR->Arb_Send_Flag = 1u;
Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack)); Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack));
} }
else if(ENUM_AREA_SLAVE == local_area_state && 0u == id_mm) else if(ENUM_AREA_SLAVE == local_area_state && 0u == id_mm)
@@ -461,6 +478,7 @@ static void s_Area_Arb_Send_Process(void)
/**本地备地主,与主地主通信中断,容忍一周期发送请求 */ /**本地备地主,与主地主通信中断,容忍一周期发送请求 */
if(tolerate_arb >= 1u) if(tolerate_arb >= 1u)
{ {
AREA_ARB_CTRL_PTR->Arb_Send_Flag = 1u;
Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack)); Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack));
tolerate_arb = 0u; tolerate_arb = 0u;
} }
@@ -474,6 +492,7 @@ static void s_Area_Arb_Send_Process(void)
/**未知地主系,与其他三系通信持续中断10周期,发送仲裁请求 */ /**未知地主系,与其他三系通信持续中断10周期,发送仲裁请求 */
if(tolerate_arb >= 10u) if(tolerate_arb >= 10u)
{ {
AREA_ARB_CTRL_PTR->Arb_Send_Flag = 1u;
Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack)); Area_Arb_Req_Send(&arb_pack, sizeof(arb_pack));
tolerate_arb = 0u; tolerate_arb = 0u;
} }
@@ -528,13 +547,23 @@ static void s_Area_Arb_Recv_Process(void)
} }
} }
} }
s_Area_2oo2Sync_AfterArbRecv();
} }
/** /**
* @brief 状态转移处理 * @brief 状态转移处理
*/ */
static void s_Area_Arb_State_Transition(void) static void s_Area_Arb_State_Transition(void)
{ {
if(1u == AREA_ARB_CTRL_PTR->Arb_Send_Flag && 0x00u == AREA_ARB_CTRL_PTR->Arb_Ack)
{
/**发送了仲裁请求但未收到应答,直接宕机 */
CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
}
else
{
/**进行状态转换 */
Area_With_Arb_State_Vote();
}
} }
/** /**
* @brief 主地主的组播发送状态数据处理 * @brief 主地主的组播发送状态数据处理
@@ -623,6 +652,10 @@ static void s_Area_Cycle_Init(void)
AREA_COMM_STATUS_PTR->Patner_RcvFlag = CM_FALSE; AREA_COMM_STATUS_PTR->Patner_RcvFlag = CM_FALSE;
AREA_COMM_STATUS_PTR->Area_A_RcvFlag = CM_FALSE; AREA_COMM_STATUS_PTR->Area_A_RcvFlag = CM_FALSE;
AREA_COMM_STATUS_PTR->Area_B_RcvFlag = CM_FALSE; AREA_COMM_STATUS_PTR->Area_B_RcvFlag = CM_FALSE;
/**每周期获取所需标志 */
AREA_FLAGS_CTRL_PTR->Time_Sync_Flag = CFM_GetTimeSyncFlag();
AREA_FLAGS_CTRL_PTR->Sync_Fail_Flag = CFM_GetSyncFailFlag();
AREA_FLAGS_CTRL_PTR->Sync_Health_Flag = CFM_GetSyncHealth();
} }
/** /**
* @brief 根据ID设置接收状态 * @brief 根据ID设置接收状态
@@ -792,7 +825,7 @@ static void s_Area_SendACK_After2oo2()
/**发送帧初始化 */ /**发送帧初始化 */
state_pack.Len = AREA_ARB_STATE_PACK_REAL_LEN - 1; state_pack.Len = AREA_ARB_STATE_PACK_REAL_LEN - 1;
state_pack.MsgType = ENUM_AREA_MSG_STATE_ACK; state_pack.MsgType = ENUM_AREA_MSG_STATE_ACK;
state_pack.TimeSyncFlag = CFM_GetTimeSyncFlag(); /**获取校时标志 */ state_pack.TimeSyncFlag = AREA_FLAGS_CTRL_PTR->Time_Sync_Flag; /**获取校时标志 */
state_pack.SrcID = AREA_BASIC_CFG_PTR->BoardID; state_pack.SrcID = AREA_BASIC_CFG_PTR->BoardID;
state_pack.StateArea = AREA_STATE_CTRL_PTR->StateArea.Local_state; state_pack.StateArea = AREA_STATE_CTRL_PTR->StateArea.Local_state;
state_pack.State2x = AREA_STATE_CTRL_PTR->State2x.LocalState; state_pack.State2x = AREA_STATE_CTRL_PTR->State2x.LocalState;
@@ -830,3 +863,20 @@ static void s_Area_SendACK_After2oo2()
Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID, &state_pack, sizeof(state_pack)); Area_State_Send(AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID, &state_pack, sizeof(state_pack));
} }
} }
/**
* @brief 对接收到的仲裁应答进行2取同步
*/
static void s_Area_2oo2Sync_AfterArbRecv()
{
CM_INT32 len = sizeof(STRU_AREA_WITH_ARB_REQ_T), rcv_len = 0;
STRU_AREA_WITH_ARB_REQ_T peer_ctrl = {0};
/**2取交互仲裁应答信息 */
rcv_len = Area_2oo2_Currency_NoSplit(AREA_ARB_CTRL_PTR, len, &peer_ctrl, len);
CM_ASSERT(len == rcv_len, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
if(peer_ctrl.Arb_Ack == 0x55u && AREA_ARB_CTRL_PTR->Arb_Ack == 0x00u)
{
/**本CPU没有收到仲裁回复,另一CPU收到,同步仲裁状态 */
AREA_ARB_CTRL_PTR->Arb_Ack = peer_ctrl.Arb_Ack;
}
}
+12
View File
@@ -11,6 +11,7 @@
#define AREA_STATE_CTRL_PTR (&g_area_with_arb_cfg.State_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_COMM_STATUS_PTR (&g_area_with_arb_cfg.Comm_Status) /**< 仲裁模式下使用,区域模块的通信状态记录 */
#define AREA_ARB_CTRL_PTR (&g_area_with_arb_cfg.Arb_CTRL) /**< 仲裁模式下使用,区域模块的仲裁控制 */ #define AREA_ARB_CTRL_PTR (&g_area_with_arb_cfg.Arb_CTRL) /**< 仲裁模式下使用,区域模块的仲裁控制 */
#define AREA_FLAGS_CTRL_PTR (&g_area_with_arb_cfg.Flag_CTRL) /**< 仲裁模式下使用,区域模块使用的标志位 */
/*仲裁模式下,区域间所有通信相关配置*/ /*仲裁模式下,区域间所有通信相关配置*/
typedef struct typedef struct
@@ -35,9 +36,18 @@ typedef struct
/*仲裁模式下,记录仲裁的回复*/ /*仲裁模式下,记录仲裁的回复*/
typedef struct typedef struct
{ {
CM_UINT8 Arb_Send_Flag; /**< 仲裁请求发送标志位,记录本周期是否发送了仲裁请求 */
CM_UINT8 Arb_Ack; /**< 记录仲裁的回复 */ CM_UINT8 Arb_Ack; /**< 记录仲裁的回复 */
}STRU_AREA_WITH_ARB_REQ_T; }STRU_AREA_WITH_ARB_REQ_T;
/*仲裁模式下,记录各种同步标志(时间/数据同步) */
typedef struct
{
CM_BOOL Time_Sync_Flag; /**< 时间同步标志 */
CM_BOOL Sync_Health_Flag; /**< 同步健康标志 */
CM_BOOL Sync_Fail_Flag; /**< 同步失败标志 CM_FALSE-同步失败 CM_TRUE-同步成功*/
}STRU_AREA_WITH_ARB_FLAGS_T;
/*仲裁模式下,区域线程控制*/ /*仲裁模式下,区域线程控制*/
typedef struct typedef struct
{ {
@@ -54,6 +64,7 @@ typedef struct
CM_UINT8 Partner_Area_A_BoardID; /**< 对系id */ CM_UINT8 Partner_Area_A_BoardID; /**< 对系id */
CM_UINT8 Partner_Area_B_BoardID; /**< 对系id */ CM_UINT8 Partner_Area_B_BoardID; /**< 对系id */
CM_UINT16 OutnetID; /**<外网ID */ CM_UINT16 OutnetID; /**<外网ID */
CM_UINT8 AreaID; /**< 区域IDA地或B地 */
}STRU_AREA_WITH_ARB_BASIC_CFG_T; }STRU_AREA_WITH_ARB_BASIC_CFG_T;
/*仲裁模式下,记录2乘状态结构体*/ /*仲裁模式下,记录2乘状态结构体*/
@@ -81,6 +92,7 @@ typedef struct
STRU_AREA_WITH_ARB_STATE_CTRL_T State_CTRL; /**<状态控制 */ STRU_AREA_WITH_ARB_STATE_CTRL_T State_CTRL; /**<状态控制 */
STRU_AREA_WITH_ARB_COMM_STATUS_T Comm_Status; /**<通信状态记录 */ STRU_AREA_WITH_ARB_COMM_STATUS_T Comm_Status; /**<通信状态记录 */
STRU_AREA_WITH_ARB_REQ_T Arb_CTRL; /**< 与仲裁的交互 */ STRU_AREA_WITH_ARB_REQ_T Arb_CTRL; /**< 与仲裁的交互 */
STRU_AREA_WITH_ARB_FLAGS_T Flag_CTRL; /**< 记录各种标志 */
}STRU_AREA_WITH_ARB_CFG_ALL_T; }STRU_AREA_WITH_ARB_CFG_ALL_T;
extern STRU_AREA_WITH_ARB_CFG_ALL_T g_area_with_arb_cfg; extern STRU_AREA_WITH_ARB_CFG_ALL_T g_area_with_arb_cfg;
+146
View File
@@ -0,0 +1,146 @@
#include "Arb_State_Vote.h"
/**仅在状态表决时使用,简化宏,只包含区域状态 */
#define VOTE_STATE_CTRL (&(AREA_STATE_CTRL_PTR->StateArea))
/**
* @brief 宕机状态转换
*/
void s_Shutdown_vote(void);
/**
* @brief 未知地状态转换
*/
void s_Unknown_vote(void);
/**
* @brief 离线地状态转换
*/
void s_Offline_vote(void);
/**
* @brief 主地状态转换
*/
void s_Master_vote(void);
/**
* @brief 备地状态转换
*/
void s_Slave_vote(void);
void Area_With_Arb_State_Vote(void)
{
ENUM_AREA_STATE local_state = VOTE_STATE_CTRL->Local_state;
switch(local_state)
{
case ENUM_AREA_SHUTDOWN:
s_Shutdown_vote();
break;
case ENUM_AREA_UNKNOW:
s_Unknown_vote();
break;
case ENUM_AREA_OFFLINE:
s_Offline_vote();
break;
case ENUM_AREA_MASTER:
s_Master_vote();
break;
case ENUM_AREA_SLAVE:
s_Slave_vote();
break;
}
}
/**
* @brief 宕机状态转换
*/
void s_Shutdown_vote(void)
{
VOTE_STATE_CTRL->Local_state = ENUM_AREA_SHUTDOWN;
CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
}
/**
* @brief 未知地状态转换
*/
void s_Unknown_vote(void)
{
/**获取另外三系状态 */
ENUM_AREA_STATE Partner_State = VOTE_STATE_CTRL->Partner_state;
ENUM_AREA_STATE Area_A_State = VOTE_STATE_CTRL->Partner_Area_A_state;
ENUM_AREA_STATE Area_B_State = VOTE_STATE_CTRL->Partner_Area_B_state;
/**初始化未知地计数 */
static CM_UINT32 unkown_cnt = 0u;
/**状态转换部分 */
if(0x55u == AREA_ARB_CTRL_PTR->Arb_Ack)
{
/**收到仲裁升主回复 */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_MASTER;
}
else if(ENUM_AREA_MASTER == Partner_State)
{
/**和主地在同一地 */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_MASTER;
}
else if((ENUM_AREA_UNKNOW == Area_A_State || ENUM_AREA_UNKNOW == Area_B_State)
&& (MSCP_AREA_ID_B == AREA_BASIC_CFG_PTR->AreaID))
{
/**另一地是离线地,本地是B地,降离线 */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_OFFLINE;
AREA_LOG_MSG("AREA_STATE_VOTE:Unknow>>>>>Offline, A is Unknown, Local is B\n");
}
else if((ENUM_AREA_SLAVE == Area_A_State || ENUM_AREA_SLAVE == Area_B_State))
{
/**另一地是备地,降离线(暂不存在改场景,预留转换) */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_OFFLINE;
AREA_LOG_MSG("AREA_STATE_VOTE:Unknow>>>>>Offline, Another Area is Slave\n");
}
else if((ENUM_AREA_MASTER == Area_A_State || ENUM_AREA_MASTER == Area_B_State))
{
/**另一地是主地,降离线 */
VOTE_STATE_CTRL->Local_state = ENUM_AREA_OFFLINE;
}
else if((MSCP_AREA_ID_A == AREA_BASIC_CFG_PTR->AreaID)
&& (ENUM_AREA_UNKNOW == Area_A_State || ENUM_AREA_SHUTDOWN == Area_A_State || ENUM_AREA_OFFLINE == Area_A_State)
&& (ENUM_AREA_UNKNOW == Area_B_State || ENUM_AREA_SHUTDOWN == Area_B_State || ENUM_AREA_OFFLINE == Area_B_State))
{
/**另一地为未知地/离线地/宕机,本地是A地,维持10周期升主 */
unkown_cnt++;
if(unkown_cnt > MSCP_AREA_UNKNOW_COUNT_MAX)
{
VOTE_STATE_CTRL->Local_state = ENUM_AREA_MASTER;
unkown_cnt = 0u;
}
}
else
{
}
/**离开未知地,清空计数 */
if(ENUM_AREA_UNKNOW == VOTE_STATE_CTRL->Local_state)
{
unkown_cnt = 0u;
}
}
/**
* @brief 离线地状态转换
*/
void s_Offline_vote(void)
{
CM_BOOL Sync_Fail_Flag = AREA_FLAGS_CTRL_PTR->Sync_Fail_Flag;
CM_BOOL Sync_Health_Flag = AREA_FLAGS_CTRL_PTR->Sync_Health_Flag;
if()
{
}
}
/**
* @brief 主地状态转换
*/
void s_Master_vote(void)
{
}
/**
* @brief 备地状态转换
*/
void s_Slave_vote(void)
{
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef ARB_STATE_VOTE_H_
#define ARB_STATE_VOTE_H_
#include "Arb.h"
void Area_With_Arb_State_Vote(void);
#endif