// // 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); } } }