Modbus RTU v1
This commit is contained in:
@@ -105,6 +105,27 @@ static bool parse_i32(const char *s, int *out)
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CONFIG_SPIFFS_BASE_PATH "/spiffs"
|
||||
|
||||
static void copy_csv_path(char *dst, size_t dst_size, const char *src)
|
||||
{
|
||||
if (dst == NULL || dst_size == 0U)
|
||||
return;
|
||||
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
|
||||
if (src[0] == '/')
|
||||
{
|
||||
copy_str(dst, dst_size, src);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(dst, dst_size, CONFIG_SPIFFS_BASE_PATH "/%s", src);
|
||||
dst[dst_size - 1U] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_str(char *dst, size_t dst_size, const char *src)
|
||||
{
|
||||
if (dst == NULL || dst_size == 0U)
|
||||
@@ -355,7 +376,7 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
}
|
||||
else if (str_ieq(key, "csv"))
|
||||
{
|
||||
copy_str(dev->csv, sizeof(dev->csv), value);
|
||||
copy_csv_path(dev->csv, sizeof(dev->csv), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#define DEVICE_NAME_MAX_LEN 32
|
||||
#define DEVICE_CSV_MAX_LEN 64
|
||||
#define MAX_VIRTUAL_DEVICES 3
|
||||
#define DEVICE_CSV_MAX_LEN 96
|
||||
#define MAX_VIRTUAL_DEVICES 10 /* This the max devices it will simualte, adjust if you need more than 10, do recall this will take up memory */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
||||
@@ -240,22 +240,6 @@ static uint8_t data_type_reg_span(modbus_data_type_t data_type)
|
||||
}
|
||||
}
|
||||
|
||||
static bool db_has_duplicate_name(const modbus_db_t *db, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (db == NULL || name == NULL)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < db->count; i++)
|
||||
{
|
||||
if (strcmp(db->points[i].name, name) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool db_has_duplicate_type_offset(const modbus_db_t *db,
|
||||
modbus_point_type_t type,
|
||||
uint16_t offset)
|
||||
@@ -428,18 +412,9 @@ static bool append_helper_points(modbus_db_t *db, const modbus_point_t *base_pt)
|
||||
helper.bit_value = 0U;
|
||||
helper.reg_value = 0U;
|
||||
|
||||
snprintf(helper.name,
|
||||
sizeof(helper.name),
|
||||
"%.25s__w%u",
|
||||
base_pt->name,
|
||||
(unsigned)(i + 1U));
|
||||
|
||||
if (db->count >= MODBUS_MAX_POINTS)
|
||||
return false;
|
||||
|
||||
if (db_has_duplicate_name(db, helper.name))
|
||||
return false;
|
||||
|
||||
if (db_has_duplicate_type_offset(db, helper.type, helper.offset))
|
||||
return false;
|
||||
|
||||
@@ -498,12 +473,6 @@ static bool parse_csv_line(const char *line_in, modbus_point_t *pt)
|
||||
if (!normalize_address(pt->type, pt->raw_address, &pt->offset))
|
||||
return false;
|
||||
|
||||
if (fields[2][0] == '\0')
|
||||
return false;
|
||||
|
||||
strncpy(pt->name, fields[2], sizeof(pt->name) - 1U);
|
||||
pt->name[sizeof(pt->name) - 1U] = '\0';
|
||||
|
||||
pt->data_type = parse_data_type(fields[3]);
|
||||
if (pt->data_type == MB_DATA_INVALID)
|
||||
return false;
|
||||
@@ -624,9 +593,6 @@ static bool parse_csv_line(const char *line_in, modbus_point_t *pt)
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(pt->notes, fields[7], sizeof(pt->notes) - 1U);
|
||||
pt->notes[sizeof(pt->notes) - 1U] = '\0';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -767,20 +733,10 @@ bool modbus_points_load(modbus_db_t *db, const char *filename)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (db_has_duplicate_name(db, pt.name))
|
||||
{
|
||||
printf("CSV ERROR line %u: duplicate name '%s'\n",
|
||||
(unsigned)line_num,
|
||||
pt.name);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (db_has_duplicate_type_offset(db, pt.type, pt.offset))
|
||||
{
|
||||
printf("CSV ERROR line %u: duplicate Modbus address for name '%s' raw=%lu offset=%u\n",
|
||||
printf("CSV ERROR line %u: duplicate Modbus address raw=%lu offset=%u\n",
|
||||
(unsigned)line_num,
|
||||
pt.name,
|
||||
(unsigned long)pt.raw_address,
|
||||
(unsigned)pt.offset);
|
||||
fclose(fp);
|
||||
@@ -793,9 +749,8 @@ bool modbus_points_load(modbus_db_t *db, const char *filename)
|
||||
pt.pics_offset,
|
||||
pt.pics_reg_span))
|
||||
{
|
||||
printf("CSV ERROR line %u: overlapping PICS range for name '%s' pics_raw=%lu pics_offset=%u span=%u\n",
|
||||
printf("CSV ERROR line %u: overlapping PICS range pics_raw=%lu pics_offset=%u span=%u\n",
|
||||
(unsigned)line_num,
|
||||
pt.name,
|
||||
(unsigned long)pt.pics_raw_address,
|
||||
(unsigned)pt.pics_offset,
|
||||
(unsigned)pt.pics_reg_span);
|
||||
@@ -807,9 +762,8 @@ bool modbus_points_load(modbus_db_t *db, const char *filename)
|
||||
|
||||
if (!append_helper_points(db, &pt))
|
||||
{
|
||||
printf("CSV ERROR line %u: failed to append helper points for '%s'\n",
|
||||
(unsigned)line_num,
|
||||
pt.name);
|
||||
printf("CSV ERROR line %u: failed to append helper points\n",
|
||||
(unsigned)line_num);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
@@ -819,22 +773,6 @@ bool modbus_points_load(modbus_db_t *db, const char *filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
const modbus_point_t *modbus_points_find_by_name(const modbus_db_t *db, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (db == NULL || name == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < db->count; i++)
|
||||
{
|
||||
if (strcmp(db->points[i].name, name) == 0)
|
||||
return &db->points[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const modbus_point_t *modbus_points_find_by_type_offset(const modbus_db_t *db,
|
||||
modbus_point_type_t type,
|
||||
uint16_t offset)
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
|
||||
#include "modbus_memory.h"
|
||||
|
||||
#define MODBUS_MAX_POINTS 384
|
||||
#define MODBUS_MAX_NAME_LEN 32
|
||||
#define MODBUS_MAX_NOTES_LEN 64
|
||||
#define MODBUS_MAX_POINTS 384 /* Max amount of registers you allocate per device, base this on the highest register count, also the more you reserve the more memory you need*/
|
||||
|
||||
#define MODBUS_MAX_CSV_LINE_LEN 256
|
||||
|
||||
typedef enum
|
||||
@@ -47,7 +46,6 @@ typedef struct modbus_point
|
||||
uint32_t raw_address;
|
||||
uint16_t offset;
|
||||
|
||||
char name[MODBUS_MAX_NAME_LEN];
|
||||
modbus_data_type_t data_type;
|
||||
|
||||
uint8_t reg_span;
|
||||
@@ -67,8 +65,6 @@ typedef struct modbus_point
|
||||
|
||||
uint16_t pics_words[4];
|
||||
|
||||
char notes[MODBUS_MAX_NOTES_LEN];
|
||||
|
||||
uint8_t bit_value;
|
||||
uint16_t reg_value;
|
||||
} modbus_point_t;
|
||||
@@ -88,9 +84,6 @@ void modbus_points_reset(modbus_db_t *db);
|
||||
bool modbus_points_load(modbus_db_t *db, const char *filename);
|
||||
|
||||
/* Lookup helpers */
|
||||
const modbus_point_t *modbus_points_find_by_name(const modbus_db_t *db,
|
||||
const char *name);
|
||||
|
||||
const modbus_point_t *modbus_points_find_by_type_offset(const modbus_db_t *db,
|
||||
modbus_point_type_t type,
|
||||
uint16_t offset);
|
||||
|
||||
Reference in New Issue
Block a user