diff --git a/LinActuatorTasks.c b/LinActuatorTasks.c index 89a2bca..155f951 100644 --- a/LinActuatorTasks.c +++ b/LinActuatorTasks.c @@ -9,6 +9,8 @@ #include "Lins.h" #include "LoggerInterface.h" #include "string.h" +#include "LinActuatorWork.h" +#include "HVAC_model.h" //#define LOG_SIGN "Lin0" #define LOGGER env->logger @@ -597,17 +599,23 @@ static lin_event_id_t Lin_Scheduler(tLinTaskActuator *env, uint8_t numAct) { if ((numAct == 1) && (a1 == false)) { a1 = true; - LoggerFormatInfo(LOGGER, env->SIGN_LOG, "----------------------START----ACT1--------------------------------------------------------", 1) + LoggerFormatInfo(LOGGER, env->SIGN_LOG, + "----------------------START----ACT1--------------------------------------------------------", + 1) } if ((numAct == 2) && (a2 == false)) { a2 = true; - LoggerFormatInfo(LOGGER, env->SIGN_LOG, "----------------------START----ACT2--------------------------------------------------------", 1) + LoggerFormatInfo(LOGGER, env->SIGN_LOG, + "----------------------START----ACT2--------------------------------------------------------", + 1) } if ((numAct == 3) && (a3 == false)) { a3 = true; - LoggerFormatInfo(LOGGER, env->SIGN_LOG, "----------------------START----ACT3--------------------------------------------------------", 1) + LoggerFormatInfo(LOGGER, env->SIGN_LOG, + "----------------------START----ACT3--------------------------------------------------------", + 1) } @@ -1163,11 +1171,19 @@ void Lin_1_Init(tLinTaskActuator *env, tLinData *linData, tLinIO *linIO, uint8_t LIN_ISSR_ALL, + osMutexId_t modelTaskAccess, + + ActuatorCmdBus *actuator_Command_Model_trigger_local, + bool *triggerCommand, + tLoggerInterface *logger) { env->linIo = linIO; env->linData = linData; env->logger = logger; + env->modelTaskAccess = modelTaskAccess; + env->actuator_Command_Model_trigger_local = actuator_Command_Model_trigger_local; + env->triggerCommand = triggerCommand; env->LIN_ISSR_ALL = LIN_ISSR_ALL; env->access = osMutexNew(NULL); @@ -1182,6 +1198,15 @@ static _Noreturn void Lin1_Thread(tLinTaskActuator *env) { for (;;) { if (osMutexAcquire(env->access, 5000) == osOK) { + + + LinActuatorWork(env, env->modelTaskAccess, 1, + &env->actuator_Ch012_Command_Model_local, + env->actuator_Command_Model_trigger_local, + &env->actuator_Ch012_Input_Model_local, + &Actuator_Ch0_Status_Model, env->triggerCommand, "Ln1 "); + + lin_event_id_t res = Lin_Scheduler(env, 1); uint8_t isError = 0; @@ -1229,11 +1254,20 @@ void Lin_2_Init(tLinTaskActuator *env, tLinData *linData, tLinIO *linIO, uint8_t LIN_ISSR_ALL, + osMutexId_t modelTaskAccess, + ActuatorCmdBus *actuator_Command_Model_trigger_local, + bool *triggerCommand, tLoggerInterface *logger) { env->linIo = linIO; env->linData = linData; env->logger = logger; + + env->modelTaskAccess = modelTaskAccess; + env->actuator_Command_Model_trigger_local = actuator_Command_Model_trigger_local; + env->triggerCommand = triggerCommand; + + env->LIN_ISSR_ALL = LIN_ISSR_ALL; env->access = osMutexNew(NULL); @@ -1248,6 +1282,13 @@ static _Noreturn void Lin2_Thread(tLinTaskActuator *env) { for (;;) { if (osMutexAcquire(env->access, 5000) == osOK) { + + LinActuatorWork(env, env->modelTaskAccess, 2, + &env->actuator_Ch012_Command_Model_local, + env->actuator_Command_Model_trigger_local, + &env->actuator_Ch012_Input_Model_local, + &Actuator_Ch1_Status_Model, env->triggerCommand, "Ln2 "); + lin_event_id_t res = Lin_Scheduler(env, 2); uint8_t isError = 0; @@ -1295,11 +1336,19 @@ void Lin_3_Init(tLinTaskActuator *env, tLinData *linData, tLinIO *linIO, uint8_t LIN_ISSR_ALL, + osMutexId_t modelTaskAccess, + ActuatorCmdBus *actuator_Command_Model_trigger_local, + bool *triggerCommand, tLoggerInterface *logger) { env->linIo = linIO; env->linData = linData; env->logger = logger; + + env->modelTaskAccess = modelTaskAccess; + env->actuator_Command_Model_trigger_local = actuator_Command_Model_trigger_local; + env->triggerCommand = triggerCommand; + env->LIN_ISSR_ALL = LIN_ISSR_ALL; env->access = osMutexNew(NULL); @@ -1314,6 +1363,13 @@ static _Noreturn void Lin3_Thread(tLinTaskActuator *env) { for (;;) { if (osMutexAcquire(env->access, 5000) == osOK) { + + LinActuatorWork(env, env->modelTaskAccess, 3, + &env->actuator_Ch012_Command_Model_local, + env->actuator_Command_Model_trigger_local, + &env->actuator_Ch012_Input_Model_local, + &Actuator_Ch2_Status_Model, env->triggerCommand, "Ln3 "); + lin_event_id_t res = Lin_Scheduler(env, 3); uint8_t isError = 0; diff --git a/LinActuatorTasks.h b/LinActuatorTasks.h index 26fd890..906a6d0 100644 --- a/LinActuatorTasks.h +++ b/LinActuatorTasks.h @@ -8,11 +8,12 @@ #include #include "stdbool.h" #include "LinIO.h" +#include "HVAC_model_types.h" #include "LoggerInterface.h" #define LOG_LIN_ACTUATOR 1 -#define LOG_LIN1_ACTUATOR 1 -#define LOG_LIN2_ACTUATOR 1 +#define LOG_LIN1_ACTUATOR 0 +#define LOG_LIN2_ACTUATOR 0 #define LOG_LIN3_ACTUATOR 1 @@ -115,7 +116,6 @@ typedef struct __attribute__ ((packed)) { eCoils_Stop_SET Coils_Stop_SET: 2; - } ACT_CFR_SET; // Using this service the master can switch an actuator to a needed functional mode. @@ -461,6 +461,18 @@ typedef struct { tLoggerInterface *logger; + + ActuatorCmdBus *actuator_Command_Model_trigger_local; + bool *triggerCommand; + osMutexId_t modelTaskAccess; + + // Входные данные (локальные) для модели + ActuatorCmdBus actuator_Ch012_Command_Model_local; + + // Выходные данные (локальные) для модели + ActuatorCmdBusInput actuator_Ch012_Input_Model_local; + + struct { osThreadId_t id; uint32_t stack[384]; @@ -474,6 +486,9 @@ void Lin_1_Init(tLinTaskActuator *env, tLinData *linData, tLinIO *linIO, uint8_t LIN_ISSR_ALL, + osMutexId_t modelTaskAccess, + ActuatorCmdBus *actuator_Command_Model_trigger_local, + bool *triggerCommand, tLoggerInterface *logger); void Lin1_StartThread(tLinTaskActuator *env); @@ -482,6 +497,9 @@ void Lin_2_Init(tLinTaskActuator *env, tLinData *linData, tLinIO *linIO, uint8_t LIN_ISSR_ALL, + osMutexId_t modelTaskAccess, + ActuatorCmdBus *actuator_Command_Model_trigger_local, + bool *triggerCommand, tLoggerInterface *logger); void Lin2_StartThread(tLinTaskActuator *env); @@ -490,6 +508,9 @@ void Lin_3_Init(tLinTaskActuator *env, tLinData *linData, tLinIO *linIO, uint8_t LIN_ISSR_ALL, + osMutexId_t modelTaskAccess, + ActuatorCmdBus *actuator_Command_Model_trigger_local, + bool *triggerCommand, tLoggerInterface *logger); void Lin3_StartThread(tLinTaskActuator *env); diff --git a/LinActuatorWork.c b/LinActuatorWork.c new file mode 100644 index 0000000..60e660c --- /dev/null +++ b/LinActuatorWork.c @@ -0,0 +1,181 @@ +// +// Created by cfif on 20.01.2026. +// +#include "LinActuatorWork.h" +#include "string.h" + + +//#define LOG_SIGN "Lin" +#define LOGGER linTaskActuator->logger + +static bool isBroadCastTriggered(tLinTaskActuator *env, ActuatorCmdBus *actuator_Command_Model_trigger_local) { + + for (uint8_t j = 0; j < env->LIN_ISSR_ALL; ++j) { + if (actuator_Command_Model_trigger_local->BUS_ADR[j] != 0) { + return false; + } + } + + return true; +} + +static void showLogCommand(tLinTaskActuator *linTaskActuator, char *LOG_SIGN, uint8_t BUS_ADR, uint8_t COM) { + switch (COM) { + case LIN_ACT_CFR_NONE: { + LoggerFormatInfo(LOGGER, LOG_SIGN, "BUS_ADR: %d - NO COMMAND", BUS_ADR) + break; + } + + case LIN_ACT_CFR_MOD: { + LoggerFormatInfo(LOGGER, LOG_SIGN, "BUS_ADR: %d - LIN_ACT_CFR_MOD", BUS_ADR) + break; + } + + case LIN_ACT_CFR_INI: { + LoggerFormatInfo(LOGGER, LOG_SIGN, "BUS_ADR: %d - LIN_ACT_CFR_INI", BUS_ADR) + break; + } + + case LIN_ACT_CFR_SET: { + LoggerFormatInfo(LOGGER, LOG_SIGN, "BUS_ADR: %d - LIN_ACT_CFR_SET", BUS_ADR) + break; + } + + default: { + LoggerFormatInfo(LOGGER, LOG_SIGN, "BUS_ADR: %d - UNKNOWN COMMAND", BUS_ADR) + break; + } + + } +} + +#if (LOG_LIN_ACTUATOR == 1) +#define IS_LOGGING_ENABLED(numAct) \ + ( (numAct == 1 && LOG_LIN1_ACTUATOR == 1) || \ + (numAct == 2 && LOG_LIN2_ACTUATOR == 1) || \ + (numAct == 3 && LOG_LIN3_ACTUATOR == 1) ) +#endif + +// actuator_Command_Model_local - Выход модели (команды для актуаторов) ЛОКАЛЬНО +// actuator_Command_Model_trigger_local - Выход модели (команды для актуаторов) ЗАХВАТ +// actuator_Output_Model_local - Вход модели (состояния актуаторов) ЛОКАЛЬНЫЙ +// actuator_Output_Model_model - Вход модели (состояния актуаторов) МОДЕЛИ + +void LinActuatorWork(tLinTaskActuator *linTaskActuator, osMutexId_t modelTaskAccess, uint8_t numAct, + ActuatorCmdBus *actuator_Command_Model_local, + ActuatorCmdBus *actuator_Command_Model_trigger_local, + ActuatorCmdBusInput *actuator_Output_Model_local, + ActuatorCmdBusInput *actuator_Output_Model_model, + bool *triggerCommand, + char *LOG_SIGN) { + + + for (uint8_t i = 0; i < linTaskActuator->LIN_ISSR_ALL; ++i) { + + linTaskActuator->linCommandActuator[i].POS = actuator_Command_Model_local->POS[i]; + linTaskActuator->linCommandActuator[i].BUS_ADR = actuator_Command_Model_local->BUS_ADR[i]; + linTaskActuator->linCommandActuator[i].MODE = actuator_Command_Model_local->MODE[i]; + + // Если команда выполнена + if (linTaskActuator->linCommandActuator[i].COM == LIN_ACT_CFR_SUCCESSFUL) { +#if (LOG_LIN_ACTUATOR == 1) + if (IS_LOGGING_ENABLED(numAct)) { + LoggerFormatInfo(LOGGER, LOG_SIGN, "BUS_ADR: %d - SUCCESSFUL COMMAND (UNSET BUSY)", i + 1) + } +#endif + // LoggerFormatInfo(LOGGER, LOG_SIGN, "ACTUATOR %d - SUCCESSFUL COMMAND (UNSET BUSY)", numAct) + + actuator_Output_Model_local->Busy = 0; + // Разрешение обработки новой команды + //env->isActuatorNoGetNextCommand[numAct - 1] = false; + + // Обнуляем команду в локальном буфере + actuator_Command_Model_local->COM[i] = LIN_ACT_CFR_NONE; + } + + // ТОЛЬКО если команда не SUCCESSFUL, копируем новые данные + linTaskActuator->linCommandActuator[i].COM = actuator_Command_Model_local->COM[i]; + linTaskActuator->linCommandActuator[i].Stall_SET = actuator_Command_Model_local->Stall_SET[i]; + linTaskActuator->linCommandActuator[i].Lnoise_SET = actuator_Command_Model_local->Lnoise_SET[i]; + linTaskActuator->linCommandActuator[i].Autos_SET = actuator_Command_Model_local->Autos_SET[i]; + linTaskActuator->linCommandActuator[i].Speed_SET = actuator_Command_Model_local->Speed_SET[i]; + linTaskActuator->linCommandActuator[i].Coils_Stop_SET = actuator_Command_Model_local->Coils_Stop_SET[i]; + + // Заполнение данных ВХОДЫ МОДЕЛИ + actuator_Output_Model_local->in_CPOS_ALL[i] = (int16_t) linTaskActuator->linStateActuator[i].CPOS_ALL; + actuator_Output_Model_local->in_Act_Emrf_Slave[i] = (int8_t) linTaskActuator->linStateActuator[i].Emrf_Slave; + actuator_Output_Model_local->in_Mode_Slave[i] = (int8_t) linTaskActuator->linStateActuator[i].Mode_Slave; + actuator_Output_Model_local->in_Act_Err1_Supply[i] = (int8_t) linTaskActuator->linStateActuator[i].Error1_Supply_Slave; + actuator_Output_Model_local->in_Act_Err2_Communication[i] = (int8_t) linTaskActuator->linStateActuator[i].Error2_Communication_Slave; + actuator_Output_Model_local->in_Act_Err3_Temperature[i] = (int8_t) linTaskActuator->linStateActuator[i].Error3_Temperature_Slave; + actuator_Output_Model_local->in_Act_Err4_Permanent_Electrical[i] = (int8_t) linTaskActuator->linStateActuator[i].Error4_Permanent_Electrical_Slave; + actuator_Output_Model_local->in_Act_Stall_Slave[i] = linTaskActuator->linStateActuator[i].Stall_Slave; + actuator_Output_Model_local->in_Act_Reset[i] = linTaskActuator->linStateActuator[i].Reset_Slave; + } + + // Заполнение данных ВХОДЫ МОДЕЛИ + actuator_Output_Model_local->Error_Connect = linTaskActuator->error_connect; + +// LoggerFormatInfo(LOGGER, LOG_SIGN, "Busy = %d Error_Connect = %d", actuator_Output_Model_local->Busy, actuator_Output_Model_local->Error_Connect) + + + + + + if (osMutexAcquire(modelTaskAccess, 5000) == osOK) { + + // Если прията команда и актуатор не занят (может принимать команды) +// if ((*triggerCommand == true) && (env->isActuatorNoGetNextCommand[numAct - 1] == false)) { + if (*triggerCommand == true) { + + *triggerCommand = false; + +#if (LOG_LIN_ACTUATOR == 1) + if (IS_LOGGING_ENABLED(numAct)) { + if (isBroadCastTriggered(linTaskActuator, actuator_Command_Model_trigger_local)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "DETECT COMMAND (BROADCAST):") + showLogCommand(linTaskActuator, LOG_SIGN, actuator_Command_Model_trigger_local->BUS_ADR[0], + actuator_Command_Model_trigger_local->COM[0]); + } else { + LoggerInfoStatic(LOGGER, LOG_SIGN, "DETECT COMMAND (NO BROADCAST):") + for (uint8_t i = 0; i < linTaskActuator->LIN_ISSR_ALL; ++i) { + showLogCommand(linTaskActuator, LOG_SIGN, actuator_Command_Model_trigger_local->BUS_ADR[i], + actuator_Command_Model_trigger_local->COM[i]); + } + } + } +#endif + // + actuator_Output_Model_local->Busy = 1; + + // Запрещение обработки новой команды + //env->isActuatorNoGetNextCommand[numAct - 1] = true; + + // начало --- ВЫХОД МОДЕЛИ ---------- + + // ВЫХОД МОДЕЛИ + memcpy(actuator_Command_Model_local, actuator_Command_Model_trigger_local, sizeof(ActuatorCmdBus)); + + // Сброс STALL в состоянии актуатор (локальном состоянии) + +#if (LOG_LIN_ACTUATOR == 1) + if (IS_LOGGING_ENABLED(numAct)) { + LoggerInfoStatic(LOGGER, linTaskActuator->SIGN_LOG, "Reset LOCAL STALL (DETECT STALL RESET)") + } +#endif + for (uint8_t i = 0; i < linTaskActuator->LIN_ISSR_ALL; ++i) { + actuator_Output_Model_local->in_Act_Stall_Slave[i] = LIN_STALL_STA_OFF; + } + + // конец --- ВЫХОД МОДЕЛИ ---------- + + } + + // ВХОДЫ МОДЕЛИ + memcpy(actuator_Output_Model_model, actuator_Output_Model_local, sizeof(ActuatorCmdBusInput)); + + osMutexRelease(modelTaskAccess); + } + + +} diff --git a/LinActuatorWork.h b/LinActuatorWork.h new file mode 100644 index 0000000..db77741 --- /dev/null +++ b/LinActuatorWork.h @@ -0,0 +1,18 @@ +// +// Created by cfif on 20.01.2026. +// + +#ifndef HVAC_M7_LINACTUATORWORK_H +#define HVAC_M7_LINACTUATORWORK_H + +#include "LinActuatorTasks.h" + +void LinActuatorWork(tLinTaskActuator *linTaskActuator, osMutexId_t modelTaskAccess, uint8_t numAct, + ActuatorCmdBus *actuator_Command_Model_local, + ActuatorCmdBus *actuator_Command_Model_trigger_local, + ActuatorCmdBusInput *actuator_Output_Model_local, + ActuatorCmdBusInput *actuator_Output_Model_model, + bool *triggerCommand, + char *LOG_SIGN); + +#endif //HVAC_M7_LINACTUATORWORK_H