// // Created by cfif 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 *storageCalibInterface, tStorageInterface *storageParamInterface, uint32_t delay, void *dataCalib, void *dataParam, size_t sizeCalib, size_t sizeParam, uint8_t *trackableVarsTab, uint32_t trackableGroup, tLoggerInterface *logger ) { env->logger = logger; env->interfaceCalib = storageCalibInterface; env->interfaceParam = storageParamInterface; env->trackableVarsTab = trackableVarsTab; env->trackableGroup = trackableGroup; env->dataCalib = dataCalib; env->sizeCalib = sizeCalib; env->dataParam = dataParam; env->sizeParam = sizeParam; 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 VarsTabDumpObserverCalib_Load(tVarsTabDumpObserver *env) { if (osMutexAcquire(env->accessDumper, 100) == osOK) { eStorageStatus dumpStatus = StorageLoad(env->interfaceCalib, env->dataCalib, env->sizeCalib); 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 VarsTabDumpObserverParam_Load(tVarsTabDumpObserver *env) { if (osMutexAcquire(env->accessDumper, 100) == osOK) { eStorageStatus dumpStatus = StorageLoad(env->interfaceParam, env->dataParam, env->sizeParam); 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 VarsTabDumpObserverCalib_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->interfaceCalib, env->dataCalib, env->sizeCalib); 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; } } bool VarsTabDumpObserverParam_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->interfaceParam, env->dataParam, env->sizeParam); 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 (env->trackableVarsTab) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружены изменения в параметрах, необходима запись в ПЗУ") VarsTabDumpObserver_RequireDump(env); } if (env->dumpAfter && VarsTabDumpObserver_IsNowDumpRequired(env)) { if (osMutexAcquire(env->access, 1) == osOK) { if (VarsTabDumpObserver_IsNowDumpRequired(env)) { VarsTabDumpObserverParam_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) { VarsTabDumpObserverParam_Dump(env); env->dumpAfter = 0; osMutexRelease(env->access); } } }