From bf9ced85d95ba803db66bfdcfae441eebf9cc541 Mon Sep 17 00:00:00 2001 From: cfif Date: Wed, 4 Dec 2024 13:10:49 +0300 Subject: [PATCH] Init --- VarTabDumpObserver.c | 148 ++++++++++++++++++++++++++++++++++++++++++ VarsTabDumpObserver.h | 55 ++++++++++++++++ modular.json | 22 +++++++ 3 files changed, 225 insertions(+) create mode 100644 VarTabDumpObserver.c create mode 100644 VarsTabDumpObserver.h create mode 100644 modular.json diff --git a/VarTabDumpObserver.c b/VarTabDumpObserver.c new file mode 100644 index 0000000..0187aee --- /dev/null +++ b/VarTabDumpObserver.c @@ -0,0 +1,148 @@ +// +// Created by xemon on 19.12.22. +// + +#include +#include "VarsTabDumpObserver.h" +#include "SystemDelayInterface.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 (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) { + if (!env->thread.id) { + env->thread.id = osThreadNew((osThreadFunc_t) (VarsTabDumpObserver_Thread), (void *) (env), &env->thread.attr); + } +} + + +void VarsTabDumpObserver_Flush(tVarsTabDumpObserver *env) { + if (env->dumpAfter) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Есть изменения, записываем в ПЗУ") + if (osMutexAcquire(env->access, 10000) == osOK) { + VarsTabDumpObserver_Dump(env); + env->dumpAfter = 0; + } + } +} + + + diff --git a/VarsTabDumpObserver.h b/VarsTabDumpObserver.h new file mode 100644 index 0000000..0d46258 --- /dev/null +++ b/VarsTabDumpObserver.h @@ -0,0 +1,55 @@ +// +// Created by xemon on 19.12.22. +// + +#ifndef UVEOS_ON_NATION_VarsTabDumpOBSERVER_H +#define UVEOS_ON_NATION_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_Flush(tVarsTabDumpObserver *env); + +#endif //UVEOS_ON_NATION_VarsTabDumpOBSERVER_H diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..163f691 --- /dev/null +++ b/modular.json @@ -0,0 +1,22 @@ +{ + "dep": [ + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "VariablesTable" + }, + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "StorageInterface" + } + ], + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "./**.c" + ] + } +} \ No newline at end of file