Added max_points in .ini, increased spiff csv file character limit, and file name limit. Added more prints for how many devices you can configure based on current memory size and max_points.

This commit is contained in:
2026-06-23 15:39:28 -05:00
parent fcd2a46c93
commit df0f1aa2aa
7 changed files with 349 additions and 127 deletions

View File

@@ -49,7 +49,7 @@ typedef struct
{
uint8_t unit_id;
char name[DEVICE_NAME_MAX_LEN];
char csv_path[128];
char *csv_path;
modbus_db_t db;
modbus_memory_t mem;
@@ -91,6 +91,41 @@ static bool file_exists(const char *path)
return true;
}
static char *build_spiffs_path(const char *filename)
{
const char *prefix = "/spiffs/";
char *path;
size_t prefix_len;
size_t filename_len;
if (filename == NULL || filename[0] == '\0')
return NULL;
if (filename[0] == '/')
{
filename_len = strlen(filename);
path = heap_caps_malloc(filename_len + 1U, MALLOC_CAP_8BIT);
if (path == NULL)
return NULL;
memcpy(path, filename, filename_len + 1U);
return path;
}
prefix_len = strlen(prefix);
filename_len = strlen(filename);
path = heap_caps_malloc(prefix_len + filename_len + 1U, MALLOC_CAP_8BIT);
if (path == NULL)
return NULL;
memcpy(path, prefix, prefix_len);
memcpy(path + prefix_len, filename, filename_len + 1U);
return path;
}
static void spiffs_list_files(void)
{
DIR *dir;
@@ -847,6 +882,7 @@ void app_main(void)
ESP_LOGI(TAG, "Modbus Port: %u", (unsigned)g_device_cfg.modbus.port);
ESP_LOGI(TAG, "Configured device_count = %u", (unsigned)g_device_cfg.modbus.device_count);
ESP_LOGI(TAG, "Configured max_points per device = %u", (unsigned)g_device_cfg.modbus.max_points);
for (i = 0; i < g_device_cfg.modbus.device_count; i++)
{
@@ -856,7 +892,7 @@ void app_main(void)
g_device_cfg.devices[i].enabled ? 1 : 0,
(unsigned)g_device_cfg.devices[i].unit_id,
g_device_cfg.devices[i].name,
g_device_cfg.devices[i].csv);
(g_device_cfg.devices[i].csv != NULL) ? g_device_cfg.devices[i].csv : "");
}
if (g_device_cfg.modbus.device_count == 0U)
@@ -932,10 +968,14 @@ void app_main(void)
strncpy(dev->name, cfg_dev->name, sizeof(dev->name) - 1U);
dev->name[sizeof(dev->name) - 1U] = '\0';
snprintf(dev->csv_path,
sizeof(dev->csv_path),
"/spiffs/%s",
cfg_dev->csv);
dev->csv_path = build_spiffs_path(cfg_dev->csv);
if (dev->csv_path == NULL)
{
ESP_LOGE(TAG, "Failed to allocate CSV path for device %u",
(unsigned)dev->unit_id);
heap_caps_free(dev);
continue;
}
ESP_LOGI(TAG,
"Preparing device[%u]: unit_id=%u name=%s csv=%s",
@@ -949,6 +989,8 @@ void app_main(void)
ESP_LOGE(TAG, "CSV file not found for device %u: %s",
(unsigned)dev->unit_id,
dev->csv_path);
if(dev->csv_path != NULL)
heap_caps_free(dev->csv_path);
heap_caps_free(dev);
continue;
}
@@ -959,42 +1001,36 @@ void app_main(void)
modbus_points_init(&dev->db);
if (!modbus_points_load(&dev->db, dev->csv_path))
if (!modbus_points_load(&dev->db, dev->csv_path, g_device_cfg.modbus.max_points))
{
ESP_LOGE(TAG, "Failed to load CSV for device %u: %s",
(unsigned)dev->unit_id,
dev->csv_path);
if(dev->csv_path != NULL)
heap_caps_free(dev->csv_path);
heap_caps_free(dev);
continue;
}
/* Safety check: prevent memory overflow */
if (dev->db.count > MODBUS_MAX_POINTS)
{
ESP_LOGE(TAG,
"Device %u exceeded MODBUS_MAX_POINTS (%u > %u)",
(unsigned)dev->unit_id,
(unsigned)dev->db.count,
(unsigned)MODBUS_MAX_POINTS);
ESP_LOGE(TAG, "Startup aborted to prevent memory corruption.");
heap_caps_free(dev);
abort();
}
if (!modbus_memory_init(&dev->mem, &dev->db))
{
ESP_LOGE(TAG, "Memory init failed for device %u",
(unsigned)dev->unit_id);
modbus_points_reset(&dev->db);
if(dev->csv_path != NULL)
heap_caps_free(dev->csv_path);
heap_caps_free(dev);
continue;
}
ESP_LOGI(TAG, "Device %u (%s) loaded %u Modbus points from %s",
ESP_LOGI(TAG, "Device %u (%s) loaded %u / %u Modbus point entries from %s",
(unsigned)dev->unit_id,
dev->name,
(unsigned)dev->db.count,
(unsigned)dev->db.capacity,
dev->csv_path);
g_devices[g_device_count] = dev;
@@ -1020,17 +1056,23 @@ void app_main(void)
{
size_t total_points_used = 0;
size_t total_points_capacity = g_device_count * MODBUS_MAX_POINTS;
size_t total_points_capacity = 0;
size_t total_points_remaining = 0;
size_t free_heap = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t largest_block = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
size_t point_struct_size = sizeof(modbus_point_t);
size_t heap_equivalent_points = 0;
size_t configured_points_per_device = g_device_cfg.modbus.max_points;
size_t configured_db_bytes_per_device = configured_points_per_device * point_struct_size;
size_t estimated_additional_devices_free_heap = 0;
size_t estimated_additional_devices_largest_block = 0;
if (point_struct_size > 0U)
heap_equivalent_points = free_heap / point_struct_size;
if (configured_db_bytes_per_device > 0U)
{
estimated_additional_devices_free_heap = free_heap / configured_db_bytes_per_device;
estimated_additional_devices_largest_block = largest_block / configured_db_bytes_per_device;
}
for (i = 0; i < g_device_count; i++)
{
@@ -1038,46 +1080,56 @@ void app_main(void)
size_t remaining = 0;
float pct = 0.0f;
if (dev->db.count < MODBUS_MAX_POINTS)
remaining = MODBUS_MAX_POINTS - dev->db.count;
if (dev == NULL)
continue;
if (MODBUS_MAX_POINTS > 0U)
pct = (100.0f * (float)dev->db.count) / (float)MODBUS_MAX_POINTS;
if (dev->db.count < dev->db.capacity)
remaining = dev->db.capacity - dev->db.count;
if (dev->db.capacity > 0U)
pct = (100.0f * (float)dev->db.count) / (float)dev->db.capacity;
ESP_LOGI(TAG,
"Device %u (%s): used=%u / max=%u, remaining=%u (%.1f%% used)",
(unsigned)dev->unit_id,
dev->name,
(unsigned)dev->db.count,
(unsigned)MODBUS_MAX_POINTS,
(unsigned)remaining,
pct);
"Device %u (%s): used=%u / max=%u, remaining=%u (%.1f%% used)",
(unsigned)dev->unit_id,
dev->name,
(unsigned)dev->db.count,
(unsigned)dev->db.capacity,
(unsigned)remaining,
pct);
total_points_used += dev->db.count;
total_points_capacity += dev->db.capacity;
total_points_remaining += remaining;
}
ESP_LOGI(TAG,
"Configured capacity: used=%u / max=%u, remaining=%u",
(unsigned)total_points_used,
(unsigned)total_points_capacity,
(unsigned)total_points_remaining);
"Configured point capacity: used=%u / max=%u, remaining=%u",
(unsigned)total_points_used,
(unsigned)total_points_capacity,
(unsigned)total_points_remaining);
ESP_LOGI(TAG,
"Free heap: %u bytes, largest block: %u bytes, point size: %u bytes",
(unsigned)free_heap,
(unsigned)largest_block,
(unsigned)point_struct_size);
"Configured max_points per device=%u, point size=%u bytes, DB bytes per device=%u",
(unsigned)configured_points_per_device,
(unsigned)point_struct_size,
(unsigned)configured_db_bytes_per_device);
ESP_LOGI(TAG,
"Heap-equivalent points available (informational only): %u",
(unsigned)heap_equivalent_points);
"Free heap=%u bytes, largest block=%u bytes",
(unsigned)free_heap,
(unsigned)largest_block);
ESP_LOGI(TAG,
"Estimated additional devices possible with current max_points: free_heap=%u, largest_block=%u",
(unsigned)estimated_additional_devices_free_heap,
(unsigned)estimated_additional_devices_largest_block);
}
ESP_LOGI(TAG, "---------------------------------");
ESP_LOGI(TAG, "----- Point Cost Guide -----");
ESP_LOGI(TAG, "Internal point usage (counts against MODBUS_MAX_POINTS):");
ESP_LOGI(TAG, "Internal point usage (counts against configured max_points):");
ESP_LOGI(TAG, " data_type=bool -> 1 point");
ESP_LOGI(TAG, " data_type=uint16 -> 1 point");
ESP_LOGI(TAG, " data_type=uint32 -> 2 points");
@@ -1107,30 +1159,39 @@ void app_main(void)
ESP_LOGI(TAG, "----- Modbus Memory Usage -----");
size_t total_points = 0;
for (size_t d = 0; d < g_device_count; d++)
{
const modbus_device_t *dev = g_devices[d];
size_t total_points = 0;
size_t total_capacity = 0;
if (dev == NULL)
continue;
for (size_t d = 0; d < g_device_count; d++)
{
const modbus_device_t *dev = g_devices[d];
float pct = 0.0f;
if (dev == NULL)
continue;
if (dev->db.capacity > 0U)
pct = (100.0f * (float)dev->db.count) / (float)dev->db.capacity;
ESP_LOGI(TAG,
"Device %u (%s): %u / %u points used (%.1f%%)",
(unsigned)dev->unit_id,
dev->name,
(unsigned)dev->db.count,
(unsigned)dev->db.capacity,
pct);
total_points += dev->db.count;
total_capacity += dev->db.capacity;
}
ESP_LOGI(TAG,
"Device %u (%s): %u / %u points used (%.1f%%)",
(unsigned)dev->unit_id,
dev->name,
(unsigned)dev->db.count,
(unsigned)MODBUS_MAX_POINTS,
(100.0f * (float)dev->db.count) / (float)MODBUS_MAX_POINTS);
total_points += dev->db.count;
"TOTAL POINTS LOADED: %u / %u",
(unsigned)total_points,
(unsigned)total_capacity);
}
ESP_LOGI(TAG,
"TOTAL POINTS LOADED: %u",
(unsigned)total_points);
ESP_LOGI(TAG, "--------------------------------");
if (g_device_count == 0U)