399 lines
15 KiB
C
399 lines
15 KiB
C
/*****************************************************************************
|
||
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
|
||
* @file logic_task_schedu.c
|
||
* @brief xxxx
|
||
* @author Gary
|
||
* @date 2024/09/28
|
||
* @remark 初修订
|
||
*****************************************************************************/
|
||
#include <pthread.h>
|
||
#include "logic_comm.h"
|
||
|
||
// 各模块任务函数注册
|
||
// static task_funcPoint_t g_taskUnitSet;
|
||
|
||
// 设置任务的固定参数和初始参数
|
||
// static task_params_t g_defaultParams;
|
||
|
||
// 序号,设备号,点位ID
|
||
ParamFromRTDB RTDBtable[e_Logic_RTDB_end] =
|
||
{
|
||
{e_Logic_totalAcPower, kDev_Type_Pccmeter, kPCC_TotalActivePwr },
|
||
{e_Logic_emsActivePower, kDev_Type_Bsmeter, kBs_TotalActivePwr },
|
||
{e_Logic_bmsSoc, kDev_Type_BCU, kBcu_SOC },
|
||
{e_Logic_pcsMaxChaPower, kDev_Type_PCS, kPcs_MaxAllowedChgPwr },
|
||
{e_Logic_pcsMaxDiscPower, kDev_Type_PCS, kPcs_MaxAllowedDisChgPwr },
|
||
{e_Logic_nowBmsPower, kDev_Type_PCS, kPcs_TotalActivePwr },
|
||
{e_Logic_nowActiveDemand, kDev_Type_Pccmeter, kPCC_MaxDemandActiveFwd },
|
||
{e_Logic_distrPower, kDev_Type_PCS, kPcs_ConstantActivePwrSet },
|
||
{e_Logic_pcsSwitch, kDev_Type_PCS, kPcs_DeviceSwitchCommand },
|
||
{e_Logic_pcsState, kDev_Type_PCS, kPcs_IsOnline },
|
||
{e_Logic_bmsState, kDev_Type_BCU, kBcu_IsOnline },
|
||
{e_Logic_emsMode, kDev_Type_EMS, kEms_LogicMode },
|
||
{e_Logic_bsuMaxCellTemp, kDev_Type_BSU, kBsu_MaxCellTemp },
|
||
{e_Logic_bsuMinCellTemp, kDev_Type_BSU, kBsu_MinCellTemp }
|
||
// {e_Logic_AcLiquidSwitch, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetOnOff },
|
||
// {e_Logic_AcLiquidHeatTemp, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetHeatTemp },
|
||
// {e_Logic_AcLiquidColdTemp, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetCoolDiff }
|
||
};
|
||
|
||
/*****************************************************************************
|
||
* @brief 获取RTDB参数
|
||
* @param[in] 枚举序号,参数指针,数据类型
|
||
* @return 无
|
||
*****************************************************************************/
|
||
void logic_getValue(int No, void *value, data_type_e dataType)
|
||
{
|
||
if (No < 0 || No >= e_Logic_RTDB_end)
|
||
{
|
||
// 输入的 No 无效
|
||
return;
|
||
}
|
||
|
||
// 从表格中获取对应的条目
|
||
ParamFromRTDB entry = RTDBtable[No];
|
||
|
||
switch (dataType)
|
||
{
|
||
case Uint8:
|
||
{
|
||
// 对于 uint8_t 类型
|
||
uint8_t *uint8Value = (uint8_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
uint8Value[i] = (uint8_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Int8:
|
||
{
|
||
// 对于 int8_t 类型
|
||
int8_t *int8Value = (int8_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
int8Value[i] = (int8_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Uint16:
|
||
{
|
||
// 对于 uint16_t 类型
|
||
uint16_t *uint16Value = (uint16_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
uint16Value[i] = (uint16_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Int16:
|
||
{
|
||
// 对于 int16_t 类型
|
||
int16_t *int16Value = (int16_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
int16Value[i] = (int16_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Uint32:
|
||
{
|
||
// 对于 uint32_t 类型
|
||
uint32_t *uint32Value = (uint32_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
uint32Value[i] = (uint32_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Int32:
|
||
{
|
||
// 对于 int32_t 类型
|
||
int32_t *int32Value = (int32_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
int32Value[i] = (int32_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Uint64:
|
||
{
|
||
// 对于 uint64_t 类型
|
||
uint64_t *uint64Value = (uint64_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
uint64Value[i] = (uint64_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Int64:
|
||
{
|
||
// 对于 int64_t 类型
|
||
int64_t *int64Value = (int64_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
int64Value[i] = (int64_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Float32:
|
||
{
|
||
// 对于 float_t (Float32) 类型
|
||
float_t *floatValue = (float_t *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
floatValue[i] = (float_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
case Float64:
|
||
{
|
||
// 对于 double (Float64) 类型
|
||
double *doubleValue = (double *)value;
|
||
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
|
||
{
|
||
doubleValue[i] = getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
// 不支持的类型
|
||
return;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
* @brief 判断跳过语句
|
||
* @param[in] No 枚举序号(对应 RTDBtable 中的索引)
|
||
* @param[in] value 参数指针,表示要写入的数据
|
||
* @param[in] num 数量
|
||
* @return 无
|
||
*****************************************************************************/
|
||
void logic_skip_judge(bool *skip, uint16_t num, int No, void *value, data_type_e dataType)
|
||
{
|
||
ParamFromRTDB entry = RTDBtable[No];
|
||
|
||
for (uint16_t i = 0; i < num; i++)
|
||
{
|
||
// skip[i] = false; // 默认不跳过
|
||
if(stlogic.para_delivery.task_params.distr.allocateMode)
|
||
{
|
||
float_t *floatValue = (float_t *)value;
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_APhaseAPSet, (float_t)floatValue[i]/3);
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_BPhaseAPSet, (float_t)floatValue[i]/3);
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_CPhaseAPSet, (float_t)floatValue[i]/3);
|
||
skip[i] = true; // 标记跳过
|
||
continue;
|
||
}
|
||
|
||
// 根据 No 值进行不同的处理
|
||
switch (No)
|
||
{
|
||
case e_Logic_pcsSwitch: // PCS开关
|
||
// 判断 pcsState 和 bmsState
|
||
if (stlogic.para_delivery.task_params.distr.pcsState[i] == 0 ||
|
||
stlogic.para_delivery.task_params.distr.bmsState[i] == 0)
|
||
{
|
||
skip[i] = true; // 标记跳过
|
||
}
|
||
else
|
||
{
|
||
// _PCS 特殊处理
|
||
#ifdef _PCS
|
||
// if (dataType == Uint16 && value != NULL)
|
||
// {
|
||
uint16_t *uint16Value = (uint16_t *)value;
|
||
if (uint16Value[i])
|
||
{
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceStartup, 1.0);
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceShutdown, 0.0);
|
||
}
|
||
else
|
||
{
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceStartup, 0.0);
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceShutdown, 1.0);
|
||
}
|
||
// }
|
||
skip[i] = true; // 标记跳过
|
||
#endif
|
||
}
|
||
break;
|
||
|
||
case e_Logic_distrPower: // distrPower 为 No 的处理逻辑
|
||
// 判断 pcsState 和 bmsState
|
||
if (stlogic.para_delivery.task_params.distr.pcsState[i] == 0 ||
|
||
stlogic.para_delivery.task_params.distr.bmsState[i] == 0)
|
||
{
|
||
// 分配电力为 No 且满足保护条件时跳过
|
||
if (E_TACTIC_MODE_DEBUG != stlogic.para_delivery.mode ||
|
||
!stlogic.para_delivery.task_params.debug.protectSwitch)
|
||
{
|
||
skip[i] = true; // 标记跳过
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
// 如果 No 不符合任何已定义的条件,默认不跳过
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*****************************************************************************
|
||
* @brief 写入RTDB参数
|
||
* @param[in] No 枚举序号(对应 RTDBtable 中的索引)
|
||
* @param[in] value 参数指针,表示要写入的数据
|
||
* @param[in] num 数量
|
||
* @param[in] dataType 数据类型,表示写入的数据类型(Uint8、Int16 等)
|
||
* @return 无
|
||
*****************************************************************************/
|
||
void logic_setValue(int No, void *value, uint16_t num, data_type_e dataType)
|
||
{
|
||
if (No < 0 || No >= e_Logic_RTDB_end)
|
||
{
|
||
// 输入的 No 无效
|
||
return;
|
||
}
|
||
|
||
// 从表格中获取对应的条目
|
||
ParamFromRTDB entry = RTDBtable[No];
|
||
|
||
bool skip[MAX_NUM_CABINT] = {false};
|
||
// 调用跳过判断逻辑
|
||
logic_skip_judge(skip, num, No, value, dataType);
|
||
|
||
for (uint16_t i = 0; i < num; i++)
|
||
{
|
||
if (skip[i])
|
||
continue;
|
||
|
||
switch (dataType)
|
||
{
|
||
case Uint8:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint8_t*)value)[i]);
|
||
break;
|
||
case Int8:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int8_t*)value)[i]);
|
||
break;
|
||
case Uint16:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint16_t*)value)[i]);
|
||
break;
|
||
case Int16:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int16_t*)value)[i]);
|
||
break;
|
||
case Uint32:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint32_t*)value)[i]);
|
||
break;
|
||
case Int32:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int32_t*)value)[i]);
|
||
break;
|
||
case Uint64:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint64_t*)value)[i]);
|
||
break;
|
||
case Int64:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int64_t*)value)[i]);
|
||
break;
|
||
case Float32:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((float*)value)[i]);
|
||
break;
|
||
case Float64:
|
||
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, ((double*)value)[i]);
|
||
break;
|
||
default:
|
||
// 不支持的类型,返回
|
||
return;
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
* @brief 实时库获取参数
|
||
*
|
||
* @return 0 更新成功 -1 失败 1 无更新
|
||
*****************************************************************************/
|
||
void logic_getRTDBParams()
|
||
{
|
||
/*获取电表的数据*/
|
||
logic_getValue(e_Logic_totalAcPower, &stlogic.para_delivery.task_params.protect.totalActivePower, Float32);
|
||
logic_getValue(e_Logic_emsActivePower, &stlogic.para_delivery.task_params.protect.emsActivePower, Float32);
|
||
logic_getValue(e_Logic_nowActiveDemand, &stlogic.para_delivery.task_params.protect.nowActiveDemand, Float32);
|
||
|
||
/*获取pcs的数据*/
|
||
logic_getValue(e_Logic_bmsSoc, &stlogic.para_delivery.task_params.distr.bmsSoc, Float32);
|
||
logic_getValue(e_Logic_pcsMaxChaPower, &stlogic.para_delivery.task_params.distr.pcsMaxChaPower, Float32);
|
||
logic_getValue(e_Logic_pcsMaxDiscPower, &stlogic.para_delivery.task_params.distr.pcsMaxDiscPower, Float32);
|
||
logic_getValue(e_Logic_nowBmsPower, &stlogic.para_delivery.task_params.distr.nowBmsPower, Float32);
|
||
logic_getValue(e_Logic_pcsState, &stlogic.para_delivery.task_params.distr.pcsState, Uint8);
|
||
logic_getValue(e_Logic_bmsState, &stlogic.para_delivery.task_params.distr.bmsState, Uint8);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* @brief 数据返回实时库
|
||
* @param[in] 无
|
||
* @return
|
||
*********************************************************************/
|
||
int logic_paramUpload()
|
||
{
|
||
|
||
if (LOGIC_SIGN_UPLOAD == stlogic.para_delivery.task_params.protect.protectSign)
|
||
{
|
||
stlogic.para_delivery.task_params.protect.protectSign = LOGIC_SIGN_NONE;
|
||
writeWebSign(kSign_ShMem, kSign_Protect, LOGIC_SIGN_UPLOAD);
|
||
}
|
||
|
||
if (LOGIC_SIGN_UPLOAD == stlogic.para_delivery.task_params.distr.powerSign)
|
||
{
|
||
stlogic.para_delivery.task_params.distr.powerSign = LOGIC_SIGN_NONE;
|
||
writeWebSign(kSign_ShMem, kSign_ActivePower, LOGIC_SIGN_UPLOAD);
|
||
}
|
||
|
||
switch (stlogic.para_delivery.mode)
|
||
{
|
||
case E_TACTIC_MODE_DEBUG: // 调试模式
|
||
writeWebSign(kSign_ShMem, kSign_LogicDebug, LOGIC_SIGN_UPLOAD);
|
||
// PCS开关机下发
|
||
logic_setValue(e_Logic_pcsSwitch, &stlogic.para_delivery.task_params.distr.pcsSwitch, stlogic.para_delivery.task_params.distr.cabintCont, Uint16);
|
||
// 功率下发
|
||
logic_setValue(e_Logic_distrPower, &stlogic.para_delivery.task_params.distr.nowDistPower, stlogic.para_delivery.task_params.distr.cabintCont, Float32);
|
||
break;
|
||
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
|
||
writeWebSign(kSign_ShMem, kSign_LogicPeakValley, LOGIC_SIGN_UPLOAD);
|
||
// PCS开关机下发
|
||
logic_setValue(e_Logic_pcsSwitch, &stlogic.para_delivery.task_params.distr.pcsSwitch, stlogic.para_delivery.task_params.distr.cabintCont, Uint16);
|
||
// 功率下发
|
||
logic_setValue(e_Logic_distrPower, &stlogic.para_delivery.task_params.distr.nowDistPower, stlogic.para_delivery.task_params.distr.cabintCont, Float32);
|
||
break;
|
||
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
|
||
/* 暂未实现 */
|
||
// 系统状态更新为停机
|
||
updateState(kState_Shutdown, true);
|
||
break;
|
||
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
|
||
/* 暂未实现 */
|
||
// 系统状态更新为停机
|
||
updateState(kState_Shutdown, true);
|
||
break;
|
||
case E_TACTIC_MODE_DMDCTRL: // 需量控制
|
||
/* 暂未实现 */
|
||
// 系统状态更新为停机
|
||
updateState(kState_Shutdown, true);
|
||
break;
|
||
case E_TACTIC_MODE_PFCTRL: // 功率因数
|
||
/* 暂未实现 */
|
||
// 系统状态更新为停机
|
||
updateState(kState_Shutdown, true);
|
||
break;
|
||
default:
|
||
// 系统状态更新为停机
|
||
updateState(kState_Shutdown, true);
|
||
break;
|
||
}
|
||
// 运行模式入RTDB
|
||
logic_setValue(e_Logic_emsMode, &stlogic.para_delivery.mode, 1, Uint16);
|
||
return 0;
|
||
}
|