commit 476236a24688035e997b29033b32c278bbe23866 Author: cfif Date: Fri Oct 24 12:29:49 2025 +0300 Обновление diff --git a/VarTabDumpObserver.c b/VarTabDumpObserver.c new file mode 100644 index 0000000..fecb364 --- /dev/null +++ b/VarTabDumpObserver.c @@ -0,0 +1,164 @@ +// +// Created by xemon on 19.12.22. +// + +#include +#include "VarsTabDumpObserver.h" +#include "SystemDelayInterface.h" +#include "string.h" + + +#define LOGGER env->logger +#define LOG_SIGN "Хран.Наб." + +void VarsTabDumpObserver_Init( + tVarsTabDumpObserver *env, + tStorageInterface *interface, + uint32_t delay, + void *data, + size_t size, + tVariablesTable *VarsTab, + uint32_t trackableGroup +) { + env->interface = interface; + env->trackableVarsTab = VarsTab; + env->trackableGroup = trackableGroup; + + env->data = data; + env->size = size; + + env->delay = delay; + env->dumpAfter = 0; + env->access = osMutexNew(NULL); + env->accessDumper = osMutexNew(NULL); + + InitThreadAtrStatic(&env->thread.attr, "Data", env->thread.controlBlock, env->thread.stack, osPriorityNormal); + env->thread.id = 0; +} + + +bool VarsTabDumpObserver_Load(tVarsTabDumpObserver *env) { + + if (osMutexAcquire(env->accessDumper, 100) == osOK) { + eStorageStatus dumpStatus = StorageLoad(env->interface, env->data, env->size); + osMutexRelease(env->accessDumper); + + if (dumpStatus == STORAGE_ERR_DEVICE) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка ПЗУ") + env->health = false; + return false; + } else if (dumpStatus == STORAGE_OK) { + env->health = true; + LoggerInfoStatic(LOGGER, LOG_SIGN, "Данные успешно загружены из ПЗУ") + return true; + } + LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка данных при загрузке из ПЗУ") + return false; + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Ошибка чтения ПЗУ!!!") + LoggerErrorStatic(LOGGER, LOG_SIGN, "Ошибка параллельного доступа") + return false; + } + +} + +bool VarsTabDumpObserver_Dump(tVarsTabDumpObserver *env) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Попытка записи в ПЗУ...") + + + if (env->logger) { + env->logger->logging( + env->logger->env, "Хран.Наб.", + sizeof("Хран.Наб.") - 1, + LOGLEVEL_INFO, + "Запись в ПЗУ...", + sizeof("Запись в ПЗУ...") - 1, true + ); + } + + if (osMutexAcquire(env->accessDumper, 100) == osOK) { + + eStorageStatus result = StorageDump(env->interface, env->data, env->size); + + osMutexRelease(env->accessDumper); + + env->health = (result == STORAGE_OK); + + if (env->health) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Успешно записано в ПЗУ") + return true; + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Ошибка записи в ПЗУ!!!") + if (result == STORAGE_ERR_DATA) { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Ошибка контрольной суммы") + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Ошибка ПЗУ") + } + return false; + } + + } else { + LoggerErrorStatic(LOGGER, LOG_SIGN, "Ошибка записи в ПЗУ!!!") + LoggerErrorStatic(LOGGER, LOG_SIGN, "Ошибка параллельного доступа") + return false; + } +} + + +static bool VarsTabDumpObserver_IsNowDumpRequired(tVarsTabDumpObserver *env) { + return env->dumpAfter < SystemGetMs(); +} + +void VarsTabDumpObserver_RequireDump(tVarsTabDumpObserver *env) { + if (osMutexAcquire(env->access, 1) == osOK) { + env->dumpAfter = SystemGetMs() + env->delay; + osMutexRelease(env->access); + } +} + +void DeviceStorageProcessing(tVarsTabDumpObserver *env) { + if (VariablesTable_TakeChange(env->trackableVarsTab, env->trackableGroup)) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружены изменения, необходима запись в ПЗУ") + VarsTabDumpObserver_RequireDump(env); + } + + if (env->dumpAfter && VarsTabDumpObserver_IsNowDumpRequired(env)) { + if (osMutexAcquire(env->access, 1) == osOK) { + if (VarsTabDumpObserver_IsNowDumpRequired(env)) { + VarsTabDumpObserver_Dump(env); + env->dumpAfter = 0; + } + osMutexRelease(env->access); + } + } +} + +static _Noreturn void VarsTabDumpObserver_Thread(tVarsTabDumpObserver *env) { + for (;;) { + DeviceStorageProcessing(env); + SystemDelayMs(100); + } +} + +void VarsTabDumpObserver_StartThread(tVarsTabDumpObserver *env) { + ThreadBlock_Start(env->thread, env, VarsTabDumpObserver_Thread); +} + +void VarsTabDumpObserver_StopThread(tVarsTabDumpObserver *env) { + ThreadBlock_Stop(env->thread); +} + + +void VarsTabDumpObserver_Flush(tVarsTabDumpObserver *env) { + if (env->dumpAfter) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Есть изменения, записываем в ПЗУ") + if (osMutexAcquire(env->access, 10000) == osOK) { + VarsTabDumpObserver_Dump(env); + env->dumpAfter = 0; + osMutexRelease(env->access); + } + } +} + + + diff --git a/VarsTabDumpObserver.h b/VarsTabDumpObserver.h new file mode 100644 index 0000000..504fac2 --- /dev/null +++ b/VarsTabDumpObserver.h @@ -0,0 +1,57 @@ +// +// Created by CFIF on 19.12.22. +// + +#ifndef HVAC_VarsTabDumpOBSERVER_H +#define HVAC_VarsTabDumpOBSERVER_H + +#include +#include "VariablesTable.h" +#include "LoggerInterface.h" + +typedef struct { + tLoggerInterface *logger; + tStorageInterface *interface; + tVariablesTable *trackableVarsTab; + uint32_t trackableGroup; + void *data; + size_t size; + + bool health; + + osMutexId_t access; + osMutexId_t accessDumper; + uint32_t dumpAfter; + uint32_t delay; + + struct { + osThreadId_t id; + uint32_t stack[256]; + StaticTask_t controlBlock; + osThreadAttr_t attr; + } thread; +} tVarsTabDumpObserver; + +void VarsTabDumpObserver_Init( + tVarsTabDumpObserver *env, + tStorageInterface *interface, + uint32_t delay, + void *data, + size_t size, + tVariablesTable *VarsTab, + uint32_t trackableGroup +); + +bool VarsTabDumpObserver_Load(tVarsTabDumpObserver *env); + +bool VarsTabDumpObserver_Dump(tVarsTabDumpObserver *env); + +void VarsTabDumpObserver_RequireDump(tVarsTabDumpObserver *env); + +void VarsTabDumpObserver_StartThread(tVarsTabDumpObserver *env); + +void VarsTabDumpObserver_StopThread(tVarsTabDumpObserver *env); + +void VarsTabDumpObserver_Flush(tVarsTabDumpObserver *env); + +#endif //HVAC_VarsTabDumpOBSERVER_H diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..0dd1901 --- /dev/null +++ b/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "./**.c" + ] + } +} \ No newline at end of file