165 lines
5.1 KiB
C
165 lines
5.1 KiB
C
//
|
||
// 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);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|