This commit is contained in:
cfif 2025-06-02 13:26:41 +03:00
commit f5a5299519
3 changed files with 327 additions and 0 deletions

248
VarTabDumpObserver.c Normal file
View File

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

57
VarsTabDumpObserver.h Normal file
View File

@ -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

22
modular.json Normal file
View File

@ -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"
]
}
}