Files
CCU621M/app/plat_comm/plat_comm_task.c
T

288 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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)
/* 积成 IESZTbs_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 平台A1 平台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 4G1 网线 */
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 单步;4Gt_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;
}
}