Начало

This commit is contained in:
cfif 2025-09-23 17:12:43 +03:00
commit 6b67decb18
3 changed files with 370 additions and 0 deletions

227
VariablesTable.c Normal file
View File

@ -0,0 +1,227 @@
//
// 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;
}

131
VariablesTable.h Normal file
View File

@ -0,0 +1,131 @@
//
// Created by zemon on 02.06.2022.
//
#ifndef TERMINAL_MOTO_0_0_1_PUBLICVARIABLESTABLE_H
#define TERMINAL_MOTO_0_0_1_PUBLICVARIABLESTABLE_H
#include "stdint.h"
#include <stdbool.h>
#include <cmsis_os.h>
typedef enum {
VARIABLE_TYPE_UINT8 = 0x01,
VARIABLE_TYPE_UINT16 = 0x02,
VARIABLE_TYPE_STRING = 0x03,
VARIABLE_TYPE_BOOL = 0x04,
VARIABLE_TYPE_FLOAT32 = 0x05,
VARIABLE_TYPE_INT32 = 0x06,
VARIABLE_TYPE_UINT32 = 0x07,
VARIABLE_TYPE_INT16 = 0x08,
VARIABLE_TYPE_INT64 = 0x09,
VARIABLE_TYPE_ARR_U8_STATIC = 0x0,
} eVariableTypeId;
extern uint8_t variablesTypeLength[];
#define VARIABLE_NAME_LENGTH 64
typedef struct {
char *str;
uint8_t length;
} tVariableName;
#define VARIABLE_NAME(STR) {.str=(STR), .length=sizeof(STR)-1}
typedef struct {
tVariableName name;
eVariableTypeId typeId;
void *addr;
void *len;
#ifdef VARIABLE_TABLE_WITH_ID
uint16_t id;
uint16_t idUDS;
uint8_t lenUds;
uint8_t limit;
uint32_t begin;
uint32_t end;
#endif
uint16_t *writeAttempts;
uint32_t groupMask;//это маска группы изменений (см tVariablesTable)
} tVariableDescriptor;
typedef struct {
tVariableDescriptor *items;
uint16_t limit;
uint16_t count;
//все изменени разбиты на группы
//всего возможно 32 группы соответственно
//при изменении переменной поднимаеться бит соответствующей группы
//и изменение можно обработать
uint32_t changes;
osMutexId_t writeAccess;
} tVariablesTable;
void VariablesTableInit(tVariablesTable *env, tVariableDescriptor *memAlloc, uint16_t memAllocLimit);
#define VariablesTableInitStatic(ENV, MEM) VariablesTableInit(ENV,MEM, sizeof(MEM)/sizeof(tVariableDescriptor))
bool VariablesTableAdd(
tVariablesTable *env,
char *nameStatic,
uint8_t nameLength,
eVariableTypeId type,
void *addr,
void *len,
uint16_t *writeAttempts,
uint32_t groupMask
);
#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
);
#endif
tVariableDescriptor *VariablesTable_GetLast(tVariablesTable *env);
tVariableDescriptor *VariablesTable_GetByName(tVariablesTable *env, char *name, uint8_t nameLen);
#define VariablesTable_GetByNameStatic(ENV, NAME) VariablesTable_GetByName(ENV, NAME, sizeof(NAME)-1)
uint8_t VariablesTable_GetVarLength(tVariableDescriptor *descriptor);
uint8_t VariablesTable_GetVarTypeLength(tVariableDescriptor *var);
bool VariablesTable_IsVariableChangeAllowed(tVariableDescriptor *var);
void VariablesTable_VariableChanged(tVariablesTable *env, tVariableDescriptor *var);
bool VariablesTable_RequireChange(tVariablesTable *env, uint32_t timeout);
void VariablesTable_ReleaseChange(tVariablesTable *env);
bool VariablesTable_TakeChange(tVariablesTable *env, uint32_t groupMask);
#ifdef VARIABLE_TABLE_WITH_ID
bool VariablesTable_SetId_ByName(tVariablesTable *env, char *name, uint8_t nameLen, uint16_t id);
tVariableDescriptor *VariablesTable_GetById(tVariablesTable *env, uint16_t id);
bool VariablesTable_SetIdUDS_ByName(tVariablesTable *env, char *name, uint8_t nameLen, uint16_t id, uint16_t len);
#define VariablesTable_SetIdUDS_ByNameStatic(ENV, NAME, ID, LEN) VariablesTable_SetIdUDS_ByName(ENV, NAME, sizeof(NAME)-1, ID, LEN)
tVariableDescriptor *VariablesTable_GetByIdUDS(tVariablesTable *env, uint16_t id);
#endif
#endif //TERMINAL_MOTO_0_0_1_PUBLICVARIABLESTABLE_H

12
modular.json Normal file
View File

@ -0,0 +1,12 @@
{
"dep": [
],
"cmake": {
"inc_dirs": [
"./"
],
"srcs": [
"./**.c"
]
}
}