385 lines
12 KiB
C
385 lines
12 KiB
C
/*****************************************************************************
|
||
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
|
||
* @file logic_main.c
|
||
* @brief xxxx
|
||
* @author Gary
|
||
* @date 2024/09/29
|
||
* @remark 初修订
|
||
*****************************************************************************/
|
||
#include "logic_main.h"
|
||
|
||
logic_pthread_t stlogic = {0};
|
||
tast_register_execute *task_group[E_TACTIC_MODE_END] = {0}; // MAX_TASK_NUM改用枚举
|
||
|
||
// 用于log打印 与 work_mode_e 强绑定
|
||
const char *workModeNames[] = {
|
||
"无",
|
||
"调试模式",
|
||
"削峰填谷模式",
|
||
"需求响应模式",
|
||
"负载跟踪模式",
|
||
"需量控制",
|
||
"功率因数",
|
||
"null"};
|
||
|
||
/*********************************************************************
|
||
* @brief 初始化任务参数
|
||
* @param[in] 无
|
||
* @return 0:sucessful;1:fault
|
||
*********************************************************************/
|
||
static int initTaskParam()
|
||
{
|
||
logic_getProtectParam();
|
||
|
||
logic_getPowerDistrParam();
|
||
|
||
work_mode_set_t tempMode;
|
||
if (0 == kit_get_work_mode_set(&tempMode))
|
||
{
|
||
stlogic.para_delivery.mode = tempMode.workMode;
|
||
}
|
||
else if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
|
||
{
|
||
KITLOG(LOG_MODBUS_EN, INFO_EN, "获取调试配置失败 %s ==> %s", workModeNames[stlogic.para_delivery.mode], workModeNames[tempMode.workMode]);
|
||
KITPTF(LOG_MODBUS_EN, INFO_EN, "获取调试配置失败 %s ==> %s", workModeNames[stlogic.para_delivery.mode], workModeNames[tempMode.workMode]);
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
// 读取参数值
|
||
switch (stlogic.para_delivery.mode)
|
||
{
|
||
case E_TACTIC_MODE_DEBUG: // 调试模式
|
||
logic_debugParamUpdate();
|
||
break;
|
||
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
|
||
logic_peakValleyUpdate();
|
||
break;
|
||
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
|
||
/* 暂未实现 */
|
||
break;
|
||
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
|
||
/* 暂未实现 */
|
||
break;
|
||
case E_TACTIC_MODE_DMDCTRL: // 需量控制模式
|
||
/* 暂未实现 */
|
||
break;
|
||
case E_TACTIC_MODE_PFCTRL: // 功率因数模式
|
||
/* 暂未实现 */
|
||
break;
|
||
default:
|
||
/*无模式*/
|
||
break;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 注册并初始化一个新的任务节点
|
||
* @param[in] task_func 任务的函数指针
|
||
* @return 成功时返回指向新任务节点的指针;失败时返回 NULL
|
||
*********************************************************************/
|
||
// 初始化任务链表节点
|
||
tast_register_execute *register_task(task_func_t task_func)
|
||
{
|
||
tast_register_execute *new_task = (tast_register_execute *)malloc(sizeof(tast_register_execute));
|
||
if (new_task == NULL)
|
||
{
|
||
printf("Memory allocation failed!\n");
|
||
return NULL;
|
||
}
|
||
// new_task->taskPeriod = period;
|
||
new_task->task = task_func;
|
||
new_task->next = NULL;
|
||
return new_task;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 初始化任务链表,支持多个任务函数指针
|
||
* @param[in] count 任务数量
|
||
* @param[in] ... 可变参数,任务函数指针
|
||
* @return 成功时返回指向链表头部的指针;失败时返回 NULL
|
||
*********************************************************************/
|
||
tast_register_execute *init_task_list(int count, ...)
|
||
{
|
||
if (count <= 0)
|
||
return NULL; // 确保任务数量合法
|
||
|
||
va_list args; // 用于处理可变参数
|
||
va_start(args, count); // 初始化可变参数列表
|
||
|
||
tast_register_execute *head = NULL, *current = NULL;
|
||
|
||
// 循环遍历每个任务函数
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
task_func_t task_func = va_arg(args, task_func_t); // 获取当前任务函数指针
|
||
tast_register_execute *new_task = register_task(task_func);
|
||
if (new_task == NULL)
|
||
{
|
||
// 内存分配失败时,清理已分配的节点并返回 NULL
|
||
// free_task_list(head);
|
||
va_end(args); // 清理可变参数列表
|
||
return NULL;
|
||
}
|
||
|
||
if (head == NULL)
|
||
{
|
||
// 第一个任务作为头节点
|
||
head = new_task;
|
||
}
|
||
else
|
||
{
|
||
// 将新任务链接到链表末尾
|
||
current->next = new_task;
|
||
}
|
||
current = new_task; // 更新当前任务
|
||
}
|
||
|
||
va_end(args); // 结束可变参数处理
|
||
return head;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 初始化任务注册信息
|
||
* @param[in] 无
|
||
* @return 0:sucessful;1:fault
|
||
*********************************************************************/
|
||
static int logic_initTaskRegister()
|
||
{
|
||
INIT_TASK_GROUP();
|
||
|
||
for (int i = 0; i < E_TACTIC_MODE_END; i++)
|
||
{
|
||
if (task_group[i] == NULL)
|
||
{
|
||
printf("Failed to initialize task group 0.\n");
|
||
return 1; // 错误返回
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 创建任务线程
|
||
* @param[in] 无
|
||
* @return 无
|
||
*********************************************************************/
|
||
static int creatLogicTaskEntry()
|
||
{
|
||
if (pthread_create(&stlogic.tfd, NULL, creatLogicTaskThread, (void *)&stlogic.para_delivery) == 0)
|
||
{
|
||
KITPTF(LOG_LOGIC_EN, INFO_EN, "task线程创建成功");
|
||
KITLOG(LOG_LOGIC_EN, INFO_EN, "task线程创建成功");
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 新建任务模块的初始化工作
|
||
* @param[in] 无
|
||
* @return 0:sucessful;1:fault
|
||
*********************************************************************/
|
||
int creatLogicCtrTaskEntry()
|
||
{
|
||
initTaskParam();
|
||
|
||
if (logic_initTaskRegister() != 0)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
if (creatLogicTaskEntry() != 0)
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 任务触发,读取数据库入参
|
||
* @param[in] 无
|
||
* @return
|
||
*********************************************************************/
|
||
void logic_taskTrigger()
|
||
{
|
||
int modeChange = 0;
|
||
// 读取是否参数更新
|
||
for (u_int16_t i = kSign_Logic_Start; i < kSign_Logic_End; i++)
|
||
{
|
||
stlogic.para_delivery.ParaChangeSign.ParaChangeUnion |= ((readWebSign(kSign_ShMem, i) == LOGIC_SIGN_MESSAGE) << i);
|
||
}
|
||
|
||
// 读取是否切换模式
|
||
if (LOGIC_SIGN_MESSAGE == readWebSign(kSign_ShMem, kSign_LogicMode))
|
||
{
|
||
writeWebSign(kSign_ShMem, kSign_LogicMode, 0);
|
||
modeChange = 1;
|
||
work_mode_set_t tempMode;
|
||
if (0 != kit_get_work_mode_set(&tempMode))
|
||
{
|
||
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
|
||
{
|
||
KITLOG(LOG_LOGIC_EN, INFO_EN, "获取调试配置失败 模式切换失败!!! %s ==> %s",workModeNames[stlogic.para_delivery.mode],workModeNames[tempMode.workMode]);
|
||
KITPTF(LOG_LOGIC_EN, INFO_EN, "获取调试配置失败 模式切换失败!!! %s ==> %s",workModeNames[stlogic.para_delivery.mode],workModeNames[tempMode.workMode]);
|
||
return;
|
||
}
|
||
}
|
||
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
|
||
{
|
||
KITLOG(LOG_LOGIC_EN, INFO_EN, "模式切换 %s ==> %s",workModeNames[stlogic.para_delivery.mode],workModeNames[tempMode.workMode]);
|
||
KITPTF(LOG_LOGIC_EN, INFO_EN, "模式切换 %s ==> %s",workModeNames[stlogic.para_delivery.mode],workModeNames[tempMode.workMode]);
|
||
return;
|
||
}
|
||
stlogic.para_delivery.mode = tempMode.workMode;
|
||
}
|
||
|
||
stlogic.para_delivery.task_params.protect.protectSign = (readWebSign(kSign_ShMem, kSign_Protect) == LOGIC_SIGN_MESSAGE);
|
||
stlogic.para_delivery.task_params.distr.powerSign = (readWebSign(kSign_ShMem, kSign_ActivePower) == LOGIC_SIGN_MESSAGE);
|
||
|
||
//数据库获取参数
|
||
/****保护****/
|
||
if (LOGIC_SIGN_MESSAGE == stlogic.para_delivery.task_params.protect.protectSign)
|
||
{
|
||
if (1 == logic_getProtectParam())
|
||
{
|
||
KITLOG(LOG_LOGIC_EN, INFO_EN, "保护参数错误");
|
||
KITPTF(LOG_LOGIC_EN, INFO_EN, "保护参数错误");
|
||
return;
|
||
}
|
||
stlogic.para_delivery.task_params.protect.protectSign = LOGIC_SIGN_UPLOAD;
|
||
}
|
||
|
||
/****功率分配****/
|
||
if (LOGIC_SIGN_MESSAGE == stlogic.para_delivery.task_params.distr.powerSign)
|
||
{
|
||
if (1 == logic_getPowerDistrParam())
|
||
{
|
||
KITLOG(LOG_LOGIC_EN, INFO_EN, "分配参数错误");
|
||
KITPTF(LOG_LOGIC_EN, INFO_EN, "分配参数错误");
|
||
return;
|
||
}
|
||
// 成功读完清除标志
|
||
stlogic.para_delivery.task_params.distr.powerSign = LOGIC_SIGN_UPLOAD;
|
||
}
|
||
|
||
//判定是否模式和参数统一
|
||
switch (stlogic.para_delivery.mode)
|
||
{
|
||
case E_TACTIC_MODE_DEBUG: // 调试模式
|
||
if (stlogic.para_delivery.ParaChangeSign.bits.debug || modeChange)
|
||
{
|
||
writeWebSign(kSign_ShMem, kSign_LogicDebug, LOGIC_SIGN_NONE);
|
||
if (1 == logic_debugParamUpdate())
|
||
{
|
||
KITLOG(LOG_LOGIC_EN, INFO_EN, "调试参数错误");
|
||
KITPTF(LOG_LOGIC_EN, INFO_EN, "调试参数错误");
|
||
}
|
||
// 成功读完清除标志
|
||
stlogic.para_delivery.ParaChangeSign.bits.debug = LOGIC_SIGN_NONE;
|
||
}
|
||
break;
|
||
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
|
||
if (stlogic.para_delivery.ParaChangeSign.bits.peakValley || modeChange)
|
||
{
|
||
writeWebSign(kSign_ShMem, kSign_LogicPeakValley, LOGIC_SIGN_NONE);
|
||
if (1 == logic_peakValleyUpdate())
|
||
{
|
||
KITLOG(LOG_LOGIC_EN, INFO_EN, "削峰填谷参数错误");
|
||
KITPTF(LOG_LOGIC_EN, INFO_EN, "削峰填谷参数错误");
|
||
}
|
||
// 成功读完清除标志
|
||
stlogic.para_delivery.ParaChangeSign.bits.peakValley = LOGIC_SIGN_NONE;
|
||
}
|
||
break;
|
||
|
||
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
|
||
/* 暂未实现 */
|
||
|
||
break;
|
||
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
|
||
/* 暂未实现 */
|
||
|
||
break;
|
||
case E_TACTIC_MODE_DMDCTRL: // 需量控制
|
||
/* 暂未实现 */
|
||
|
||
break;
|
||
case E_TACTIC_MODE_PFCTRL: // 功率因数
|
||
/* 暂未实现 */
|
||
|
||
break;
|
||
default:
|
||
/*无模式*/
|
||
stlogic.para_delivery.task_params.distr.power = 0;
|
||
stlogic.para_delivery.task_params.protect.power = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 调度函数,根据收到的指令执行对应任务链
|
||
* @param[in] task_param 任务参数
|
||
* @return 0: 成功, 1: 错误(如索引无效)
|
||
*********************************************************************/
|
||
int logic_taskExe(work_mode_e mode)
|
||
{
|
||
if (mode >= E_TACTIC_MODE_END)
|
||
{
|
||
// printf("Invalid task group index!\n");
|
||
return 1; // 返回错误
|
||
}
|
||
|
||
tast_register_execute *current = task_group[mode];
|
||
|
||
// 遍历并执行任务链表中的所有任务
|
||
while (current != NULL)
|
||
{
|
||
current->task(); // 执行当前任务
|
||
current = current->next; // 移动到下一个任务
|
||
}
|
||
|
||
return 0; // 成功
|
||
}
|
||
|
||
/*****************************************************************************
|
||
* @brief 创建任务调度线程
|
||
* @param[in] 无
|
||
* @return 无
|
||
*****************************************************************************/
|
||
void *creatLogicTaskThread(void *arg)
|
||
{
|
||
task_params_t *task_param_in = (task_params_t *)arg;
|
||
while (stlogic.exitTaskFlag == 0)
|
||
{
|
||
logic_taskTrigger();
|
||
logic_getRTDBParams();
|
||
if (0 != logic_taskExe(task_param_in->mode))
|
||
{
|
||
// 处理调度错误,可以记录日志
|
||
KITLOG(LOG_LOGIC_EN, ERROR_EN, "任务调度失败,参数无效");
|
||
usleep(50000); // 50ms sleep
|
||
continue;
|
||
}
|
||
logic_paramUpload();
|
||
|
||
usleep(20000); // 20ms sleep
|
||
}
|
||
|
||
pthread_exit(NULL);
|
||
}
|
||
|
||
void example_task1()
|
||
{
|
||
;
|
||
}
|