#include "plat_comm/plat_comm_task.h" #include "plat_comm/impl/bs_connect_impl.h" #include "plat_comm/impl/bs_public_impl.h" #if EC200A_4G_EN #include "plat_comm/4g_module/ec200a_4g_cfg.h" #endif #include "app_init/app_init.h" #include "app_init/task_lock.h" #include "publicdata/publicdata.h" #include "wdt_task/wdt_task.h" #define PLATCOMM_TASK_ID (TASK_ID_PlatComm) #define PLATCOMM_SLEEP_TIME_MS() (MY_GET_SLEEP_TIME(PLATCOMM_TASK_ID)) #define PLATCOMM_LOCK_INIT() (u8_task_lock_ctrl(PLATCOMM_TASK_ID, TASK_LOCK_OP_INIT)) #define PLATCOMM_LOCK_TAKE() (u8_task_lock_ctrl(PLATCOMM_TASK_ID, TASK_LOCK_OP_TAKE)) #define PLATCOMM_LOCK_GIVE() (u8_task_lock_ctrl(PLATCOMM_TASK_ID, TASK_LOCK_OP_GIVE)) #define PLATCOMM_FEED_DOG() (v_wdt_setFlag(PLATCOMM_TASK_ID)) #define PLATCOMM_LOG(fmt, ...) MYLOG_MSG(PLATCOMM_TASK_ID, (fmt), ##__VA_ARGS__) BS_TASK_CTRL_DATA s_bs_task_ctrl; typedef struct { const char *Master; void (*v_bs_data_init)(U8_T); //数据初始化 U8_T (*v_bs_tcp_connect)(void); //tcp建立 U8_T (*v_bs_logon_connect)(void); //平台登录 void (*v_bs_recv_data)(void); //平台接收数据 void (*v_bs_recv_data_divide)(U8_T,U8_T*,U16_T); //平台接收数据 void (*v_bs_send_ctrl)(void); //平台发送逻辑控制 void (*v_bs_private_logic)(U8_T); //私有逻辑执行函数 } MasterFuncPtl; const MasterFuncPtl MasterFuncArray[MAX_BS_NUM]= //最大2个平台 { // 字符名称 数据初始化 TCP连接 登录连接 接收解析函数 发送控制函数 私有逻辑执行函数 #if (BS_IES_EN) /* 积成 IESZT:bs_ies_ctrl=状态机,bs_ies_interface=0x68 组解帧;阶段1 登录+心跳 */ {"ieszt", v_ies_init_data, v_ies_tcp_connect, v_ies_logo_on,v_ies_recv_data,v_ies_recv_unpack,v_ies_send_ctrl,v_ies_private_logic}, #endif #if (BS_GWSDK_EN) {"gwsdk", v_sdk_init_data, v_sdk_tcp_connect, v_sdk_logo_on,v_sdk_recv_data,NULL,v_sdk_send_ctrl,v_sdk_private_crel}, //0积成平台 #endif #if (BS_OCPP_EN) //OCPP平台使能 {"ocpp", v_ocpp_init_data, v_ocpp_tcp_connect, v_ocpp_logo_on,v_ocpp_recv_data,NULL,v_ocpp_send_ctrl,v_ocpp_private_logic}, //1 云快充平台 #endif #if ((BS_IES_EN + BS_GWSDK_EN + BS_OCPP_EN) < MAX_BS_NUM) {"null", NULL, NULL, NULL, NULL, NULL, NULL, NULL}, #endif }; /****************************************************************************系统集成改动部分-开始******************************************************/ #if 1 //公共接口 外部调用函数 /**************************************************** *函数名称: v_set_bs_renew() *功能说明: 设置联网状态 重新连接 *参数说明: * 输入参数: U8_T u8_bs 平台类型 * 输出参数: ****************************************************/ void v_set_bs_renew(U8_T u8_bs) { /* 网口:必须先关闭 socket,否则只清 fd 会导致 LwIP 侧 socket 泄漏,重连几次后 connect 失败(再连也连不上) */ if (s_bs_task_ctrl.s_bs_ctrl[u8_bs].u8_netType != 0) { v_bs_eth_close_socket(u8_bs); /* 内部已置 fd=-1、u8_TCP_connect_flag=0 */ } else { s_bs_task_ctrl.s_bs_ctrl[u8_bs].u8_TCP_connect_flag = 0; s_bs_task_ctrl.s_bs_ctrl[u8_bs].fd = (S32_T)-1; s_bs_task_ctrl.s_bs_ctrl[u8_bs].u8_4g_soft_tcp_reconnect = 1; s_bs_task_ctrl.s_bs_ctrl[u8_bs].u8_4g_tcp_soft_fail_streak = 0; } s_bs_task_ctrl.s_bs_ctrl[u8_bs].u8_log_on_flag = 0; /* 勿在此处调用 v_bs_data_init:原先会触发 v_bs_4G_data_init 整网重驻网。 * 断连后仅关 Socket + QIOPEN 由 u8_tcp_connect / v_ocpp_init_data_ex(...,0) 完成(不清 OCPP_DATA_CTRL)。 * 上电首次 v_ocpp_init_data:`v_ocpp_mv_offline_init` + 运行态 RAM 重置 + v_ocpp_init_data_ex(...,1); * TCP 长时间失败在 BS_ocpp_ctrl 内调用 `v_ocpp_init_data`(与上电同路径)。 */ } #endif void v_plat_data_init(void) { memset(&s_bs_task_ctrl , 0, sizeof(s_bs_task_ctrl)); s_bs_task_ctrl.u8_gunCnt = u32_bs_get_sys_data(0, E_BS_GET_SYS_DATA_GUN_NUM, 0); /* 通过 u32_bs_get_sys_data 获取平台使能:0 平台A,1 平台B */ s_bs_task_ctrl.s_bs_ctrl[0].bs_enable = (U8_T)u32_bs_get_sys_data(0, E_BS_GET_SYS_DATA_PLAT_EN, 0); s_bs_task_ctrl.s_bs_ctrl[1].bs_enable = (U8_T)u32_bs_get_sys_data(1, E_BS_GET_SYS_DATA_PLAT_EN, 0); if(s_bs_task_ctrl.s_bs_ctrl[0].bs_enable && s_bs_task_ctrl.s_bs_ctrl[1].bs_enable) s_bs_task_ctrl.u8_4g_dispense_en = 1; //socketA和socketB使能 4g 数据分发使能 /* 通过 u32_bs_get_sys_data 获取联网类型:0 4G,1 网线 */ s_bs_task_ctrl.s_bs_ctrl[0].u8_netType = u32_bs_get_sys_data(0,E_BS_GET_SYS_DATA_NET_TYPE,0); s_bs_task_ctrl.s_bs_ctrl[1].u8_netType = u32_bs_get_sys_data(1,E_BS_GET_SYS_DATA_NET_TYPE,0); } #if SYSTEM_TYPE == SYSTEM_TYPE_CCU601E_D /** 是否有 FTP/远程升级在跑(含 OCPP 日志上传:CallResult 前 u8_updata_flag 仍为 0 的窗口) */ static U8_T u8_plat_comm_ftp_transfer_active(void) { U8_T active = (U8_T)((s_bs_task_ctrl.s_bs_ctrl[0].u8_updata_flag != 0U || s_bs_task_ctrl.s_bs_ctrl[1].u8_updata_flag != 0U) ? 1U : 0U); #if BS_OCPP_EN if (active == 0U && t_ftp_update_info.u8_netType == 0U && s_bs_task_ctrl.ocpp_data.u8_log_file_upload != 0U) { active = 1U; } #endif return active; } /** 各平台一轮:建链 / 登录 / send / recv / private_logic(与 FTP 步进分离,占满「联网」段) */ static void v_plat_comm_network_round(void) { U8_T i; for (i = 0; i < MAX_BS_NUM; i++) { if (s_bs_task_ctrl.s_bs_ctrl[i].bs_enable == 0) { continue; } if (s_bs_task_ctrl.s_bs_ctrl[i].u8_TCP_connect_flag == 0) { if (MasterFuncArray[i].v_bs_tcp_connect != NULL) { s_bs_task_ctrl.s_bs_ctrl[i].u8_TCP_connect_flag = MasterFuncArray[i].v_bs_tcp_connect(); } if (s_bs_task_ctrl.s_bs_ctrl[i].u8_TCP_connect_flag) { Plat_Comm_LOG("[%d] tcp connect\n", i); } } else { if (s_bs_task_ctrl.s_bs_ctrl[i].u8_log_on_flag == 0) { if (MasterFuncArray[i].v_bs_logon_connect != NULL) { s_bs_task_ctrl.s_bs_ctrl[i].u8_log_on_flag = MasterFuncArray[i].v_bs_logon_connect(); } if (s_bs_task_ctrl.s_bs_ctrl[i].u8_log_on_flag) { Plat_Comm_LOG("[%d] logOn is ok\n", i); } } else { if (MasterFuncArray[i].v_bs_send_ctrl != NULL) { MasterFuncArray[i].v_bs_send_ctrl(); } } } if (MasterFuncArray[i].v_bs_recv_data != NULL) { MasterFuncArray[i].v_bs_recv_data(); } if (MasterFuncArray[i].v_bs_private_logic != NULL) { MasterFuncArray[i].v_bs_private_logic(i); } } } /** FTP 单步;4G(t_ftp_update_info.u8_netType==0)时随后双路 recv,便于收 +QFTP* 等尾 URC */ static void v_plat_comm_ftp_round(void) { U8_T i; v_ftp_update_action(); if (t_ftp_update_info.u8_netType != 0U) { return; } for (i = 0; i < MAX_BS_NUM; i++) { if (s_bs_task_ctrl.s_bs_ctrl[i].bs_enable == 0) { continue; } if (MasterFuncArray[i].v_bs_recv_data != NULL) { MasterFuncArray[i].v_bs_recv_data(); } } } #endif void v_plat_comm_task(void *arg) { uint16_t sleep_time_ms; uint32_t last_send_time; uint32_t current_time; static uint8_t s_plat_comm_net_ftp_phase = 0U; (void)arg; (void)PLATCOMM_LOCK_INIT(); sleep_time_ms = PLATCOMM_SLEEP_TIME_MS(); last_send_time = get_current_seconds(); v_plat_data_init(); if(s_bs_task_ctrl.s_bs_ctrl[0].bs_enable != 0 && MasterFuncArray[0].v_bs_data_init != NULL) MasterFuncArray[0].v_bs_data_init(0); if(s_bs_task_ctrl.s_bs_ctrl[1].bs_enable != 0 && MasterFuncArray[1].v_bs_data_init != NULL) MasterFuncArray[1].v_bs_data_init(1); for (;;) { PLATCOMM_FEED_DOG(); current_time = get_current_seconds(); if ((TASK_RUN_PRINT_TIME != 0U) && (u32_safe_seconds_since(last_send_time) >= TASK_RUN_PRINT_TIME)) { if (PLATCOMM_LOCK_TAKE() == 1U) { PLATCOMM_LOG("plat comm task is runing, sleep time is %ums", sleep_time_ms); (void)PLATCOMM_LOCK_GIVE(); } last_send_time = current_time; } #if 0 //屏蔽联网测试 mSleep(u16_leep_time); // if(MasterFuncArray[0].v_bs_private_logic != NULL) //私有逻辑执行函数 例如超时计数等,注意判断网路连接状态 // MasterFuncArray[0].v_bs_private_logic(0); continue; #endif #if SYSTEM_TYPE == SYSTEM_TYPE_CCU601E_D /* FTP 活跃时:相邻两个 Plat_Comm 周期各只做一端——周期 A 仅联网、周期 B 仅 FTP,互不叠在同一周期内。 * 无 FTP 时:每周期只跑联网,并把相位复位为 0(下次进入 FTP 仍先联网)。4G FTP 步内为 `v_ftp_update_action` 后再双路 recv。 */ { U8_T const ftp_active = u8_plat_comm_ftp_transfer_active(); if (ftp_active == 0U) { s_plat_comm_net_ftp_phase = 0U; v_plat_comm_network_round(); } else if (s_plat_comm_net_ftp_phase == 0U) { v_plat_comm_network_round(); s_plat_comm_net_ftp_phase = 1U; } else { v_plat_comm_ftp_round(); s_plat_comm_net_ftp_phase = 0U; } } #else /* 遍历平台 A/B */ for (U8_T i = 0U; i < 2U; i++) { if (s_bs_task_ctrl.s_bs_ctrl[i].bs_enable == 0U) { continue; } /* 状态机:未建链 → 建链;已建链未登录 → 登录;已登录 → 周期发送 */ if (s_bs_task_ctrl.s_bs_ctrl[i].u8_TCP_connect_flag == 0U) { if (MasterFuncArray[i].v_bs_tcp_connect != NULL) { s_bs_task_ctrl.s_bs_ctrl[i].u8_TCP_connect_flag = MasterFuncArray[i].v_bs_tcp_connect(); } } else if (s_bs_task_ctrl.s_bs_ctrl[i].u8_log_on_flag == 0U) { if (MasterFuncArray[i].v_bs_logon_connect != NULL) { s_bs_task_ctrl.s_bs_ctrl[i].u8_log_on_flag = MasterFuncArray[i].v_bs_logon_connect(); } } else if (MasterFuncArray[i].v_bs_send_ctrl != NULL) { MasterFuncArray[i].v_bs_send_ctrl(); } /* 接收:4G 双 socket 分发模式 或 单平台透传模式 */ if (s_bs_task_ctrl.u8_4g_dispense_en != 0U) { v_4g_wh5_data_divide_recv(MasterFuncArray[0].v_bs_recv_data_divide, MasterFuncArray[1].v_bs_recv_data_divide); } else if (MasterFuncArray[i].v_bs_recv_data != NULL) { MasterFuncArray[i].v_bs_recv_data(); } /* 协议私有逻辑:状态变位检测、超时处理等 */ if (MasterFuncArray[i].v_bs_private_logic != NULL) { MasterFuncArray[i].v_bs_private_logic(i); } } #endif /* 动态 sleep:扣除本周期发送占用的时间,保证整体周期稳定 */ if (s_bs_task_ctrl.u8_sendCnt * Plat_Send_Sleep < sleep_time_ms) { mSleep(sleep_time_ms - s_bs_task_ctrl.u8_sendCnt * Plat_Send_Sleep); } else { mSleep(sleep_time_ms); } s_bs_task_ctrl.u8_sendCnt = 0U; } }