Init
This commit is contained in:
commit
f5a5299519
|
|
@ -0,0 +1,248 @@
|
|||
//
|
||||
// Created by xemon on 19.12.22.
|
||||
//
|
||||
|
||||
#include <CmsisRtosThreadUtils.h>
|
||||
#include "VarsTabDumpObserver.h"
|
||||
#include "SystemDelayInterface.h"
|
||||
#include "string.h"
|
||||
|
||||
#ifdef STORAGE_ARTERY_CHECK_CLEAR
|
||||
|
||||
#include "StorageOnFlashArtery.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#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, "Попытка записи в ПЗУ...")
|
||||
|
||||
|
||||
#ifdef STORAGE_ARTERY_CHECK_CLEAR
|
||||
tStorageOnFlashArtery *storageOnFlashArteryCheckClear = env->interface->env;
|
||||
|
||||
int isMainFlashPageAddressCheckClear = memcmp((uint8_t *) storageOnFlashArteryCheckClear->mainFlashPageAddress,
|
||||
env->data, env->size);
|
||||
int isRecoveryFlashPageAddressCheckClear = memcmp(
|
||||
(uint8_t *) storageOnFlashArteryCheckClear->recoveryFlashPageAddress, env->data, env->size);
|
||||
|
||||
if ((isMainFlashPageAddressCheckClear == 0) && (isRecoveryFlashPageAddressCheckClear == 0)) {
|
||||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Запись в ПЗУ не требуется (1)")
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (env->logger) {
|
||||
env->logger->logging(
|
||||
env->logger->env, "Хран.Наб.",
|
||||
sizeof("Хран.Наб.") - 1,
|
||||
LOGLEVEL_INFO,
|
||||
"Запись в ПЗУ...",
|
||||
sizeof("Запись в ПЗУ...") - 1, true
|
||||
);
|
||||
}
|
||||
|
||||
if (osMutexAcquire(env->accessDumper, 100) == osOK) {
|
||||
|
||||
#ifdef STORAGE_ARTERY_CHECK_WRITE_SECTORS
|
||||
tStorageOnFlashArtery *storageOnFlashArteryCheckWriteSectors = env->interface->env;
|
||||
|
||||
uint8_t maxCountWriteSectors = 0;
|
||||
|
||||
uint8_t countSectorsFullSize = env->size / FLASH_PAGE_SIZE;
|
||||
uint16_t countSectorTailSize = env->size % FLASH_PAGE_SIZE;
|
||||
|
||||
for (uint8_t i = 0; i < countSectorsFullSize; ++i) {
|
||||
|
||||
int isMainFlashPageAddressCheckWriteSectors =
|
||||
memcmp((uint8_t *) (i * FLASH_PAGE_SIZE +
|
||||
storageOnFlashArteryCheckWriteSectors->mainFlashPageAddress),
|
||||
i * FLASH_PAGE_SIZE + env->data, FLASH_PAGE_SIZE);
|
||||
|
||||
int isRecoveryFlashPageAddressCheckWriteSectors =
|
||||
memcmp((uint8_t *) (i * FLASH_PAGE_SIZE +
|
||||
storageOnFlashArteryCheckWriteSectors->recoveryFlashPageAddress),
|
||||
i * FLASH_PAGE_SIZE + env->data, FLASH_PAGE_SIZE);
|
||||
|
||||
if ((isMainFlashPageAddressCheckWriteSectors != 0) || (isRecoveryFlashPageAddressCheckWriteSectors != 0)) {
|
||||
maxCountWriteSectors = i;
|
||||
LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Сектор %d, требуется запись в ПЗУ", maxCountWriteSectors)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (countSectorTailSize > 0) {
|
||||
|
||||
int isMainFlashPageAddressCheckWriteSectors =
|
||||
memcmp((uint8_t *) (countSectorsFullSize * FLASH_PAGE_SIZE +
|
||||
storageOnFlashArteryCheckWriteSectors->mainFlashPageAddress),
|
||||
countSectorsFullSize * FLASH_PAGE_SIZE + env->data, countSectorTailSize);
|
||||
|
||||
int isRecoveryFlashPageAddressCheckWriteSectors =
|
||||
memcmp((uint8_t *) (countSectorsFullSize * FLASH_PAGE_SIZE +
|
||||
storageOnFlashArteryCheckWriteSectors->recoveryFlashPageAddress),
|
||||
countSectorsFullSize * FLASH_PAGE_SIZE + env->data, countSectorTailSize);
|
||||
|
||||
if ((isMainFlashPageAddressCheckWriteSectors != 0) || (isRecoveryFlashPageAddressCheckWriteSectors != 0)) {
|
||||
maxCountWriteSectors = countSectorsFullSize + 1;
|
||||
LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Сектор %d, требуется запись в ПЗУ", maxCountWriteSectors)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (maxCountWriteSectors == 0) {
|
||||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Запись в ПЗУ не требуется (2)")
|
||||
osMutexRelease(env->accessDumper);
|
||||
return true;
|
||||
}
|
||||
|
||||
eStorageStatus result;
|
||||
|
||||
if (maxCountWriteSectors > countSectorsFullSize) {
|
||||
result = StorageDump(env->interface, env->data, env->size);
|
||||
} else {
|
||||
result = StorageDump(env->interface, env->data, maxCountWriteSectors * FLASH_PAGE_SIZE);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef STORAGE_ARTERY_CHECK_WRITE_SECTORS
|
||||
eStorageStatus result = StorageDump(env->interface, env->data, env->size);
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// Created by xemon on 19.12.22.
|
||||
//
|
||||
|
||||
#ifndef UVEOS_ON_NATION_VarsTabDumpOBSERVER_H
|
||||
#define UVEOS_ON_NATION_VarsTabDumpOBSERVER_H
|
||||
|
||||
#include <StorageIO.h>
|
||||
#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_StopThread(tVarsTabDumpObserver *env);
|
||||
|
||||
void VarsTabDumpObserver_Flush(tVarsTabDumpObserver *env);
|
||||
|
||||
#endif //UVEOS_ON_NATION_VarsTabDumpOBSERVER_H
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"dep": [
|
||||
{
|
||||
"type": "git",
|
||||
"provider": "Smart_Components_Aurus",
|
||||
"repo": "VariablesTable"
|
||||
},
|
||||
{
|
||||
"type": "git",
|
||||
"provider": "Smart_Components_Aurus",
|
||||
"repo": "StorageInterface"
|
||||
}
|
||||
],
|
||||
"cmake": {
|
||||
"inc_dirs": [
|
||||
"./"
|
||||
],
|
||||
"srcs": [
|
||||
"./**.c"
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue