/***************************************************************************** * @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() { ; }