227 lines
5.3 KiB
C
227 lines
5.3 KiB
C
//
|
|
// Created by zemon on 03.06.2022.
|
|
|
|
#include <string.h>
|
|
#include <SystemDelayInterface.h>
|
|
#include "VariablesTable.h"
|
|
|
|
uint8_t variablesTypeLength[] = {
|
|
[VARIABLE_TYPE_UINT8] = 0x01,
|
|
[VARIABLE_TYPE_UINT16] = 0x02,
|
|
[VARIABLE_TYPE_STRING] = 0x00,
|
|
[VARIABLE_TYPE_BOOL] = 0x01,
|
|
[VARIABLE_TYPE_FLOAT32] = 0x04,
|
|
[VARIABLE_TYPE_INT32] = 0x04,
|
|
[VARIABLE_TYPE_UINT32] = 0x04,
|
|
[VARIABLE_TYPE_INT16] = 0x02,
|
|
[VARIABLE_TYPE_INT64] = 0x08,
|
|
[VARIABLE_TYPE_ARR_U8_STATIC] = 0x00
|
|
};
|
|
|
|
|
|
void VariablesTableInit(tVariablesTable *env, tVariableDescriptor *mem, uint16_t limit) {
|
|
env->items = mem;
|
|
env->limit = limit;
|
|
env->count = 0;
|
|
env->changes = 0;
|
|
env->writeAccess = osMutexNew(NULL);
|
|
}
|
|
|
|
bool VariablesTableAdd(
|
|
tVariablesTable *env,
|
|
char *nameStatic,
|
|
uint8_t nameLength,
|
|
eVariableTypeId type,
|
|
void *addr,
|
|
void *len,
|
|
uint16_t *writeAttempts,
|
|
uint32_t groupMask
|
|
) {
|
|
if (env->count >= env->limit) {
|
|
return false;
|
|
}
|
|
|
|
tVariableDescriptor *var = env->items + env->count;
|
|
|
|
var->name.str = nameStatic;
|
|
var->name.length = nameLength;
|
|
|
|
#ifdef VARIABLE_TABLE_WITH_ID
|
|
var->idUDS = 0;
|
|
var->lenUds = 0;
|
|
var->begin = 0;
|
|
var->end = 0;
|
|
var->id = 0;
|
|
var->limit = 0;
|
|
#endif
|
|
|
|
var->typeId = type;
|
|
var->addr = addr;
|
|
var->len = len;
|
|
var->writeAttempts = writeAttempts;
|
|
var->groupMask = groupMask;
|
|
|
|
++env->count;
|
|
return true;
|
|
}
|
|
|
|
#ifdef VARIABLE_TABLE_WITH_ID
|
|
|
|
bool VariablesTableWithIdAdd(
|
|
tVariablesTable *env,
|
|
char *nameStatic,
|
|
uint8_t nameLength,
|
|
eVariableTypeId type,
|
|
void *addr,
|
|
void *len,
|
|
uint16_t id,
|
|
uint8_t limit,
|
|
uint16_t *writeAttempts,
|
|
uint32_t groupMask
|
|
) {
|
|
if (env->count >= env->limit) {
|
|
return false;
|
|
}
|
|
|
|
tVariableDescriptor *var = env->items + env->count;
|
|
|
|
var->name.str = nameStatic;
|
|
var->name.length = nameLength;
|
|
|
|
var->id = id;
|
|
var->limit = limit;
|
|
|
|
var->typeId = type;
|
|
var->addr = addr;
|
|
var->len = len;
|
|
var->writeAttempts = writeAttempts;
|
|
var->groupMask = groupMask;
|
|
|
|
++env->count;
|
|
return true;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
tVariableDescriptor *VariablesTable_GetLast(tVariablesTable *env) {
|
|
return env->items + env->count - 1;
|
|
}
|
|
|
|
tVariableDescriptor *VariablesTable_GetByName(tVariablesTable *env, char *name, uint8_t nameLen) {
|
|
// Поиск текстового id в таблице
|
|
|
|
for (uint16_t id = 0; id < env->count; ++id) {
|
|
if (nameLen == env->items[id].name.length) {
|
|
if (strncmp(name, env->items[id].name.str, nameLen) == 0) {
|
|
return env->items + id;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef VARIABLE_TABLE_WITH_ID
|
|
|
|
bool VariablesTable_SetId_ByName(tVariablesTable *env, char *name, uint8_t nameLen, uint16_t id) {
|
|
|
|
tVariableDescriptor *desc = VariablesTable_GetByName(env, name, nameLen);
|
|
|
|
if (desc != NULL) {
|
|
desc->id = id;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
tVariableDescriptor *VariablesTable_GetById(tVariablesTable *env, uint16_t id) {
|
|
// Поиск по id в таблице
|
|
|
|
for (uint16_t i = 0; i < env->count; ++i) {
|
|
if (id == env->items[i].id) {
|
|
return env->items + i;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool VariablesTable_SetIdUDS_ByName(tVariablesTable *env, char *name, uint8_t nameLen, uint16_t id, uint16_t len) {
|
|
|
|
tVariableDescriptor *desc = VariablesTable_GetByName(env, name, nameLen);
|
|
|
|
if (desc != NULL) {
|
|
desc->idUDS = id;
|
|
desc->lenUds = len;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
tVariableDescriptor *VariablesTable_GetByIdUDS(tVariablesTable *env, uint16_t id) {
|
|
// Поиск по id в таблице
|
|
|
|
for (uint16_t i = 0; i < env->count; ++i) {
|
|
if (id == env->items[i].idUDS) {
|
|
return env->items + i;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#endif
|
|
|
|
uint8_t VariablesTable_GetVarLength(tVariableDescriptor *var) {
|
|
uint8_t len = variablesTypeLength[var->typeId];
|
|
|
|
if (!len) {
|
|
len = *(uint8_t *) var->len;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
|
|
uint8_t VariablesTable_GetVarTypeLength(tVariableDescriptor *var) {
|
|
return variablesTypeLength[var->typeId];
|
|
}
|
|
|
|
|
|
//todo нужно сделать доступ к записи значений потокозащищенным
|
|
bool VariablesTable_RequireChange(tVariablesTable *env, uint32_t timeout) {
|
|
return osMutexAcquire(env->writeAccess, SystemMsToTicks(timeout)) == osOK;
|
|
}
|
|
|
|
bool VariablesTable_IsVariableChangeAllowed(tVariableDescriptor *var) {
|
|
return var->writeAttempts ? *var->writeAttempts : true;
|
|
}
|
|
|
|
|
|
void VariablesTable_VariableChanged(tVariablesTable *env, tVariableDescriptor *var) {
|
|
if (var->writeAttempts) {
|
|
--(*var->writeAttempts);
|
|
}
|
|
env->changes |= var->groupMask;
|
|
}
|
|
|
|
void VariablesTable_ReleaseChange(tVariablesTable *env) {
|
|
osMutexRelease(env->writeAccess);
|
|
}
|
|
|
|
bool VariablesTable_TakeChange(tVariablesTable *env, uint32_t groupMask) {
|
|
if (env->changes) {
|
|
if (VariablesTable_RequireChange(env, 0)) {
|
|
if (env->changes & groupMask) {
|
|
env->changes &= ~groupMask;
|
|
VariablesTable_ReleaseChange(env);
|
|
return true;
|
|
}
|
|
VariablesTable_ReleaseChange(env);
|
|
}
|
|
}
|
|
return false;
|
|
} |