VariablesTable/VariablesTable.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;
}