VarTabDumpObserver/VarTabDumpObserver.c

165 lines
5.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by xemon on 19.12.22.
//
#include <CmsisRtosThreadUtils.h>
#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);
}
}
}