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:
195
main/main.c
195
main/main.c
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user