소스 검색

Merge branch 'bugfix/modbus_allow_address_gaps_in_master_data_dict_v44' into 'release/v4.4'

freemodbus: allow address gaps in master data dictionary (support of UID field in MBAP) (backport v4.4)

See merge request espressif/esp-idf!16896
Jiang Jiang Jian 3 년 전
부모
커밋
5ff09f0a06

+ 2 - 0
components/freemodbus/common/esp_modbus_master.c

@@ -18,6 +18,8 @@
 #include "esp_modbus_master.h"  // for public interface defines
 #include "esp_modbus_callbacks.h"   // for callback functions
 
+static const char TAG[] __attribute__((unused)) = "MB_CONTROLLER_MASTER";
+
 // This file implements public API for Modbus master controller.
 // These functions are wrappers for interface functions of the controller
 static mb_master_interface_t* master_interface_ptr = NULL;

+ 4 - 3
components/freemodbus/common/esp_modbus_slave.c

@@ -43,6 +43,7 @@ static uint8_t mb_slave_id[] = { MB_ID_BYTE0(MB_CONTROLLER_SLAVE_ID),
 
 // Common interface pointer for slave port
 static mb_slave_interface_t* slave_interface_ptr = NULL;
+static const char TAG[] __attribute__((unused)) = "MB_CONTROLLER_SLAVE";
 
 // Searches the register in the area specified by type, returns descriptor if found, else NULL
 static mb_descr_entry_t* mbc_slave_find_reg_descriptor(mb_param_type_t type, uint16_t addr, size_t regs)
@@ -259,11 +260,11 @@ static esp_err_t mbc_slave_send_param_info(mb_event_group_t par_type, uint16_t m
     par_info.mb_offset = mb_offset;
     BaseType_t status = xQueueSend(mbs_opts->mbs_notification_queue_handle, &par_info, MB_PAR_INFO_TOUT);
     if (pdTRUE == status) {
-        ESP_LOGD(MB_SLAVE_TAG, "Queue send parameter info (type, address, size): %d, 0x%.4x, %d",
+        ESP_LOGD(TAG, "Queue send parameter info (type, address, size): %d, 0x%.4x, %d",
                 par_type, (uint32_t)par_address, par_size);
         error = ESP_OK;
     } else if (errQUEUE_FULL == status) {
-        ESP_LOGD(MB_SLAVE_TAG, "Parameter queue is overflowed.");
+        ESP_LOGD(TAG, "Parameter queue is overflowed.");
     }
     return error;
 }
@@ -276,7 +277,7 @@ static esp_err_t mbc_slave_send_param_access_notification(mb_event_group_t event
     esp_err_t err = ESP_FAIL;
     mb_event_group_t bits = (mb_event_group_t)xEventGroupSetBits(mbs_opts->mbs_event_group, (EventBits_t)event);
     if (bits & event) {
-        ESP_LOGD(MB_SLAVE_TAG, "The MB_REG_CHANGE_EVENT = 0x%.2x is set.", (uint8_t)event);
+        ESP_LOGD(TAG, "The MB_REG_CHANGE_EVENT = 0x%.2x is set.", (uint8_t)event);
         err = ESP_OK;
     }
     return err;

+ 18 - 0
components/freemodbus/common/include/esp_modbus_common.h

@@ -22,6 +22,24 @@
 extern "C" {
 #endif
 
+#if __has_include("esp_check.h")
+#include "esp_check.h"
+
+#define MB_RETURN_ON_FALSE(a, err_code, tag, format, ...) ESP_RETURN_ON_FALSE(a, err_code, tag, format __VA_OPT__(,) __VA_ARGS__)
+
+#else
+
+// if cannot include esp_check then use custom check macro
+
+#define MB_RETURN_ON_FALSE(a, err_code, tag, format, ...) do {                                         \
+        if (!(a)) {                                                                              \
+            ESP_LOGE(tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__);        \
+            return err_code;                                                                               \
+        }                                                                                                  \
+} while(0)
+
+#endif
+
 #define MB_CONTROLLER_STACK_SIZE            (CONFIG_FMB_CONTROLLER_STACK_SIZE)   // Stack size for Modbus controller
 #define MB_CONTROLLER_PRIORITY              (CONFIG_FMB_PORT_TASK_PRIO - 1)    // priority of MB controller task
 

+ 6 - 0
components/freemodbus/common/include/esp_modbus_master.h

@@ -25,6 +25,12 @@
 extern "C" {
 #endif
 
+#define MB_MASTER_CHECK(a, err_code, format, ...) MB_RETURN_ON_FALSE(a, err_code, TAG, format __VA_OPT__(,) __VA_ARGS__)
+
+#define MB_MASTER_ASSERT(con) do { \
+        if (!(con)) { ESP_LOGE(TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \
+    } while (0)
+
 /*!
  * \brief Modbus descriptor table parameter type defines.
  */

+ 6 - 0
components/freemodbus/common/include/esp_modbus_slave.h

@@ -28,6 +28,12 @@
 extern "C" {
 #endif
 
+#define MB_SLAVE_CHECK(a, err_code, format, ...) MB_RETURN_ON_FALSE(a, err_code, TAG, format __VA_OPT__(,) __VA_ARGS__)
+
+#define MB_SLAVE_ASSERT(con) do { \
+        if (!(con)) { ESP_LOGE(TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \
+    } while (0)
+
 /**
  * @brief Parameter access event information type
  */

+ 19 - 12
components/freemodbus/common/mbc_master.h

@@ -12,9 +12,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #ifndef _MB_CONTROLLER_MASTER_H
 #define _MB_CONTROLLER_MASTER_H
 
+#include <sys/queue.h>              // for list
 #include "freertos/FreeRTOS.h"      // for task creation and queue access
 #include "freertos/task.h"          // for task api access
 #include "freertos/event_groups.h"  // for event groups
@@ -28,18 +30,6 @@
 
 /* ----------------------- Defines ------------------------------------------*/
 
-#define MB_MASTER_TAG "MB_CONTROLLER_MASTER"
-
-#define MB_MASTER_CHECK(a, ret_val, str, ...) \
-    if (!(a)) { \
-        ESP_LOGE(MB_MASTER_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
-        return (ret_val); \
-    }
-
-#define MB_MASTER_ASSERT(con) do { \
-        if (!(con)) { ESP_LOGE(MB_MASTER_TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \
-    } while (0)
-
 /**
  * @brief Request mode for parameter to use in data dictionary
  */
@@ -59,6 +49,19 @@ typedef struct {
     uart_parity_t parity;                   /*!< Modbus UART parity settings */
 } mb_master_comm_info_t;
 
+#if MB_MASTER_TCP_ENABLED
+/**
+ * @brief Modbus slave addr list item for the master
+ */
+typedef struct mb_slave_addr_entry_s{
+    uint16_t index;                             /*!< Index of the slave address */
+    const char* ip_address;                     /*!< IP address string of the slave */
+    uint8_t slave_addr;                         /*!< Short slave address */
+    void* p_data;                               /*!< pointer to data structure */
+    LIST_ENTRY(mb_slave_addr_entry_s) entries;  /*!< The slave address entry */
+} mb_slave_addr_entry_t;
+#endif
+
 /**
  * @brief Modbus controller handler structure
  */
@@ -71,6 +74,10 @@ typedef struct {
     EventGroupHandle_t mbm_event_group;                 /*!< Modbus controller event group */
     const mb_parameter_descriptor_t* mbm_param_descriptor_table; /*!< Modbus controller parameter description table */
     size_t mbm_param_descriptor_size;                   /*!< Modbus controller parameter description table size*/
+#if MB_MASTER_TCP_ENABLED
+    LIST_HEAD(mbm_slave_addr_info_, mb_slave_addr_entry_s) mbm_slave_list; /*!< Slave address information list */
+    uint16_t mbm_slave_list_count;
+#endif
 } mb_master_options_t;
 
 typedef esp_err_t (*iface_get_cid_info)(uint16_t, const mb_parameter_descriptor_t**); /*!< Interface get_cid_info method */

+ 0 - 12
components/freemodbus/common/mbc_slave.h

@@ -31,18 +31,6 @@
 #define MB_CONTROLLER_NOTIFY_QUEUE_SIZE     (CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE) // Number of messages in parameter notification queue
 #define MB_CONTROLLER_NOTIFY_TIMEOUT        (pdMS_TO_TICKS(CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT)) // notification timeout
 
-#define MB_SLAVE_TAG "MB_CONTROLLER_SLAVE"
-
-#define MB_SLAVE_CHECK(a, ret_val, str, ...) \
-    if (!(a)) { \
-        ESP_LOGE(MB_SLAVE_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
-        return (ret_val); \
-    }
-
-#define MB_SLAVE_ASSERT(con) do { \
-        if (!(con)) { ESP_LOGE(MB_SLAVE_TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \
-    } while (0)
-
 /**
  * @brief Device communication parameters for master
  */

+ 11 - 10
components/freemodbus/serial_master/modbus_controller/mbc_serial_master.c

@@ -40,6 +40,7 @@ extern BOOL xMBMasterPortSerialTxPoll(void);
 
 
 static mb_master_interface_t* mbm_interface_ptr = NULL; //&default_interface_inst;
+static const char *TAG = "MB_CONTROLLER_MASTER";
 
 // Modbus event processing task
 static void modbus_master_task(void *pvParameters)
@@ -238,7 +239,7 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi
                                                         (USHORT)mb_size, (LONG) MB_RESPONSE_TICS );
             break;
         default:
-            ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect function in request (%u) ",
+            ESP_LOGE(TAG, "%s: Incorrect function in request (%u) ",
                                                     __FUNCTION__, mb_command);
             mb_error = MB_MRE_NO_REG;
             break;
@@ -269,7 +270,7 @@ static esp_err_t mbc_serial_master_send_request(mb_param_request_t* request, voi
             break;
 
         default:
-            ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect return code (%x) ",
+            ESP_LOGE(TAG, "%s: Incorrect return code (%x) ",
                                                                 __FUNCTION__, mb_error);
             error = ESP_FAIL;
             break;
@@ -324,12 +325,12 @@ static uint8_t mbc_serial_master_get_command(mb_param_type_t param_type, mb_para
             if (mode != MB_PARAM_WRITE) {
                 command = MB_FUNC_READ_DISCRETE_INPUTS;
             } else {
-                ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect mode (%u)",
+                ESP_LOGE(TAG, "%s: Incorrect mode (%u)",
                             __FUNCTION__, (uint8_t)mode);
             }
             break;
         default:
-            ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect param type (%u)",
+            ESP_LOGE(TAG, "%s: Incorrect param type (%u)",
                             __FUNCTION__, param_type);
             break;
     }
@@ -401,16 +402,16 @@ static esp_err_t mbc_serial_master_get_parameter(uint16_t cid, char* name,
         // Send request to read characteristic data
         error = mbc_serial_master_send_request(&request, value_ptr);
         if (error == ESP_OK) {
-            ESP_LOGD(MB_MASTER_TAG, "%s: Good response for get cid(%u) = %s",
+            ESP_LOGD(TAG, "%s: Good response for get cid(%u) = %s",
                                     __FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error));
         } else {
-            ESP_LOGD(MB_MASTER_TAG, "%s: Bad response to get cid(%u) = %s",
+            ESP_LOGD(TAG, "%s: Bad response to get cid(%u) = %s",
                                             __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error));
         }
         // Set the type of parameter found in the table
         *type = reg_info.param_type;
     } else {
-        ESP_LOGE(MB_MASTER_TAG, "%s: The cid(%u) not found in the data dictionary.",
+        ESP_LOGE(TAG, "%s: The cid(%u) not found in the data dictionary.",
                                                     __FUNCTION__, reg_info.cid);
         error = ESP_ERR_INVALID_ARG;
     }
@@ -436,16 +437,16 @@ static esp_err_t mbc_serial_master_set_parameter(uint16_t cid, char* name,
         // Send request to write characteristic data
         error = mbc_serial_master_send_request(&request, value_ptr);
         if (error == ESP_OK) {
-            ESP_LOGD(MB_MASTER_TAG, "%s: Good response for set cid(%u) = %s",
+            ESP_LOGD(TAG, "%s: Good response for set cid(%u) = %s",
                                     __FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error));
         } else {
-            ESP_LOGD(MB_MASTER_TAG, "%s: Bad response to set cid(%u) = %s",
+            ESP_LOGD(TAG, "%s: Bad response to set cid(%u) = %s",
                                     __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error));
         }
         // Set the type of parameter found in the table
         *type = reg_info.param_type;
     } else {
-        ESP_LOGE(MB_MASTER_TAG, "%s: The requested cid(%u) not found in the data dictionary.",
+        ESP_LOGE(TAG, "%s: The requested cid(%u) not found in the data dictionary.",
                                     __FUNCTION__, reg_info.cid);
         error = ESP_ERR_INVALID_ARG;
     }

+ 1 - 0
components/freemodbus/serial_slave/modbus_controller/mbc_serial_slave.c

@@ -29,6 +29,7 @@
 
 // Shared pointer to interface structure
 static mb_slave_interface_t* mbs_interface_ptr = NULL;
+static const char *TAG = "MB_CONTROLLER_SLAVE";
 
 // Modbus task function
 static void modbus_slave_task(void *pvParameters)

+ 122 - 32
components/freemodbus/tcp_master/modbus_controller/mbc_tcp_master.c

@@ -19,6 +19,7 @@
 #include <sys/time.h>               // for calculation of time stamp in milliseconds
 #include "esp_log.h"                // for log_write
 #include <string.h>                 // for memcpy
+#include <sys/queue.h>              // for list
 #include "freertos/FreeRTOS.h"      // for task creation and queue access
 #include "freertos/task.h"          // for task api access
 #include "freertos/event_groups.h"  // for event groups
@@ -42,6 +43,59 @@
 #define MB_TCP_CONNECTION_TOUT pdMS_TO_TICKS(CONFIG_FMB_TCP_CONNECTION_TOUT_SEC * 1000)
 
 static mb_master_interface_t* mbm_interface_ptr = NULL;
+static const char *TAG = "MB_CONTROLLER_MASTER";
+
+// Searches the slave address in the address info list and returns address info if found, else NULL
+static mb_slave_addr_entry_t* mbc_tcp_master_find_slave_addr(uint8_t slave_addr)
+{
+    mb_slave_addr_entry_t* it;
+    mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts;
+
+    if (LIST_EMPTY(&mbm_opts->mbm_slave_list)) {
+        return NULL;
+    }
+    LIST_FOREACH(it, &mbm_opts->mbm_slave_list, entries) {
+        if (slave_addr == it->slave_addr) {
+            return it;
+        }
+    }
+    return NULL;
+}
+
+static esp_err_t mbc_tcp_master_add_slave(uint16_t index, uint8_t slave_addr, const char* ip_addr)
+{
+    MB_MASTER_ASSERT(mbm_interface_ptr != NULL);
+    // Initialize interface properties
+    mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts;
+
+    mb_slave_addr_entry_t* new_slave_entry = (mb_slave_addr_entry_t*) heap_caps_malloc(sizeof(mb_slave_addr_entry_t),
+                                               MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
+    MB_MASTER_CHECK((new_slave_entry != NULL), ESP_ERR_NO_MEM, "mb can not allocate memory for slave entry.");
+    new_slave_entry->index = index;
+    new_slave_entry->ip_address = ip_addr;
+    new_slave_entry->slave_addr = slave_addr;
+    new_slave_entry->p_data = NULL;
+    LIST_INSERT_HEAD(&mbm_opts->mbm_slave_list, new_slave_entry, entries);
+    MB_MASTER_CHECK((mbm_opts->mbm_slave_list_count < (MB_TCP_PORT_MAX_CONN - 1)),
+                        ESP_ERR_INVALID_STATE, "mb max number of slaves < %d.", MB_TCP_PORT_MAX_CONN);
+    mbm_opts->mbm_slave_list_count++;
+    return ESP_OK;
+}
+
+static void mbc_tcp_master_free_slave_list(void)
+{
+    mb_slave_addr_entry_t* it;
+    MB_MASTER_ASSERT(mbm_interface_ptr != NULL);
+
+    // Initialize interface properties
+    mb_master_options_t* mbm_opts = &mbm_interface_ptr->opts;
+
+    LIST_FOREACH(it, &mbm_opts->mbm_slave_list, entries) {
+        LIST_REMOVE(it, entries);
+        mbm_opts->mbm_slave_list_count--;
+        free(it);
+    }
+}
 
 // Modbus event processing task
 static void modbus_tcp_master_task(void *pvParameters)
@@ -113,21 +167,21 @@ static esp_err_t mbc_tcp_master_start(void)
     vMBTCPPortMasterSetNetOpt(comm_info->ip_netif_ptr, ip_ver, proto);
     vMBTCPPortMasterTaskStart();
 
-    // Add slave IP address for each slave to initialise connection
-    for (int idx = 0; *comm_ip_table != NULL; idx++, comm_ip_table++)
-    {
-        result = (BOOL)xMBTCPPortMasterAddSlaveIp(*comm_ip_table);
+    // Add slave IP address for each slave to initialize connection
+    mb_slave_addr_entry_t *p_slave_info;
+
+    LIST_FOREACH(p_slave_info, &mbm_opts->mbm_slave_list, entries) {
+        result = (BOOL)xMBTCPPortMasterAddSlaveIp(p_slave_info->index, p_slave_info->ip_address, p_slave_info->slave_addr);
         MB_MASTER_CHECK(result, ESP_ERR_INVALID_STATE, "mb stack add slave IP failed: %s.", *comm_ip_table);
     }
-    // Init polling event handlers and wait before start polling
-    xMBTCPPortMasterWaitEvent(mbm_opts->mbm_event_group, (EventBits_t)MB_EVENT_STACK_STARTED, 1);
+
+    // Add end of list condition
+    (void)xMBTCPPortMasterAddSlaveIp(0xFF, NULL, 0xFF);
 
     status = eMBMasterEnable();
     MB_MASTER_CHECK((status == MB_ENOERR), ESP_ERR_INVALID_STATE,
             "mb stack set slave ID failure, eMBMasterEnable() returned (0x%x).", (uint32_t)status);
 
-    // Send end of list condition to start connection phase
-    (void)xMBTCPPortMasterAddSlaveIp(NULL);
 
     // Wait for connection done event
     bool start = (bool)xMBTCPPortMasterWaitEvent(mbm_opts->mbm_event_group,
@@ -160,6 +214,7 @@ static esp_err_t mbc_tcp_master_destroy(void)
     mbm_opts->mbm_task_handle = NULL;
     (void)vEventGroupDelete(mbm_opts->mbm_event_group);
     mbm_opts->mbm_event_group = NULL;
+    mbc_tcp_master_free_slave_list();
     free(mbm_interface_ptr); // free the memory allocated for options
     vMBPortSetMode((UCHAR)MB_PORT_INACTIVE);
     mbm_interface_ptr = NULL;
@@ -179,14 +234,25 @@ static esp_err_t mbc_tcp_master_set_descriptor(const mb_parameter_descriptor_t*
     MB_MASTER_CHECK((comm_ip_table != NULL), ESP_ERR_INVALID_ARG, "mb ip table address is incorrect.");
 
     const mb_parameter_descriptor_t *reg_ptr = descriptor;
+    uint16_t slave_cnt = 0;
+    mb_slave_addr_entry_t* p_slave = NULL;
+
     // Go through all items in the table to check all Modbus registers
-    for (uint16_t counter = 0; counter < (num_elements); counter++, reg_ptr++)
+    for (int idx = 0; idx < (num_elements); idx++, reg_ptr++)
     {
-        MB_MASTER_CHECK((comm_ip_table[reg_ptr->mb_slave_addr - 1] != NULL), ESP_ERR_INVALID_ARG, "mb ip table address is incorrect.");
         // Below is the code to check consistency of the table format and required fields.
-        MB_MASTER_CHECK((reg_ptr->cid == counter), ESP_ERR_INVALID_ARG, "mb descriptor cid field is incorrect.");
+        MB_MASTER_CHECK((reg_ptr->cid == idx), ESP_ERR_INVALID_ARG, "mb descriptor cid field is incorrect.");
         MB_MASTER_CHECK((reg_ptr->param_key != NULL), ESP_ERR_INVALID_ARG, "mb descriptor param key is incorrect.");
         MB_MASTER_CHECK((reg_ptr->mb_size > 0), ESP_ERR_INVALID_ARG, "mb descriptor param size is incorrect.");
+        // Is the slave already in the list?
+        p_slave = mbc_tcp_master_find_slave_addr(reg_ptr->mb_slave_addr);
+        // Add it to slave list if not there.
+        if (!p_slave) {
+            // Is the IP address correctly defined for the slave?
+            MB_MASTER_CHECK((comm_ip_table[slave_cnt]), ESP_ERR_INVALID_STATE, "mb missing IP address for cid #%d.", reg_ptr->cid);
+            // Add slave to the list
+            MB_MASTER_ASSERT(mbc_tcp_master_add_slave(idx, reg_ptr->mb_slave_addr, comm_ip_table[slave_cnt++]) == ESP_OK);
+        }
     }
     mbm_opts->mbm_param_descriptor_table = descriptor;
     mbm_opts->mbm_param_descriptor_size = num_elements;
@@ -258,7 +324,7 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void*
                                                         (USHORT)mb_size, (LONG) MB_RESPONSE_TIMEOUT );
             break;
         default:
-            ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect function in request (%u) ",
+            ESP_LOGE(TAG, "%s: Incorrect function in request (%u) ",
                                                     __FUNCTION__, mb_command);
             mb_error = MB_MRE_NO_REG;
             break;
@@ -289,7 +355,7 @@ static esp_err_t mbc_tcp_master_send_request(mb_param_request_t* request, void*
             break;
 
         default:
-            ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect return code (%x) ", __FUNCTION__, mb_error);
+            ESP_LOGE(TAG, "%s: Incorrect return code (%x) ", __FUNCTION__, mb_error);
             error = ESP_FAIL;
             break;
     }
@@ -333,11 +399,11 @@ static uint8_t mbc_tcp_master_get_command(mb_param_type_t param_type, mb_param_m
             if (mode != MB_PARAM_WRITE) {
                 command = MB_FUNC_READ_DISCRETE_INPUTS;
             } else {
-                ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect mode (%u)", __FUNCTION__, (uint8_t)mode);
+                ESP_LOGE(TAG, "%s: Incorrect mode (%u)", __FUNCTION__, (uint8_t)mode);
             }
             break;
         default:
-            ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect param type (%u)", __FUNCTION__, param_type);
+            ESP_LOGE(TAG, "%s: Incorrect param type (%u)", __FUNCTION__, param_type);
             break;
     }
     return command;
@@ -368,7 +434,7 @@ static esp_err_t mbc_tcp_master_set_param_data(void* dest, void* src, mb_descr_t
             memcpy((void*)dest, (void*)src, (size_t)param_size);
             break;
         default:
-            ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect param type (%u).",
+            ESP_LOGE(TAG, "%s: Incorrect param type (%u).",
                         __FUNCTION__, (uint16_t)param_type);
             err = ESP_ERR_NOT_SUPPORTED;
             break;
@@ -420,31 +486,43 @@ static esp_err_t mbc_tcp_master_get_parameter(uint16_t cid, char* name, uint8_t*
 {
     MB_MASTER_CHECK((name != NULL), ESP_ERR_INVALID_ARG, "mb incorrect descriptor.");
     MB_MASTER_CHECK((type != NULL), ESP_ERR_INVALID_ARG, "type pointer is incorrect.");
+    MB_MASTER_CHECK((value != NULL), ESP_ERR_INVALID_ARG, "value pointer is incorrect.");
     esp_err_t error = ESP_ERR_INVALID_RESPONSE;
     mb_param_request_t request ;
     mb_parameter_descriptor_t reg_info = { 0 };
-    uint8_t param_buffer[PARAM_MAX_SIZE] = { 0 };
+    uint8_t* pdata = NULL;
 
     error = mbc_tcp_master_set_request(name, MB_PARAM_READ, &request, &reg_info);
     if ((error == ESP_OK) && (cid == reg_info.cid)) {
-        error = mbc_tcp_master_send_request(&request, &param_buffer[0]);
+        // alloc buffer to store parameter data
+        pdata = calloc(1, (reg_info.mb_size << 1));
+        if (!pdata) {
+            return ESP_ERR_INVALID_STATE;
+        }
+        error = mbc_tcp_master_send_request(&request, pdata);
         if (error == ESP_OK) {
             // If data pointer is NULL then we don't need to set value (it is still in the cache of cid)
             if (value != NULL) {
-                error = mbc_tcp_master_set_param_data((void*)value, (void*)&param_buffer[0],
+                error = mbc_tcp_master_set_param_data((void*)value, (void*)pdata,
                                                     reg_info.param_type, reg_info.param_size);
-                MB_MASTER_CHECK((error == ESP_OK), ESP_ERR_INVALID_STATE, "fail to set parameter data.");
+                if (error != ESP_OK) {
+                    ESP_LOGE(TAG, "fail to set parameter data.");
+                    error = ESP_ERR_INVALID_STATE;
+                } else {
+                    ESP_LOGD(TAG, "%s: Good response for get cid(%u) = %s",
+                                                        __FUNCTION__, (unsigned)reg_info.cid, (char*)esp_err_to_name(error));
+                }
             }
-            ESP_LOGD(MB_MASTER_TAG, "%s: Good response for get cid(%u) = %s",
-                                    __FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error));
         } else {
-            ESP_LOGD(MB_MASTER_TAG, "%s: Bad response to get cid(%u) = %s",
+            ESP_LOGD(TAG, "%s: Bad response to get cid(%u) = %s",
                                             __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error));
+            error = ESP_ERR_INVALID_RESPONSE;
         }
+        free(pdata);
         // Set the type of parameter found in the table
         *type = reg_info.param_type;
     } else {
-        ESP_LOGE(MB_MASTER_TAG, "%s: The cid(%u) not found in the data dictionary.",
+        ESP_LOGE(TAG, "%s: The cid(%u) not found in the data dictionary.",
                                                     __FUNCTION__, reg_info.cid);
         error = ESP_ERR_INVALID_ARG;
     }
@@ -461,27 +539,36 @@ static esp_err_t mbc_tcp_master_set_parameter(uint16_t cid, char* name, uint8_t*
     esp_err_t error = ESP_ERR_INVALID_RESPONSE;
     mb_param_request_t request ;
     mb_parameter_descriptor_t reg_info = { 0 };
-    uint8_t param_buffer[PARAM_MAX_SIZE] = { 0 };
+    uint8_t* pdata = NULL;
 
     error = mbc_tcp_master_set_request(name, MB_PARAM_WRITE, &request, &reg_info);
     if ((error == ESP_OK) && (cid == reg_info.cid)) {
+        pdata = calloc(1, (reg_info.mb_size << 1)); // alloc parameter buffer
+        if (!pdata) {
+            return ESP_ERR_INVALID_STATE;
+        }
         // Transfer value of characteristic into parameter buffer
-        error = mbc_tcp_master_set_param_data((void*)&param_buffer[0], (void*)value,
+        error = mbc_tcp_master_set_param_data((void*)pdata, (void*)value,
                                                 reg_info.param_type, reg_info.param_size);
-        MB_MASTER_CHECK((error == ESP_OK), ESP_ERR_INVALID_STATE, "failure to set parameter data.");
+        if (error != ESP_OK) {
+            ESP_LOGE(TAG, "fail to set parameter data.");
+            free(pdata);
+            return ESP_ERR_INVALID_STATE;
+        }
         // Send request to write characteristic data
-        error = mbc_tcp_master_send_request(&request, &param_buffer[0]);
+        error = mbc_tcp_master_send_request(&request, pdata);
         if (error == ESP_OK) {
-            ESP_LOGD(MB_MASTER_TAG, "%s: Good response for set cid(%u) = %s",
-                                    __FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error));
+            ESP_LOGD(TAG, "%s: Good response for set cid(%u) = %s",
+                                    __FUNCTION__, (unsigned)reg_info.cid, (char*)esp_err_to_name(error));
         } else {
-            ESP_LOGD(MB_MASTER_TAG, "%s: Bad response to set cid(%u) = %s",
+            ESP_LOGD(TAG, "%s: Bad response to set cid(%u) = %s",
                                     __FUNCTION__, reg_info.cid, (char*)esp_err_to_name(error));
         }
+        free(pdata);
         // Set the type of parameter found in the table
         *type = reg_info.param_type;
     } else {
-        ESP_LOGE(MB_MASTER_TAG, "%s: The requested cid(%u) not found in the data dictionary.",
+        ESP_LOGE(TAG, "%s: The requested cid(%u) not found in the data dictionary.",
                                     __FUNCTION__, reg_info.cid);
         error = ESP_ERR_INVALID_ARG;
     }
@@ -709,6 +796,9 @@ esp_err_t mbc_tcp_master_create(void** handler)
     }
     MB_MASTER_ASSERT(mbm_opts->mbm_task_handle != NULL); // The task is created but handle is incorrect
 
+    LIST_INIT(&mbm_opts->mbm_slave_list); // Init slave address list
+    mbm_opts->mbm_slave_list_count = 0;
+
     // Initialize public interface methods of the interface
     mbm_interface_ptr->init = mbc_tcp_master_create;
     mbm_interface_ptr->destroy = mbc_tcp_master_destroy;

+ 136 - 103
components/freemodbus/tcp_master/port/port_tcp_master.c

@@ -59,7 +59,6 @@
 #define MB_TCP_CONNECTION_TIMEOUT_MS    ( 20 )      // Connection timeout in mS
 #define MB_TCP_RECONNECT_TIMEOUT        ( 5000000 ) // Connection timeout in uS
 
-#define MB_TCP_MASTER_PORT_TAG          "MB_TCP_MASTER_PORT"
 #define MB_EVENT_REQ_DONE_MASK          (   EV_MASTER_PROCESS_SUCCESS | \
                                             EV_MASTER_ERROR_RESPOND_TIMEOUT | \
                                             EV_MASTER_ERROR_RECEIVE_DATA | \
@@ -77,6 +76,7 @@
 void vMBPortEventClose( void );
 
 /* ----------------------- Static variables ---------------------------------*/
+static const char *TAG = "MB_TCP_MASTER_PORT";
 static MbPortConfig_t xMbPortConfig;
 static EventGroupHandle_t xMasterEventHandle = NULL;
 static SemaphoreHandle_t xShutdownSemaphore = NULL;
@@ -107,7 +107,7 @@ xMBMasterTCPPortInit( USHORT usTCPPort )
 
     xMbPortConfig.pxMbSlaveInfo = calloc(MB_TCP_PORT_MAX_CONN, sizeof(MbSlaveInfo_t*));
     if (!xMbPortConfig.pxMbSlaveInfo) {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "TCP slave info alloc failure.");
+        ESP_LOGE(TAG, "TCP slave info alloc failure.");
         return FALSE;
     }
     for(int idx = 0; idx < MB_TCP_PORT_MAX_CONN; xMbPortConfig.pxMbSlaveInfo[idx] = NULL, idx++);
@@ -116,12 +116,13 @@ xMBMasterTCPPortInit( USHORT usTCPPort )
     xMbPortConfig.usPort = usTCPPort;
     xMbPortConfig.usMbSlaveInfoCount = 0;
     xMbPortConfig.ucCurSlaveIndex = 1;
+    xMbPortConfig.pxMbSlaveCurrInfo = NULL;
 
-    xMbPortConfig.xConnectQueue = xQueueCreate(2, sizeof(CHAR*));
+    xMbPortConfig.xConnectQueue = xQueueCreate(2, sizeof(MbSlaveAddrInfo_t));
     if (xMbPortConfig.xConnectQueue == 0)
     {
         // Queue was not created and must not be used.
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "TCP master queue creation failure.");
+        ESP_LOGE(TAG, "TCP master queue creation failure.");
         return FALSE;
     }
 
@@ -135,10 +136,10 @@ xMBMasterTCPPortInit( USHORT usTCPPort )
                                     MB_PORT_TASK_AFFINITY);
     if (xErr != pdTRUE)
     {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "TCP master task creation failure.");
+        ESP_LOGE(TAG, "TCP master task creation failure.");
         (void)vTaskDelete(xMbPortConfig.xMbTcpTaskHandle);
     } else {
-        ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "TCP master stack initialized.");
+        ESP_LOGI(TAG, "TCP master stack initialized.");
         bOkay = TRUE;
     }
 
@@ -146,9 +147,30 @@ xMBMasterTCPPortInit( USHORT usTCPPort )
     return bOkay;
 }
 
+static MbSlaveInfo_t* vMBTCPPortMasterFindSlaveInfo(UCHAR ucSlaveAddr)
+{
+    int xIndex;
+    BOOL xFound = false;
+    for (xIndex = 0; xIndex < xMbPortConfig.usMbSlaveInfoCount; xIndex++) {
+        if (xMbPortConfig.pxMbSlaveInfo[xIndex]->ucSlaveAddr == ucSlaveAddr) {
+            xMbPortConfig.pxMbSlaveCurrInfo = xMbPortConfig.pxMbSlaveInfo[xIndex];
+            xFound = TRUE;
+            xMbPortConfig.ucCurSlaveIndex = xIndex;
+        }
+    }
+    if (!xFound) {
+        xMbPortConfig.pxMbSlaveCurrInfo = NULL;
+        ESP_LOGE(TAG, "Slave info for short address %d not found.", ucSlaveAddr);
+    }
+    return xMbPortConfig.pxMbSlaveCurrInfo;
+}
+
 static MbSlaveInfo_t* vMBTCPPortMasterGetCurrInfo(void)
 {
-    return xMbPortConfig.pxMbSlaveInfo[xMbPortConfig.ucCurSlaveIndex - 1];
+    if (!xMbPortConfig.pxMbSlaveCurrInfo) {
+        ESP_LOGE(TAG, "Incorrect current slave info.");
+    }
+    return xMbPortConfig.pxMbSlaveCurrInfo;
 }
 
 // Start Modbus event state machine
@@ -159,10 +181,10 @@ static void vMBTCPPortMasterStartPoll(void)
         EventBits_t xFlags = xEventGroupSetBits(xMasterEventHandle,
                                                 (EventBits_t)xMasterEvent);
         if (!(xFlags & xMasterEvent)) {
-            ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to start TCP stack.");
+            ESP_LOGE(TAG, "Fail to start TCP stack.");
         }
     } else {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to start polling. Incorrect event handle...");
+        ESP_LOGE(TAG, "Fail to start polling. Incorrect event handle...");
     }
 }
 
@@ -174,10 +196,10 @@ static void vMBTCPPortMasterStopPoll(void)
         EventBits_t xFlags = xEventGroupClearBits(xMasterEventHandle,
                                                 (EventBits_t)xMasterEvent);
         if (!(xFlags & xMasterEvent)) {
-            ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to stop polling.");
+            ESP_LOGE(TAG, "Fail to stop polling.");
         }
     } else {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to stop polling. Incorrect event handle...");
+        ESP_LOGE(TAG, "Fail to stop polling. Incorrect event handle...");
     }
 }
 
@@ -208,11 +230,11 @@ static BOOL xMBTCPPortMasterCloseConnection(MbSlaveInfo_t* pxInfo)
         return FALSE;
     }
     if (pxInfo->xSockId == -1) {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Wrong socket info or disconnected socket: %d, skip.", pxInfo->xSockId);
+        ESP_LOGE(TAG, "Wrong socket info or disconnected socket: %d, skip.", pxInfo->xSockId);
         return FALSE;
     }
     if (shutdown(pxInfo->xSockId, SHUT_RDWR) == -1) {
-        ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Shutdown failed sock %d, errno=%d", pxInfo->xSockId, errno);
+        ESP_LOGV(TAG, "Shutdown failed sock %d, errno=%d", pxInfo->xSockId, errno);
     }
     close(pxInfo->xSockId);
     pxInfo->xSockId = -1;
@@ -282,12 +304,12 @@ static int xMBTCPPortMasterGetBuf(MbSlaveInfo_t* pxInfo, UCHAR* pucDstBuf, USHOR
                 continue;
             } else if (errno == ENOTCONN) {
                 // Socket connection closed
-                ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) connection closed.",
+                ESP_LOGE(TAG, "Socket(#%d)(%s) connection closed.",
                                             pxInfo->xSockId, pxInfo->pcIpAddr);
                 return ERR_CONN;
             } else {
                 // Other error occurred during receiving
-                ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) receive error, length=%d, errno=%d",
+                ESP_LOGE(TAG, "Socket(#%d)(%s) receive error, length=%d, errno=%d",
                                             pxInfo->xSockId, pxInfo->pcIpAddr, xLength, errno);
                 return -1;
             }
@@ -318,7 +340,7 @@ static int vMBTCPPortMasterReadPacket(MbSlaveInfo_t* pxInfo)
             pxInfo->xRcvErr = xRet;
             return xRet;
         } else if (xRet != MB_TCP_UID) {
-            ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket (#%d)(%s), Fail to read modbus header. ret=%d",
+            ESP_LOGD(TAG, "Socket (#%d)(%s), Fail to read modbus header. ret=%d",
                                                                 pxInfo->xSockId, pxInfo->pcIpAddr, xRet);
             pxInfo->xRcvErr = ERR_VAL;
             return ERR_VAL;
@@ -332,7 +354,7 @@ static int vMBTCPPortMasterReadPacket(MbSlaveInfo_t* pxInfo)
             return xRet;
         } else if (xRet != xLength) {
             // Received incorrect or fragmented packet.
-            ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) incorrect packet, length=%d, TID=0x%02x, errno=%d(%s)",
+            ESP_LOGD(TAG, "Socket(#%d)(%s) incorrect packet, length=%d, TID=0x%02x, errno=%d(%s)",
                                                pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usRcvPos,
                                                usTidRcv, errno, strerror(errno));
             pxInfo->xRcvErr = ERR_VAL;
@@ -342,13 +364,13 @@ static int vMBTCPPortMasterReadPacket(MbSlaveInfo_t* pxInfo)
 
         // Check transaction identifier field in the incoming packet.
         if ((pxInfo->usTidCnt - 1) != usTidRcv) {
-            ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket (#%d)(%s), incorrect TID(0x%02x)!=(0x%02x) received, discard data.",
+            ESP_LOGD(TAG, "Socket (#%d)(%s), incorrect TID(0x%02x)!=(0x%02x) received, discard data.",
                                                 pxInfo->xSockId, pxInfo->pcIpAddr, usTidRcv, (pxInfo->usTidCnt - 1));
             pxInfo->xRcvErr = ERR_BUF;
             return ERR_BUF;
         }
         pxInfo->usRcvPos += xRet + MB_TCP_UID;
-        ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) get data, length=%d, TID=0x%02x, errno=%d(%s)",
+        ESP_LOGD(TAG, "Socket(#%d)(%s) get data, length=%d, TID=0x%02x, errno=%d(%s)",
                                            pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usRcvPos,
                                            usTidRcv, errno, strerror(errno));
         pxInfo->xRcvErr = ERR_OK;
@@ -365,7 +387,7 @@ static err_t xMBTCPPortMasterSetNonBlocking(MbSlaveInfo_t* pxInfo)
     // Set non blocking attribute for socket
     ULONG ulFlags = fcntl(pxInfo->xSockId, F_GETFL);
     if (fcntl(pxInfo->xSockId, F_SETFL, ulFlags | O_NONBLOCK) == -1) {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s), fcntl() call error=%d",
+        ESP_LOGE(TAG, "Socket(#%d)(%s), fcntl() call error=%d",
                                               pxInfo->xSockId, pxInfo->pcIpAddr, errno);
         return ERR_WOULDBLOCK;
     }
@@ -398,12 +420,12 @@ static err_t xMBTCPPortMasterCheckAlive(MbSlaveInfo_t* pxInfo, ULONG xTimeoutMs)
             if (errno == EINPROGRESS) {
                 xErr = ERR_INPROGRESS;
             } else {
-                ESP_LOGV(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(" connection, select write err(errno) = %d(%d)."),
+                ESP_LOGV(TAG, MB_SLAVE_FMT(" connection, select write err(errno) = %d(%d)."),
                                                     pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xErr, errno);
                 xErr = ERR_CONN;
             }
         } else if (xErr == 0) {
-            ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s), connection timeout occurred, err(errno) = %d(%d).",
+            ESP_LOGV(TAG, "Socket(#%d)(%s), connection timeout occurred, err(errno) = %d(%d).",
                                         pxInfo->xSockId, pxInfo->pcIpAddr, xErr, errno);
             return ERR_INPROGRESS;
         } else {
@@ -412,11 +434,11 @@ static err_t xMBTCPPortMasterCheckAlive(MbSlaveInfo_t* pxInfo, ULONG xTimeoutMs)
             // Check socket error
             xErr = getsockopt(pxInfo->xSockId, SOL_SOCKET, SO_ERROR, (void*)&xOptErr, (socklen_t*)&ulOptLen);
             if (xOptErr != 0) {
-                ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s), sock error occurred (%d).",
+                ESP_LOGD(TAG, "Socket(#%d)(%s), sock error occurred (%d).",
                                             pxInfo->xSockId, pxInfo->pcIpAddr, xOptErr);
                 return ERR_CONN;
             }
-            ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s), is alive.",
+            ESP_LOGV(TAG, "Socket(#%d)(%s), is alive.",
                                         pxInfo->xSockId, pxInfo->pcIpAddr);
             return ERR_OK;
         }
@@ -446,7 +468,7 @@ static BOOL xMBTCPPortMasterCheckHost(const CHAR* pcHostStr, ip_addr_t* pxHostAd
     int xRet = getaddrinfo(pcHostStr, NULL, &xHint, &pxAddrList);
 
     if (xRet != 0) {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Incorrect host name or IP: %s", pcHostStr);
+        ESP_LOGE(TAG, "Incorrect host name or IP: %s", pcHostStr);
         return FALSE;
     }
     if (pxAddrList->ai_family == AF_INET) {
@@ -464,20 +486,24 @@ static BOOL xMBTCPPortMasterCheckHost(const CHAR* pcHostStr, ip_addr_t* pxHostAd
     if (pxHostAddr) {
         *pxHostAddr = xTargetAddr;
     }
-    ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "Host[IP]: \"%s\"[%s]", pxAddrList->ai_canonname, pcStr);
+    ESP_LOGI(TAG, "Host[IP]: \"%s\"[%s]", pxAddrList->ai_canonname, pcStr);
     freeaddrinfo(pxAddrList);
     return TRUE;
 }
 
-BOOL xMBTCPPortMasterAddSlaveIp(const CHAR* pcIpStr)
+BOOL xMBTCPPortMasterAddSlaveIp(const USHORT usIndex, const CHAR* pcIpStr, UCHAR ucSlaveAddress)
 {
     BOOL xRes = FALSE;
+    MbSlaveAddrInfo_t xSlaveAddrInfo = { 0 };
     MB_PORT_CHECK(xMbPortConfig.xConnectQueue != NULL, FALSE, "Wrong slave IP address to add.");
-    if (pcIpStr) {
+    if (pcIpStr && (usIndex != 0xFF)) {
         xRes = xMBTCPPortMasterCheckHost(pcIpStr, NULL);
     }
     if (xRes || !pcIpStr) {
-        BaseType_t xStatus = xQueueSend(xMbPortConfig.xConnectQueue, (const void*)&pcIpStr, 100);
+        xSlaveAddrInfo.pcIPAddr = pcIpStr;
+        xSlaveAddrInfo.usIndex = usIndex;
+        xSlaveAddrInfo.ucSlaveAddr = ucSlaveAddress;
+        BaseType_t xStatus = xQueueSend(xMbPortConfig.xConnectQueue, (void*)&xSlaveAddrInfo, 100);
         MB_PORT_CHECK((xStatus == pdTRUE), FALSE, "FAIL to add slave IP address: [%s].", pcIpStr);
     }
     return xRes;
@@ -515,7 +541,7 @@ static err_t xMBTCPPortMasterConnect(MbSlaveInfo_t* pxInfo)
     int xRet = getaddrinfo(pxInfo->pcIpAddr, pcStr, &xHint, &pxAddrList);
     free(pcStr);
     if (xRet != 0) {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Cannot resolve host: %s", pxInfo->pcIpAddr);
+        ESP_LOGE(TAG, "Cannot resolve host: %s", pxInfo->pcIpAddr);
         return ERR_CONN;
     }
 
@@ -538,12 +564,12 @@ static err_t xMBTCPPortMasterConnect(MbSlaveInfo_t* pxInfo)
         if (pxInfo->xSockId <= 0) {
             pxInfo->xSockId = socket(pxCurAddr->ai_family, pxCurAddr->ai_socktype, pxCurAddr->ai_protocol);
             if (pxInfo->xSockId < 0) {
-                ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Unable to create socket: #%d, errno %d", pxInfo->xSockId, errno);
+                ESP_LOGE(TAG, "Unable to create socket: #%d, errno %d", pxInfo->xSockId, errno);
                 xErr = ERR_IF;
                 continue;
             }
         } else {
-            ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Socket (#%d)(%s) created.", pxInfo->xSockId, cStr);
+            ESP_LOGV(TAG, "Socket (#%d)(%s) created.", pxInfo->xSockId, cStr);
         }
 
         // Set non blocking attribute for socket
@@ -554,7 +580,7 @@ static err_t xMBTCPPortMasterConnect(MbSlaveInfo_t* pxInfo)
         xErr = connect(pxInfo->xSockId, (struct sockaddr*)pxCurAddr->ai_addr, pxCurAddr->ai_addrlen);
         if ((xErr < 0) && (errno == EINPROGRESS || errno == EALREADY)) {
             // The unblocking connect is pending (check status later) or already connected
-            ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Socket(#%d)(%s) connection is pending, errno %d (%s).",
+            ESP_LOGV(TAG, "Socket(#%d)(%s) connection is pending, errno %d (%s).",
                                         pxInfo->xSockId, cStr, errno, strerror(errno));
 
             // Set keep alive flag in socket options
@@ -567,12 +593,12 @@ static err_t xMBTCPPortMasterConnect(MbSlaveInfo_t* pxInfo)
             continue;
         } else if (xErr != ERR_OK) {
             // Other error occurred during connection
-            ESP_LOGV(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(" unable to connect, error=%d, errno %d (%s)"),
+            ESP_LOGV(TAG, MB_SLAVE_FMT(" unable to connect, error=%d, errno %d (%s)"),
                                                 pxInfo->xIndex, pxInfo->xSockId, cStr, xErr, errno, strerror(errno));
             xMBTCPPortMasterCloseConnection(pxInfo);
             xErr = ERR_CONN;
         } else {
-            ESP_LOGI(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", successfully connected."),
+            ESP_LOGI(TAG, MB_SLAVE_FMT(", successfully connected."),
                                                   pxInfo->xIndex, pxInfo->xSockId, cStr);
             continue;
         }
@@ -614,7 +640,7 @@ static int xMBTCPPortMasterCheckConnState(fd_set* pxFdSet)
             xErr = xMBTCPPortMasterCheckAlive(pxInfo, 0);
             if ((xErr < 0) && (((xTime - pxInfo->xRecvTimeStamp) > MB_TCP_RECONNECT_TIMEOUT) ||
                                 ((xTime - pxInfo->xSendTimeStamp) > MB_TCP_RECONNECT_TIMEOUT))) {
-                ESP_LOGI(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", slave is down, off_time[r][w](us) = [%ju][%ju]."),
+                ESP_LOGI(TAG, MB_SLAVE_FMT(", slave is down, off_time[r][w](us) = [%ju][%ju]."),
                                                             pxInfo->xIndex,
                                                             pxInfo->xSockId,
                                                             pxInfo->pcIpAddr,
@@ -636,9 +662,9 @@ static void xMBTCPPortMasterFsmSetError(eMBMasterErrorEventType xErrType, eMBMas
 
 static void vMBTCPPortMasterTask(void *pvParameters)
 {
-    CHAR* pcAddrStr = NULL;
     MbSlaveInfo_t* pxInfo;
     MbSlaveInfo_t* pxCurrInfo;
+
     fd_set xConnSet;
     fd_set xReadSet;
     int xMaxSd = 0;
@@ -648,51 +674,53 @@ static void vMBTCPPortMasterTask(void *pvParameters)
 
     // Register each slave in the connection info structure
     while (1) {
-        BaseType_t xStatus = xQueueReceive(xMbPortConfig.xConnectQueue, (void*)&pcAddrStr, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS));
-        xMBTCPPortMasterCheckShutdown();
+        MbSlaveAddrInfo_t xSlaveAddrInfo = { 0 };
+        BaseType_t xStatus = xQueueReceive(xMbPortConfig.xConnectQueue, (void*)&xSlaveAddrInfo, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS));
+	    xMBTCPPortMasterCheckShutdown();
         if (xStatus != pdTRUE) {
-            ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Fail to register slave IP.");
+            ESP_LOGE(TAG, "Fail to register slave IP.");
         } else {
-            if (pcAddrStr == NULL && xMbPortConfig.usMbSlaveInfoCount) {
+            if (xSlaveAddrInfo.pcIPAddr == NULL && xMbPortConfig.usMbSlaveInfoCount && xSlaveAddrInfo.usIndex == 0xFF) {
                 break;
             }
             if (xMbPortConfig.usMbSlaveInfoCount > MB_TCP_PORT_MAX_CONN) {
-                ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Exceeds maximum connections limit=%d.", MB_TCP_PORT_MAX_CONN);
+                ESP_LOGE(TAG, "Exceeds maximum connections limit=%d.", MB_TCP_PORT_MAX_CONN);
                 break;
             }
             pxInfo = calloc(1, sizeof(MbSlaveInfo_t));
             if (!pxInfo) {
-                ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Slave(#%d), info structure allocation fail.",
+                ESP_LOGE(TAG, "Slave(#%d), info structure allocation fail.",
                                                     xMbPortConfig.usMbSlaveInfoCount);
                 free(pxInfo);
                 break;
             }
             pxInfo->pucRcvBuf = calloc(MB_TCP_BUF_SIZE, sizeof(UCHAR));
             if (!pxInfo->pucRcvBuf) {
-                ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Slave(#%d), receive buffer allocation fail.",
+                ESP_LOGE(TAG, "Slave(#%d), receive buffer allocation fail.",
                                                     xMbPortConfig.usMbSlaveInfoCount);
                 free(pxInfo->pucRcvBuf);
                 break;
             }
             pxInfo->usRcvPos = 0;
-            pxInfo->pcIpAddr = pcAddrStr;
+            pxInfo->pcIpAddr = xSlaveAddrInfo.pcIPAddr;
             pxInfo->xSockId = -1;
             pxInfo->xError = -1;
             pxInfo->xRecvTimeStamp = xMBTCPGetTimeStamp();
             pxInfo->xSendTimeStamp = xMBTCPGetTimeStamp();
             pxInfo->xMbProto = MB_PROTO_TCP;
-            pxInfo->xIndex = xMbPortConfig.usMbSlaveInfoCount;
+            pxInfo->ucSlaveAddr = xSlaveAddrInfo.ucSlaveAddr;
+            pxInfo->xIndex = xSlaveAddrInfo.usIndex;
             pxInfo->usTidCnt = (USHORT)(xMbPortConfig.usMbSlaveInfoCount << 8U);
             // Register slave
             xMbPortConfig.pxMbSlaveInfo[xMbPortConfig.usMbSlaveInfoCount++] = pxInfo;
-            ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "Add slave IP: %s", pcAddrStr);
+            ESP_LOGI(TAG, "Add slave IP: %s", xSlaveAddrInfo.pcIPAddr);
         }
     }
 
     // Main connection cycle
     while (1)
     {
-        ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "Connecting to slaves...");
+        ESP_LOGI(TAG, "Connecting to slaves...");
         xTime = xMBTCPGetTimeStamp();
         usSlaveConnCnt = 0;
         CHAR ucDot = '.';
@@ -705,7 +733,7 @@ static void vMBTCPPortMasterTask(void *pvParameters)
                 pxInfo = xMbPortConfig.pxMbSlaveInfo[ucCnt];
                 // if slave descriptor is NULL then it is end of list or connection closed.
                 if (!pxInfo) {
-                    ESP_LOGV(MB_TCP_MASTER_PORT_TAG, "Index: %d is not initialized, skip.", ucCnt);
+                    ESP_LOGV(TAG, "Index: %d is not initialized, skip.", ucCnt);
                     if (xMbPortConfig.usMbSlaveInfoCount) {
                         continue;
                     }
@@ -720,12 +748,12 @@ static void vMBTCPPortMasterTask(void *pvParameters)
                         // In case of connection errors remove the socket from set
                         if (FD_ISSET(pxInfo->xSockId, &xConnSet)) {
                             FD_CLR(pxInfo->xSockId, &xConnSet);
-                            ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(" connect failed, error = %d."),
+                            ESP_LOGE(TAG, MB_SLAVE_FMT(" connect failed, error = %d."),
                                                                             pxInfo->xIndex, pxInfo->xSockId,
                                                                             (char*)pxInfo->pcIpAddr, xErr);
-                                if (usSlaveConnCnt) {
-                                    usSlaveConnCnt--;
-                                }
+                            if (usSlaveConnCnt) {
+                                usSlaveConnCnt--;
+                            }
                         }
                         break;
                     case ERR_OK:
@@ -734,7 +762,7 @@ static void vMBTCPPortMasterTask(void *pvParameters)
                             FD_SET(pxInfo->xSockId, &xConnSet);
                             usSlaveConnCnt++;
                             xMaxSd = (pxInfo->xSockId > xMaxSd) ? pxInfo->xSockId : xMaxSd;
-                            ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", connected %d slave(s), error = %d."),
+                            ESP_LOGD(TAG, MB_SLAVE_FMT(", connected %d slave(s), error = %d."),
                                                                 pxInfo->xIndex, pxInfo->xSockId,
                                                                 pxInfo->pcIpAddr,
                                                                 usSlaveConnCnt, xErr);
@@ -744,7 +772,7 @@ static void vMBTCPPortMasterTask(void *pvParameters)
                         }
                         break;
                     default:
-                        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", unexpected error = %d."),
+                        ESP_LOGE(TAG, MB_SLAVE_FMT(", unexpected error = %d."),
                                                             pxInfo->xIndex,
                                                             pxInfo->xSockId,
                                                             pxInfo->pcIpAddr, xErr);
@@ -756,7 +784,7 @@ static void vMBTCPPortMasterTask(void *pvParameters)
                 xMBTCPPortMasterCheckShutdown();
             }
         }
-        ESP_LOGI(MB_TCP_MASTER_PORT_TAG, "Connected %d slaves, start polling...", usSlaveConnCnt);
+        ESP_LOGI(TAG, "Connected %d slaves, start polling...", usSlaveConnCnt);
 
         vMBTCPPortMasterStartPoll(); // Send event to start stack
 
@@ -767,26 +795,26 @@ static void vMBTCPPortMasterTask(void *pvParameters)
             xMBMasterPortFsmWaitConfirmation(EV_MASTER_FRAME_TRANSMIT, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS));
             // Synchronize state machine with send packet event
             if (xMBMasterPortFsmWaitConfirmation(EV_MASTER_FRAME_SENT, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS))) {
-                ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "FSM Synchronized with sent event.");
+                ESP_LOGD(TAG, "FSM Synchronized with sent event.");
             }
             // Get slave info for the current slave.
             pxCurrInfo = vMBTCPPortMasterGetCurrInfo();
             if (!pxCurrInfo) {
-                ESP_LOGE(MB_TCP_MASTER_PORT_TAG, "Incorrect connection options for slave index: %d.",
+                ESP_LOGE(TAG, "Incorrect connection options for slave index: %d.",
                                             xMbPortConfig.ucCurSlaveIndex);
                 vMBTCPPortMasterStopPoll();
                 xMBTCPPortMasterCheckShutdown();
                 break; // incorrect slave descriptor, reconnect.
             }
             xTime = xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo);
-            ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Set select timeout, left time: %ju ms.",
+            ESP_LOGD(TAG, "Set select timeout, left time: %ju ms.",
                                         xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo));
             // Wait respond from current slave during respond timeout
             int xRes = vMBTCPPortMasterRxCheck(pxCurrInfo->xSockId, &xReadSet, xTime);
             if (xRes == ERR_TIMEOUT) {
                 // No respond from current slave, process timeout.
                 // Need to drop response later if it is received after timeout.
-                ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Select timeout, left time: %ju ms.",
+                ESP_LOGD(TAG, "Select timeout, left time: %ju ms.",
                                                     xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo));
                 xTime = xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo);
                 // Wait completion of last transaction
@@ -795,7 +823,7 @@ static void vMBTCPPortMasterTask(void *pvParameters)
                 continue;
             } else if (xRes < 0) {
                 // Select error (slave connection or r/w failure).
-                ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", socket select error. Slave disconnected?"),
+                ESP_LOGD(TAG, MB_SLAVE_FMT(", socket select error. Slave disconnected?"),
                             pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr);
                 xTime = xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo);
                 // Wait completion of last transaction
@@ -809,30 +837,30 @@ static void vMBTCPPortMasterTask(void *pvParameters)
             } else {
                 // Check to make sure that active slave data is ready
                 if (FD_ISSET(pxCurrInfo->xSockId, &xReadSet)) {
-                    xErr = ERR_BUF;
-                    for (int retry = 0; (xErr == ERR_BUF) && (retry < MB_TCP_READ_BUF_RETRY_CNT); retry++) {
-                        xErr = vMBTCPPortMasterReadPacket(pxCurrInfo);
+                    int xRet = ERR_BUF;
+                    for (int retry = 0; (xRet == ERR_BUF) && (retry < MB_TCP_READ_BUF_RETRY_CNT); retry++) {
+                        xRet = vMBTCPPortMasterReadPacket(pxCurrInfo);
                         // The error ERR_BUF means received response to previous request
                         // (due to timeout) with the same socket ID and incorrect TID,
                         // then ignore it and try to get next response buffer.
                     }
-                    if (xErr > 0) {
+                    if (xRet > 0) {
                         // Response received correctly, send an event to stack
                         xMBTCPPortMasterFsmSetError(EV_ERROR_INIT, EV_MASTER_FRAME_RECEIVED);
-                        ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", frame received."),
+                        ESP_LOGD(TAG, MB_SLAVE_FMT(", frame received."),
                                     pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr);
-                    } else if ((xErr == ERR_TIMEOUT) || (xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo) == 0)) {
+                    } else if ((xRet == ERR_TIMEOUT) || (xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo) == 0)) {
                         // Timeout occurred when receiving frame, process respond timeout
-                        ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", frame read timeout."),
+                        ESP_LOGD(TAG, MB_SLAVE_FMT(", frame read timeout."),
                                     pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr);
-                    } else if (xErr == ERR_BUF) {
+                    } else if (xRet == ERR_BUF) {
                         // After retries a response with incorrect TID received, process failure.
                         xMBTCPPortMasterFsmSetError(EV_ERROR_RECEIVE_DATA, EV_MASTER_ERROR_PROCESS);
-                        ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", frame error."),
+                        ESP_LOGD(TAG, MB_SLAVE_FMT(", frame error."),
                                     pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr);
                     } else {
-                        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", critical error=%d."),
-                                    pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr, xErr);
+                        ESP_LOGE(TAG, MB_SLAVE_FMT(", critical error=%d."),
+                                    pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr, xRet);
                         // Stop polling process
                         vMBTCPPortMasterStopPoll();
                         xMBTCPPortMasterCheckShutdown();
@@ -841,14 +869,14 @@ static void vMBTCPPortMasterTask(void *pvParameters)
                         break;
                     }
                     xTime = xMBTCPPortMasterGetRespTimeLeft(pxCurrInfo);
-                    ESP_LOGD(MB_TCP_MASTER_PORT_TAG, "Slave #%d, data processing left time %ju [ms].", pxCurrInfo->xIndex, xTime);
+                    ESP_LOGD(TAG, "Slave #%d, data processing left time %ju [ms].", pxCurrInfo->xIndex, xTime);
                     // Wait completion of Modbus frame processing before start of new transaction.
                     if (xMBMasterPortFsmWaitConfirmation(MB_EVENT_REQ_DONE_MASK, pdMS_TO_TICKS(xTime))) {
-                        ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", data processing completed."),
+                        ESP_LOGD(TAG, MB_SLAVE_FMT(", data processing completed."),
                                 pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr);
                     }
                     xTime = xMBTCPGetTimeStamp() - pxCurrInfo->xSendTimeStamp;
-                    ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", processing time[us] = %ju."),
+                    ESP_LOGD(TAG, MB_SLAVE_FMT(", processing time[us] = %ju."),
                                                     pxCurrInfo->xIndex, pxCurrInfo->xSockId, pxCurrInfo->pcIpAddr, xTime);
                 }
             }
@@ -885,7 +913,7 @@ vMBMasterTCPPortClose(void)
     xShutdownSemaphore = xSemaphoreCreateBinary();
     // if no semaphore (alloc issues) or couldn't acquire it, just delete the task
     if (xShutdownSemaphore == NULL || xSemaphoreTake(xShutdownSemaphore, pdMS_TO_TICKS(MB_EVENT_WAIT_TOUT_MS)) != pdTRUE) {
-        ESP_LOGW(MB_TCP_MASTER_PORT_TAG, "Modbus port task couldn't exit gracefully within timeout -> abruptly deleting the task.");
+        ESP_LOGW(TAG, "Modbus port task couldn't exit gracefully within timeout -> abruptly deleting the task.");
         vTaskDelete(xMbPortConfig.xMbTcpTaskHandle);
     }
     if (xShutdownSemaphore) {
@@ -923,13 +951,13 @@ int xMBMasterTCPPortWritePoll(MbSlaveInfo_t* pxInfo, const UCHAR * pucMBTCPFrame
     int xRes = (int)xMBTCPPortMasterCheckAlive(pxInfo, xTimeout);
     if ((xRes < 0) && (xRes != ERR_INPROGRESS))
     {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", is not writable, error: %d, errno %d"),
+        ESP_LOGE(TAG, MB_SLAVE_FMT(", is not writable, error: %d, errno %d"),
                                     pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno);
         return xRes;
     }
     xRes = send(pxInfo->xSockId, pucMBTCPFrame, usTCPLength, TCP_NODELAY);
     if (xRes < 0) {
-        ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send data error: %d, errno %d"),
+        ESP_LOGE(TAG, MB_SLAVE_FMT(", send data error: %d, errno %d"),
                                         pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno);
     }
     return xRes;
@@ -939,36 +967,41 @@ BOOL
 xMBMasterTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength )
 {
     BOOL bFrameSent = FALSE;
-    xMbPortConfig.ucCurSlaveIndex = ucMBMasterGetDestAddress();
-    MbSlaveInfo_t* pxInfo = vMBTCPPortMasterGetCurrInfo();
-
-    // If socket active then send data
-    if (pxInfo->xSockId > -1) {
-        // Apply TID field to the frame before send
-        pucMBTCPFrame[MB_TCP_TID] = (UCHAR)(pxInfo->usTidCnt >> 8U);
-        pucMBTCPFrame[MB_TCP_TID + 1] = (UCHAR)(pxInfo->usTidCnt & 0xFF);
-        int xRes = xMBMasterTCPPortWritePoll(pxInfo, pucMBTCPFrame, usTCPLength, MB_TCP_SEND_TIMEOUT_MS);
-        if (xRes < 0) {
-            ESP_LOGE(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send data failure, err(errno) = %d(%d)."),
-                                           pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno);
-            bFrameSent = FALSE;
-            pxInfo->xError = xRes;
+    USHORT ucCurSlaveIndex = ucMBMasterGetDestAddress();
+    MbSlaveInfo_t* pxInfo = vMBTCPPortMasterFindSlaveInfo(ucCurSlaveIndex);
+
+    // If the slave is correct and active then send data
+    // otherwise treat slave as died and skip
+    if (pxInfo != NULL) {
+        if (pxInfo->xSockId < 0) {
+            ESP_LOGD(TAG, MB_SLAVE_FMT(", send to died slave, error = %d"),
+                                                  pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->xError);
         } else {
-            bFrameSent = TRUE;
-            ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send data successful: TID=0x%02x, %d (bytes), errno %d"),
-                                                pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usTidCnt, xRes, errno);
-            pxInfo->xError = 0;
-            pxInfo->usRcvPos = 0;
-            if (pxInfo->usTidCnt < (USHRT_MAX - 1)) {
-                pxInfo->usTidCnt++;
+            // Apply TID field to the frame before send
+            pucMBTCPFrame[MB_TCP_TID] = (UCHAR)(pxInfo->usTidCnt >> 8U);
+            pucMBTCPFrame[MB_TCP_TID + 1] = (UCHAR)(pxInfo->usTidCnt & 0xFF);
+            int xRes = xMBMasterTCPPortWritePoll(pxInfo, pucMBTCPFrame, usTCPLength, MB_TCP_SEND_TIMEOUT_MS);
+            if (xRes < 0) {
+                ESP_LOGE(TAG, MB_SLAVE_FMT(", send data failure, err(errno) = %d(%d)."),
+                                            pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, xRes, errno);
+                bFrameSent = FALSE;
+                pxInfo->xError = xRes;
             } else {
-                pxInfo->usTidCnt = (USHORT)(pxInfo->xIndex << 8U);
+                bFrameSent = TRUE;
+                ESP_LOGD(TAG, MB_SLAVE_FMT(", send data successful: TID=0x%02x, %d (bytes), errno %d"),
+                                                    pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->usTidCnt, xRes, errno);
+                pxInfo->xError = 0;
+                pxInfo->usRcvPos = 0;
+                if (pxInfo->usTidCnt < (USHRT_MAX - 1)) {
+                    pxInfo->usTidCnt++;
+                } else {
+                    pxInfo->usTidCnt = (USHORT)(pxInfo->xIndex << 8U);
+                }
             }
+            pxInfo->xSendTimeStamp = xMBTCPGetTimeStamp();
         }
-        pxInfo->xSendTimeStamp = xMBTCPGetTimeStamp();
     } else {
-        ESP_LOGD(MB_TCP_MASTER_PORT_TAG, MB_SLAVE_FMT(", send to died slave, error = %d"),
-                                                  pxInfo->xIndex, pxInfo->xSockId, pxInfo->pcIpAddr, pxInfo->xError);
+        ESP_LOGD(TAG, "Send data to died slave, address = %d", ucCurSlaveIndex);
     }
     vMBMasterPortTimersRespondTimeoutEnable();
     xMBMasterPortEventPost(EV_MASTER_FRAME_SENT);

+ 20 - 10
components/freemodbus/tcp_master/port/port_tcp_master.h

@@ -67,6 +67,7 @@ typedef struct {
     int xError;                 /*!< Socket error */
     int xRcvErr;                /*!< Socket receive error */
     const char* pcIpAddr;       /*!< TCP/UDP IP address */
+    UCHAR ucSlaveAddr;          /*!< Slave short address */
     UCHAR* pucRcvBuf;           /*!< Receive buffer pointer */
     USHORT usRcvPos;            /*!< Receive buffer position */
     int pcPort;                 /*!< TCP/UDP port number */
@@ -77,28 +78,37 @@ typedef struct {
 } MbSlaveInfo_t;
 
 typedef struct {
-    TaskHandle_t  xMbTcpTaskHandle; /*!< Master TCP/UDP handling task handle */
-    QueueHandle_t xConnectQueue;    /*!< Master connection queue */
-    USHORT usPort;                  /*!< Master TCP/UDP port number */
-    USHORT usMbSlaveInfoCount;      /*!< Master count of connected slaves */
-    USHORT ucCurSlaveIndex;         /*!< Master current processing slave index */
-    eMBPortIpVer eMbIpVer;          /*!< Master IP version */
-    eMBPortProto eMbProto;          /*!< Master protocol type */
-    void* pvNetIface;               /*!< Master netif interface pointer */
-    MbSlaveInfo_t** pxMbSlaveInfo;  /*!< Master information structure for each connected slave */
+    TaskHandle_t  xMbTcpTaskHandle;     /*!< Master TCP/UDP handling task handle */
+    QueueHandle_t xConnectQueue;        /*!< Master connection queue */
+    USHORT usPort;                      /*!< Master TCP/UDP port number */
+    USHORT usMbSlaveInfoCount;          /*!< Master count of connected slaves */
+    USHORT ucCurSlaveIndex;             /*!< Master current processing slave index */
+    eMBPortIpVer eMbIpVer;              /*!< Master IP version */
+    eMBPortProto eMbProto;              /*!< Master protocol type */
+    void* pvNetIface;                   /*!< Master netif interface pointer */
+    MbSlaveInfo_t** pxMbSlaveInfo;      /*!< Master information structure for each connected slave */
+    MbSlaveInfo_t* pxMbSlaveCurrInfo;   /*!< Master current slave information */
 } MbPortConfig_t;
 
+typedef struct {
+    USHORT usIndex;                     /*!< index of the address info */
+    const char* pcIPAddr;               /*!< represents the IP address of the slave */
+    UCHAR ucSlaveAddr;                  /*!< slave unit ID (UID) field for MBAP frame  */
+} MbSlaveAddrInfo_t;
+
 /* ----------------------- Function prototypes ------------------------------*/
 
 // The functions below are used by Modbus controller interface to configure Modbus port.
 /**
  * Registers slave IP address
  *
+ * @param usIndex index of element in the configuration
  * @param pcIpStr IP address to register
+ * @param ucSlaveAddress slave element index
  *
  * @return TRUE if address registered successfully, else FALSE
  */
-BOOL xMBTCPPortMasterAddSlaveIp(const CHAR* pcIpStr);
+BOOL xMBTCPPortMasterAddSlaveIp(const USHORT usIndex, const CHAR* pcIpStr, UCHAR ucSlaveAddress);
 
 /**
  * Keeps FSM event handle and mask then wait for Master stack to start

+ 1 - 0
components/freemodbus/tcp_slave/modbus_controller/mbc_tcp_slave.c

@@ -32,6 +32,7 @@
 
 // Shared pointer to interface structure
 static mb_slave_interface_t* mbs_interface_ptr = NULL;
+static const char *TAG = "MB_CONTROLLER_SLAVE";
 
 // Modbus task function
 static void modbus_tcp_slave_task(void *pvParameters)

+ 35 - 35
components/freemodbus/tcp_slave/port/port_tcp_slave.c

@@ -61,13 +61,13 @@
 /* ----------------------- Defines  -----------------------------------------*/
 #define MB_TCP_DISCONNECT_TIMEOUT       ( CONFIG_FMB_TCP_CONNECTION_TOUT_SEC * 1000000 ) // disconnect timeout in uS
 #define MB_TCP_RESP_TIMEOUT_MS          ( MB_MASTER_TIMEOUT_MS_RESPOND - 2 ) // slave response time limit
-#define MB_TCP_SLAVE_PORT_TAG           "MB_TCP_SLAVE_PORT"
 #define MB_TCP_NET_LISTEN_BACKLOG       ( SOMAXCONN )
 
 /* ----------------------- Prototypes ---------------------------------------*/
 void vMBPortEventClose( void );
 
 /* ----------------------- Static variables ---------------------------------*/
+static const char *TAG = "MB_TCP_SLAVE_PORT";
 static int xListenSock = -1;
 static SemaphoreHandle_t xShutdownSemaphore = NULL;
 static MbSlavePortConfig_t xConfig = { 0 };
@@ -130,14 +130,14 @@ xMBTCPPortInit( USHORT usTCPPort )
 
     xConfig.pxMbClientInfo = calloc(MB_TCP_PORT_MAX_CONN + 1, sizeof(MbClientInfo_t*));
     if (!xConfig.pxMbClientInfo) {
-        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "TCP client info allocation failure.");
+        ESP_LOGE(TAG, "TCP client info allocation failure.");
         return FALSE;
     }
     for(int idx = 0; idx < MB_TCP_PORT_MAX_CONN; xConfig.pxMbClientInfo[idx] = NULL, idx++);
 
     xConfig.xRespQueueHandle = xMBTCPPortRespQueueCreate();
     if (!xConfig.xRespQueueHandle) {
-        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Response queue allocation failure.");
+        ESP_LOGE(TAG, "Response queue allocation failure.");
         return FALSE;
     }
 
@@ -158,10 +158,10 @@ xMBTCPPortInit( USHORT usTCPPort )
     vTaskSuspend(xConfig.xMbTcpTaskHandle);
     if (xErr != pdTRUE)
     {
-        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Server task creation failure.");
+        ESP_LOGE(TAG, "Server task creation failure.");
         vTaskDelete(xConfig.xMbTcpTaskHandle);
     } else {
-        ESP_LOGI(MB_TCP_SLAVE_PORT_TAG, "Protocol stack initialized.");
+        ESP_LOGI(TAG, "Protocol stack initialized.");
         bOkay = TRUE;
     }
     return bOkay;
@@ -196,7 +196,7 @@ static int xMBTCPPortAcceptConnection(int xListenSockId, char** pcIPAddr)
     // Accept new socket connection if not active
     xSockId = accept(xListenSockId, (struct sockaddr *)&xSrcAddr, &xSize);
     if (xSockId < 0) {
-        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Unable to accept connection: errno=%d", errno);
+        ESP_LOGE(TAG, "Unable to accept connection: errno=%d", errno);
         close(xSockId);
     } else {
         // Get the sender's ip address as string
@@ -208,7 +208,7 @@ static int xMBTCPPortAcceptConnection(int xListenSockId, char** pcIPAddr)
             inet6_ntoa_r(((struct sockaddr_in6 *)&xSrcAddr)->sin6_addr, cAddrStr, sizeof(cAddrStr) - 1);
         }
 #endif
-        ESP_LOGI(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d), accept client connection from address: %s", xSockId, cAddrStr);
+        ESP_LOGI(TAG, "Socket (#%d), accept client connection from address: %s", xSockId, cAddrStr);
         pcStr = calloc(1, strlen(cAddrStr) + 1);
         if (pcStr && pcIPAddr) {
             memcpy(pcStr, cAddrStr, strlen(cAddrStr));
@@ -224,11 +224,11 @@ static BOOL xMBTCPPortCloseConnection(MbClientInfo_t* pxInfo)
     MB_PORT_CHECK(pxInfo, FALSE, "Client info is NULL.");
 
     if (pxInfo->xSockId == -1) {
-        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Wrong socket info or disconnected socket: %d.", pxInfo->xSockId);
+        ESP_LOGE(TAG, "Wrong socket info or disconnected socket: %d.", pxInfo->xSockId);
         return FALSE;
     }
     if (shutdown(pxInfo->xSockId, SHUT_RDWR) == -1) {
-        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d), shutdown failed: errno %d", pxInfo->xSockId, errno);
+        ESP_LOGE(TAG, "Socket (#%d), shutdown failed: errno %d", pxInfo->xSockId, errno);
     }
     close(pxInfo->xSockId);
     pxInfo->xSockId = -1;
@@ -265,7 +265,7 @@ static int xMBTCPPortRxPoll(MbClientInfo_t* pxClientInfo, ULONG xTimeoutMs)
             } else if (xRet == 0) {
                 // timeout occurred
                 if ((xStartTimeStamp + xTimeoutMs * 1000) > xMBTCPGetTimeStamp()) {
-                    ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d) Read timeout.", pxClientInfo->xSockId);
+                    ESP_LOGD(TAG, "Socket (#%d) Read timeout.", pxClientInfo->xSockId);
                     xRet = ERR_TIMEOUT;
                     break;
                 }
@@ -280,12 +280,12 @@ static int xMBTCPPortRxPoll(MbClientInfo_t* pxClientInfo, ULONG xTimeoutMs)
                                       pxClientInfo->usTCPFrameBytesLeft, MSG_DONTWAIT);
                 if (xLength < 0) {
                     // If an error occurred during receiving
-                    ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Receive failed: length=%d, errno=%d", xLength, errno);
+                    ESP_LOGE(TAG, "Receive failed: length=%d, errno=%d", xLength, errno);
                     xRet = (err_t)xLength;
                     break;
                 } else if (xLength == 0) {
                     // Socket connection closed
-                    ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), connection closed.",
+                    ESP_LOGD(TAG, "Socket (#%d)(%s), connection closed.",
                                                         pxClientInfo->xSockId, pxClientInfo->pcIpAddr);
                     xRet = ERR_CLSD;
                     break;
@@ -303,14 +303,14 @@ static int xMBTCPPortRxPoll(MbClientInfo_t* pxClientInfo, ULONG xTimeoutMs)
                             pxClientInfo->usTCPFrameBytesLeft = xLength + MB_TCP_UID - pxClientInfo->usTCPBufPos;
                         } else if (pxClientInfo->usTCPBufPos == (MB_TCP_UID + xLength)) {
 #if MB_TCP_DEBUG
-                            prvvMBTCPLogFrame(MB_TCP_SLAVE_PORT_TAG, (UCHAR*)&pxClientInfo->pucTCPBuf[0], pxClientInfo->usTCPBufPos);
+                            prvvMBTCPLogFrame(TAG, (UCHAR*)&pxClientInfo->pucTCPBuf[0], pxClientInfo->usTCPBufPos);
 #endif
                             // Copy TID field from incoming packet
                             pxClientInfo->usTidCnt = MB_TCP_GET_FIELD(pxClientInfo->pucTCPBuf, MB_TCP_TID);
                             xRet = pxClientInfo->usTCPBufPos;
                             break;
                         } else if ((pxClientInfo->usTCPBufPos + xLength) >= MB_TCP_BUF_SIZE) {
-                            ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Incorrect buffer received (%u) bytes.", xLength);
+                            ESP_LOGE(TAG, "Incorrect buffer received (%u) bytes.", xLength);
                             // This should not happen. We can't deal with such a client and
                             // drop the connection for security reasons.
                             xRet = ERR_BUF;
@@ -395,7 +395,7 @@ vMBTCPPortBindAddr(const CHAR* pcBindIp)
         {
             if (listen(xListenSockFd, MB_TCP_NET_LISTEN_BACKLOG) != 0)
             {
-                ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Error occurred during listen: errno=%d", errno);
+                ESP_LOGE(TAG, "Error occurred during listen: errno=%d", errno);
                 close(xListenSockFd);
                 xListenSockFd = -1;
                 continue;
@@ -403,7 +403,7 @@ vMBTCPPortBindAddr(const CHAR* pcBindIp)
         }
         // Bind was successful
         pcStr = (pxCurAddr->ai_canonname == NULL) ? (CHAR*)"\0" : pxCurAddr->ai_canonname;
-        ESP_LOGI(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d), listener %s on port: %d, errno=%d",
+        ESP_LOGI(TAG, "Socket (#%d), listener %s on port: %d, errno=%d",
                                             xListenSockFd, pcStr, xConfig.usPort, errno);
         break;
     }
@@ -474,11 +474,11 @@ static void vMBTCPPortServerTask(void *pvParameters)
                     vTaskDelete(NULL);
                 }
                 // error occurred during wait for read
-                ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "select() errno = %d.", errno);
+                ESP_LOGE(TAG, "select() errno = %d.", errno);
                 continue;
             } else if (xErr == 0) {
                 // If timeout happened, something is wrong
-                ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "select() timeout, errno = %d.", errno);
+                ESP_LOGE(TAG, "select() timeout, errno = %d.", errno);
             }
 
             // If something happened on the master socket, then its an incoming connection.
@@ -494,21 +494,21 @@ static void vMBTCPPortServerTask(void *pvParameters)
                 // if request for new connection but no space left
                 if (pxClientInfo != NULL) {
                     if (xConfig.pxMbClientInfo[MB_TCP_PORT_MAX_CONN] == NULL) {
-                        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Fail to accept connection %d, only %d connections supported.", i + 1, MB_TCP_PORT_MAX_CONN);
+                        ESP_LOGE(TAG, "Fail to accept connection %d, only %d connections supported.", i + 1, MB_TCP_PORT_MAX_CONN);
                     }
                     xConfig.pxMbClientInfo[MB_TCP_PORT_MAX_CONN] = pxClientInfo; // set last connection info
                 } else {
                     // allocate memory for new client info
                     pxClientInfo = calloc(1, sizeof(MbClientInfo_t));
                     if (!pxClientInfo) {
-                        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Client info allocation fail.");
+                        ESP_LOGE(TAG, "Client info allocation fail.");
                         vMBTCPPortFreeClientInfo(pxClientInfo);
                         pxClientInfo = NULL;
                     } else {
                         // Accept new client connection
                         pxClientInfo->xSockId = xMBTCPPortAcceptConnection(xListenSock, &pcClientIp);
                         if (pxClientInfo->xSockId < 0) {
-                            ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Fail to accept connection for client %d.", (xConfig.usClientCount - 1));
+                            ESP_LOGE(TAG, "Fail to accept connection for client %d.", (xConfig.usClientCount - 1));
                             // Accept connection fail, then free client info and continue polling.
                             vMBTCPPortFreeClientInfo(pxClientInfo);
                             pxClientInfo = NULL;
@@ -516,7 +516,7 @@ static void vMBTCPPortServerTask(void *pvParameters)
                         }
                         pxClientInfo->pucTCPBuf = calloc(MB_TCP_BUF_SIZE, sizeof(UCHAR));
                         if (!pxClientInfo->pucTCPBuf) {
-                            ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Fail to allocate buffer for client %d.", (xConfig.usClientCount - 1));
+                            ESP_LOGE(TAG, "Fail to allocate buffer for client %d.", (xConfig.usClientCount - 1));
                             vMBTCPPortFreeClientInfo(pxClientInfo);
                             pxClientInfo = NULL;
                             continue;
@@ -550,17 +550,17 @@ static void vMBTCPPortServerTask(void *pvParameters)
                                 switch(xErr)
                                 {
                                     case ERR_TIMEOUT:
-                                        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), data receive timeout, time[us]: %d, close active connection.",
+                                        ESP_LOGE(TAG, "Socket (#%d)(%s), data receive timeout, time[us]: %d, close active connection.",
                                                                             pxClientInfo->xSockId, pxClientInfo->pcIpAddr,
                                                                             (int)(xTimeStamp - pxClientInfo->xRecvTimeStamp));
                                         break;
                                     case ERR_CLSD:
-                                        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), connection closed by peer.",
+                                        ESP_LOGE(TAG, "Socket (#%d)(%s), connection closed by peer.",
                                                                             pxClientInfo->xSockId, pxClientInfo->pcIpAddr);
                                         break;
                                     case ERR_BUF:
                                     default:
-                                        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), read data error: %d",
+                                        ESP_LOGE(TAG, "Socket (#%d)(%s), read data error: %d",
                                                                             pxClientInfo->xSockId, pxClientInfo->pcIpAddr, xErr);
                                         break;
                                 }
@@ -585,26 +585,26 @@ static void vMBTCPPortServerTask(void *pvParameters)
                                 // Complete frame received, inform state machine to process frame
                                 xMBPortEventPost(EV_FRAME_RECEIVED);
 
-                                ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Socket (#%d)(%s), get packet TID=0x%X, %d bytes.",
+                                ESP_LOGD(TAG, "Socket (#%d)(%s), get packet TID=0x%X, %d bytes.",
                                                                     pxClientInfo->xSockId, pxClientInfo->pcIpAddr,
                                                                     pxClientInfo->usTidCnt, xErr);
 
                                 // Wait while response is not processed by stack by timeout
                                 UCHAR* pucSentBuffer = vxMBTCPPortRespQueueRecv(xConfig.xRespQueueHandle);
                                 if (pucSentBuffer == NULL) {
-                                    ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Response time exceeds configured %d [ms], ignore packet.",
+                                    ESP_LOGE(TAG, "Response time exceeds configured %d [ms], ignore packet.",
                                                                         MB_TCP_RESP_TIMEOUT_MS);
                                 } else  {
                                     USHORT usSentTid = MB_TCP_GET_FIELD(pucSentBuffer, MB_TCP_TID);
                                     if (usSentTid != pxClientInfo->usTidCnt) {
-                                        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Sent TID(%x) != Recv TID(%x), ignore packet.",
+                                        ESP_LOGE(TAG, "Sent TID(%x) != Recv TID(%x), ignore packet.",
                                                                             usSentTid, pxClientInfo->usTidCnt);
                                     }
                                 }
 
                                 // Get time stamp of last data update
                                 pxClientInfo->xSendTimeStamp = xMBTCPGetTimeStamp();
-                                ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Client %d, Socket(#%d), processing time = %d (us).",
+                                ESP_LOGD(TAG, "Client %d, Socket(#%d), processing time = %d (us).",
                                                             pxClientInfo->xIndex, pxClientInfo->xSockId,
                                                             (int)(pxClientInfo->xSendTimeStamp - pxClientInfo->xRecvTimeStamp));
                             }
@@ -613,7 +613,7 @@ static void vMBTCPPortServerTask(void *pvParameters)
                                 // client is not ready to be read
                                 int64_t xTime = xMBTCPGetTimeStamp() - pxClientInfo->xRecvTimeStamp;
                                 if (xTime > MB_TCP_DISCONNECT_TIMEOUT) {
-                                    ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Client %d, Socket(#%d) do not answer for %d (us). Drop connection...",
+                                    ESP_LOGE(TAG, "Client %d, Socket(#%d) do not answer for %d (us). Drop connection...",
                                                                     pxClientInfo->xIndex, pxClientInfo->xSockId, (int)(xTime));
                                     xMBTCPPortCloseConnection(pxClientInfo);
 
@@ -622,7 +622,7 @@ static void vMBTCPPortServerTask(void *pvParameters)
                                     xConfig.pxMbClientInfo[i] = NULL;
                                 }
                             } else {
-                                ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Client %d is disconnected.", i);
+                                ESP_LOGE(TAG, "Client %d is disconnected.", i);
                             }
                         }
                     } // if ((pxClientInfo != NULL)
@@ -644,7 +644,7 @@ vMBTCPPortClose( )
     vTaskResume(xConfig.xMbTcpTaskHandle);
     if (xShutdownSemaphore == NULL || // if no semaphore (alloc issues) or couldn't acquire it, just delete the task
         xSemaphoreTake(xShutdownSemaphore, 2*pdMS_TO_TICKS(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND)) != pdTRUE) {
-        ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Task couldn't exit gracefully within timeout -> abruptly deleting the task");
+        ESP_LOGE(TAG, "Task couldn't exit gracefully within timeout -> abruptly deleting the task");
         vTaskDelete(xConfig.xMbTcpTaskHandle);
     }
     if (xShutdownSemaphore) {
@@ -706,7 +706,7 @@ xMBTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength )
         // Check if socket writable
         xErr = select(xConfig.pxCurClientInfo->xSockId + 1, NULL, &xWriteSet, &xErrorSet, &xTimeVal);
         if ((xErr == -1) || FD_ISSET(xConfig.pxCurClientInfo->xSockId, &xErrorSet)) {
-            ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket(#%d) , send select() error = %d.",
+            ESP_LOGE(TAG, "Socket(#%d) , send select() error = %d.",
                     xConfig.pxCurClientInfo->xSockId, errno);
             return FALSE;
         }
@@ -718,7 +718,7 @@ xMBTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength )
         // Write message into socket and disable Nagle's algorithm
         xErr = send(xConfig.pxCurClientInfo->xSockId, pucMBTCPFrame, usTCPLength, TCP_NODELAY);
         if (xErr < 0) {
-            ESP_LOGE(MB_TCP_SLAVE_PORT_TAG, "Socket(#%d), fail to send data, errno = %d",
+            ESP_LOGE(TAG, "Socket(#%d), fail to send data, errno = %d",
                     xConfig.pxCurClientInfo->xSockId, errno);
             xConfig.pxCurClientInfo->xError = xErr;
         } else {
@@ -726,7 +726,7 @@ xMBTCPPortSendResponse( UCHAR * pucMBTCPFrame, USHORT usTCPLength )
             vxMBTCPPortRespQueueSend(xConfig.xRespQueueHandle, (void*)pucMBTCPFrame);
         }
     } else {
-        ESP_LOGD(MB_TCP_SLAVE_PORT_TAG, "Port is not active. Release lock.");
+        ESP_LOGD(TAG, "Port is not active. Release lock.");
         vxMBTCPPortRespQueueSend(xConfig.xRespQueueHandle, (void*)pucMBTCPFrame);
     }
     return bFrameSent;

+ 22 - 28
examples/protocols/modbus/serial/mb_master/main/master.c

@@ -38,14 +38,6 @@
 #define POLL_TIMEOUT_MS                 (1)
 #define POLL_TIMEOUT_TICS               (POLL_TIMEOUT_MS / portTICK_RATE_MS)
 
-#define MASTER_TAG "MASTER_TEST"
-
-#define MASTER_CHECK(a, ret_val, str, ...) \
-    if (!(a)) { \
-        ESP_LOGE(MASTER_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
-        return (ret_val); \
-    }
-
 // The macro to get offset for parameter in the appropriate structure
 #define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) + 1))
 #define INPUT_OFFSET(field) ((uint16_t)(offsetof(input_reg_params_t, field) + 1))
@@ -57,6 +49,8 @@
 // Options can be used as bit masks or parameter limits
 #define OPTS(min_val, max_val, step_val) { .opt1 = min_val, .opt2 = max_val, .opt3 = step_val }
 
+static const char *TAG = "MASTER_TEST";
+
 // Enumeration of modbus device addresses accessed by master device
 enum {
     MB_DEVICE_ADDR1 = 1 // Only one slave device used for the test (add other slave addresses here)
@@ -135,7 +129,7 @@ static void* master_get_param_data(const mb_parameter_descriptor_t* param_descri
                break;
        }
     } else {
-        ESP_LOGE(MASTER_TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid);
+        ESP_LOGE(TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid);
         assert(instance_ptr != NULL);
     }
     return instance_ptr;
@@ -149,7 +143,7 @@ static void master_operation_func(void *arg)
     bool alarm_state = false;
     const mb_parameter_descriptor_t* param_descriptor = NULL;
 
-    ESP_LOGI(MASTER_TAG, "Start modbus test...");
+    ESP_LOGI(TAG, "Start modbus test...");
 
     for(uint16_t retry = 0; retry <= MASTER_MAX_RETRY && (!alarm_state); retry++) {
         // Read all found characteristics from slave(s)
@@ -169,7 +163,7 @@ static void master_operation_func(void *arg)
                     err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
                                                                             (uint8_t*)temp_data_ptr, &type);
                     if (err == ESP_OK) {
-                        ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = (0x%08x) read successful.",
+                        ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%08x) read successful.",
                                                  param_descriptor->cid,
                                                  (char*)param_descriptor->param_key,
                                                  (char*)param_descriptor->param_units,
@@ -181,13 +175,13 @@ static void master_operation_func(void *arg)
                             err = mbc_master_set_parameter(cid, (char*)param_descriptor->param_key,
                                                               (uint8_t*)temp_data_ptr, &type);
                             if (err == ESP_OK) {
-                                ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = (0x%08x), write successful.",
+                                ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%08x), write successful.",
                                                             param_descriptor->cid,
                                                             (char*)param_descriptor->param_key,
                                                             (char*)param_descriptor->param_units,
                                                             *(uint32_t*)temp_data_ptr);
                             } else {
-                                ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) write fail, err = 0x%x (%s).",
+                                ESP_LOGE(TAG, "Characteristic #%d (%s) write fail, err = 0x%x (%s).",
                                                         param_descriptor->cid,
                                                         (char*)param_descriptor->param_key,
                                                         (int)err,
@@ -195,7 +189,7 @@ static void master_operation_func(void *arg)
                             }
                         }
                     } else {
-                        ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
+                        ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
                                                 param_descriptor->cid,
                                                 (char*)param_descriptor->param_key,
                                                 (int)err,
@@ -208,7 +202,7 @@ static void master_operation_func(void *arg)
                         *(float*)temp_data_ptr = value;
                         if ((param_descriptor->mb_param_type == MB_PARAM_HOLDING) ||
                             (param_descriptor->mb_param_type == MB_PARAM_INPUT)) {
-                            ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.",
+                            ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.",
                                             param_descriptor->cid,
                                             (char*)param_descriptor->param_key,
                                             (char*)param_descriptor->param_units,
@@ -222,7 +216,7 @@ static void master_operation_func(void *arg)
                         } else {
                             uint16_t state = *(uint16_t*)temp_data_ptr;
                             const char* rw_str = (state & param_descriptor->param_opts.opt1) ? "ON" : "OFF";
-                            ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.",
+                            ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.",
                                             param_descriptor->cid,
                                             (char*)param_descriptor->param_key,
                                             (char*)param_descriptor->param_units,
@@ -234,7 +228,7 @@ static void master_operation_func(void *arg)
                             }
                         }
                     } else {
-                        ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
+                        ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
                                             param_descriptor->cid,
                                             (char*)param_descriptor->param_key,
                                             (int)err,
@@ -248,13 +242,13 @@ static void master_operation_func(void *arg)
     }
 
     if (alarm_state) {
-        ESP_LOGI(MASTER_TAG, "Alarm triggered by cid #%d.",
+        ESP_LOGI(TAG, "Alarm triggered by cid #%d.",
                                         param_descriptor->cid);
     } else {
-        ESP_LOGE(MASTER_TAG, "Alarm is not triggered after %d retries.",
+        ESP_LOGE(TAG, "Alarm is not triggered after %d retries.",
                                         MASTER_MAX_RETRY);
     }
-    ESP_LOGI(MASTER_TAG, "Destroy master...");
+    ESP_LOGI(TAG, "Destroy master...");
     ESP_ERROR_CHECK(mbc_master_destroy());
 }
 
@@ -275,13 +269,13 @@ static esp_err_t master_init(void)
     void* master_handler = NULL;
 
     esp_err_t err = mbc_master_init(MB_PORT_SERIAL_MASTER, &master_handler);
-    MASTER_CHECK((master_handler != NULL), ESP_ERR_INVALID_STATE,
+    MB_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE, TAG,
                                 "mb controller initialization fail.");
-    MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
                             "mb controller initialization fail, returns(0x%x).",
                             (uint32_t)err);
     err = mbc_master_setup((void*)&comm);
-    MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
                             "mb controller setup fail, returns(0x%x).",
                             (uint32_t)err);
 
@@ -290,23 +284,23 @@ static esp_err_t master_init(void)
                               CONFIG_MB_UART_RTS, UART_PIN_NO_CHANGE);
 
     err = mbc_master_start();
-    MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
                             "mb controller start fail, returns(0x%x).",
                             (uint32_t)err);
 
-    MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
             "mb serial set pin failure, uart_set_pin() returned (0x%x).", (uint32_t)err);
     // Set driver mode to Half Duplex
     err = uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX);
-    MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
             "mb serial set mode failure, uart_set_mode() returned (0x%x).", (uint32_t)err);
 
     vTaskDelay(5);
     err = mbc_master_set_descriptor(&device_parameters[0], num_device_parameters);
-    MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
                                 "mb controller set descriptor fail, returns(0x%x).",
                                 (uint32_t)err);
-    ESP_LOGI(MASTER_TAG, "Modbus master stack initialized...");
+    ESP_LOGI(TAG, "Modbus master stack initialized...");
     return err;
 }
 

+ 9 - 9
examples/protocols/modbus/serial/mb_slave/main/slave.c

@@ -40,7 +40,7 @@
                                                 | MB_EVENT_COILS_WR)
 #define MB_READ_WRITE_MASK                  (MB_READ_MASK | MB_WRITE_MASK)
 
-static const char *SLAVE_TAG = "SLAVE_TEST";
+static const char *TAG = "SLAVE_TEST";
 
 static portMUX_TYPE param_lock = portMUX_INITIALIZER_UNLOCKED;
 
@@ -92,7 +92,7 @@ void app_main(void)
     mb_register_area_descriptor_t reg_area; // Modbus register area descriptor structure
 
     // Set UART log level
-    esp_log_level_set(SLAVE_TAG, ESP_LOG_INFO);
+    esp_log_level_set(TAG, ESP_LOG_INFO);
     void* mbc_slave_handler = NULL;
 
     ESP_ERROR_CHECK(mbc_slave_init(MB_PORT_SERIAL_SLAVE, &mbc_slave_handler)); // Initialization of Modbus controller
@@ -166,8 +166,8 @@ void app_main(void)
     // Set UART driver mode to Half Duplex
     ESP_ERROR_CHECK(uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX));
 
-    ESP_LOGI(SLAVE_TAG, "Modbus slave stack initialized.");
-    ESP_LOGI(SLAVE_TAG, "Start modbus test...");
+    ESP_LOGI(TAG, "Modbus slave stack initialized.");
+    ESP_LOGI(TAG, "Start modbus test...");
 
     // The cycle below will be terminated when parameter holdingRegParams.dataChan0
     // incremented each access cycle reaches the CHAN_DATA_MAX_VAL value.
@@ -180,7 +180,7 @@ void app_main(void)
         if(event & (MB_EVENT_HOLDING_REG_WR | MB_EVENT_HOLDING_REG_RD)) {
             // Get parameter information from parameter queue
             ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, MB_PAR_INFO_GET_TOUT));
-            ESP_LOGI(SLAVE_TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
+            ESP_LOGI(TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
                     rw_str,
                     (uint32_t)reg_info.time_stamp,
                     (uint32_t)reg_info.mb_offset,
@@ -198,7 +198,7 @@ void app_main(void)
             }
         } else if (event & MB_EVENT_INPUT_REG_RD) {
             ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, MB_PAR_INFO_GET_TOUT));
-            ESP_LOGI(SLAVE_TAG, "INPUT READ (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
+            ESP_LOGI(TAG, "INPUT READ (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
                     (uint32_t)reg_info.time_stamp,
                     (uint32_t)reg_info.mb_offset,
                     (uint32_t)reg_info.type,
@@ -206,7 +206,7 @@ void app_main(void)
                     (uint32_t)reg_info.size);
         } else if (event & MB_EVENT_DISCRETE_RD) {
             ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, MB_PAR_INFO_GET_TOUT));
-            ESP_LOGI(SLAVE_TAG, "DISCRETE READ (%u us): ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
+            ESP_LOGI(TAG, "DISCRETE READ (%u us): ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
                                 (uint32_t)reg_info.time_stamp,
                                 (uint32_t)reg_info.mb_offset,
                                 (uint32_t)reg_info.type,
@@ -214,7 +214,7 @@ void app_main(void)
                                 (uint32_t)reg_info.size);
         } else if (event & (MB_EVENT_COILS_RD | MB_EVENT_COILS_WR)) {
             ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, MB_PAR_INFO_GET_TOUT));
-            ESP_LOGI(SLAVE_TAG, "COILS %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
+            ESP_LOGI(TAG, "COILS %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
                                 rw_str,
                                 (uint32_t)reg_info.time_stamp,
                                 (uint32_t)reg_info.mb_offset,
@@ -225,7 +225,7 @@ void app_main(void)
         }
     }
     // Destroy of Modbus controller on alarm
-    ESP_LOGI(SLAVE_TAG,"Modbus controller destroyed.");
+    ESP_LOGI(TAG,"Modbus controller destroyed.");
     vTaskDelay(100);
     ESP_ERROR_CHECK(mbc_slave_destroy());
 }

+ 51 - 46
examples/protocols/modbus/tcp/example_test.py

@@ -1,3 +1,6 @@
+# SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
+# SPDX-License-Identifier: Apache-2.0
+
 import logging
 import os
 import re
@@ -69,7 +72,7 @@ class DutTestThread(Thread):
         super(DutTestThread, self).__init__()
 
     def __enter__(self):
-        logger.debug('Restart %s.' % self.tname)
+        logger.debug('Restart %s.', self.tname)
         # Reset DUT first
         self.dut.reset()
         # Capture output from the DUT
@@ -80,7 +83,7 @@ class DutTestThread(Thread):
         """ The exit method of context manager
         """
         if exc_type is not None or exc_value is not None:
-            logger.info('Thread %s rised an exception type: %s, value: %s' % (self.tname, str(exc_type), str(exc_value)))
+            logger.info('Thread %s rised an exception type: %s, value: %s', self.tname, str(exc_type), str(exc_value))
 
     def run(self):
         """ The function implements thread functionality
@@ -95,7 +98,7 @@ class DutTestThread(Thread):
         # Check DUT exceptions
         dut_exceptions = self.dut.get_exceptions()
         if 'Guru Meditation Error:' in dut_exceptions:
-            raise Exception('%s generated an exception: %s\n' % (str(self.dut), dut_exceptions))
+            raise RuntimeError('%s generated an exception(s): %s\n' % (str(self.dut), dut_exceptions))
 
         # Mark thread has run to completion without any exceptions
         self.data = self.dut.stop_capture_raw_data(capture_id=self.dut.name)
@@ -106,15 +109,17 @@ class DutTestThread(Thread):
         message = r'.*Waiting IP([0-9]{1,2}) from stdin.*'
         # Read all data from previous restart to get prompt correctly
         self.dut.read()
-        result = self.dut.expect(re.compile(message), TEST_EXPECT_STR_TIMEOUT)
+        result = self.dut.expect(re.compile(message), timeout=TEST_EXPECT_STR_TIMEOUT)
         if int(result[0]) != index:
-            raise Exception('Incorrect index of IP=%d for %s\n' % (int(result[0]), str(self.dut)))
-        message = 'IP%s=%s' % (result[0], self.ip_addr)
-        self.dut.write(message, '\r\n', False)
-        logger.debug('Sent message for %s: %s' % (self.tname, message))
+            raise RuntimeError('Incorrect index of IP=%s for %s\n' % (result[0], str(self.dut)))
+        # Use the same slave IP address for all characteristics during the test
+        self.dut.write('IP0=' + self.ip_addr, '\n', False)
+        self.dut.write('IP1=' + self.ip_addr, '\n', False)
+        self.dut.write('IP2=' + self.ip_addr, '\n', False)
+        logger.debug('Set IP address=%s for %s', self.ip_addr, self.tname)
         message = r'.*IP\([0-9]+\) = \[([0-9a-zA-Z\.\:]+)\] set from stdin.*'
-        result = self.dut.expect(re.compile(message), TEST_EXPECT_STR_TIMEOUT)
-        logger.debug('Thread %s initialized with slave IP (%s).' % (self.tname, result[0]))
+        result = self.dut.expect(re.compile(message), timeout=TEST_EXPECT_STR_TIMEOUT)
+        logger.debug('Thread %s initialized with slave IP=%s.', self.tname, self.ip_addr)
 
     def test_start(self, timeout_value):
         """ The method to initialize and handle test stages
@@ -122,37 +127,37 @@ class DutTestThread(Thread):
         def handle_get_ip4(data):
             """ Handle get_ip v4
             """
-            logger.debug('%s[STACK_IPV4]: %s' % (self.tname, str(data)))
+            logger.debug('%s[STACK_IPV4]: %s', self.tname, str(data))
             self.test_stage = STACK_IPV4
 
         def handle_get_ip6(data):
             """ Handle get_ip v6
             """
-            logger.debug('%s[STACK_IPV6]: %s' % (self.tname, str(data)))
+            logger.debug('%s[STACK_IPV6]: %s', self.tname, str(data))
             self.test_stage = STACK_IPV6
 
         def handle_init(data):
             """ Handle init
             """
-            logger.debug('%s[STACK_INIT]: %s' % (self.tname, str(data)))
+            logger.debug('%s[STACK_INIT]: %s', self.tname, str(data))
             self.test_stage = STACK_INIT
 
         def handle_connect(data):
             """ Handle connect
             """
-            logger.debug('%s[STACK_CONNECT]: %s' % (self.tname, str(data)))
+            logger.debug('%s[STACK_CONNECT]: %s', self.tname, str(data))
             self.test_stage = STACK_CONNECT
 
         def handle_test_start(data):
             """ Handle connect
             """
-            logger.debug('%s[STACK_START]: %s' % (self.tname, str(data)))
+            logger.debug('%s[STACK_START]: %s', self.tname, str(data))
             self.test_stage = STACK_START
 
         def handle_par_ok(data):
             """ Handle parameter ok
             """
-            logger.debug('%s[READ_PAR_OK]: %s' % (self.tname, str(data)))
+            logger.debug('%s[READ_PAR_OK]: %s', self.tname, str(data))
             if self.test_stage >= STACK_START:
                 self.param_ok_count += 1
             self.test_stage = STACK_PAR_OK
@@ -160,14 +165,14 @@ class DutTestThread(Thread):
         def handle_par_fail(data):
             """ Handle parameter fail
             """
-            logger.debug('%s[READ_PAR_FAIL]: %s' % (self.tname, str(data)))
+            logger.debug('%s[READ_PAR_FAIL]: %s', self.tname, str(data))
             self.param_fail_count += 1
             self.test_stage = STACK_PAR_FAIL
 
         def handle_destroy(data):
             """ Handle destroy
             """
-            logger.debug('%s[DESTROY]: %s' % (self.tname, str(data)))
+            logger.debug('%s[DESTROY]: %s', self.tname, str(data))
             self.test_stage = STACK_DESTROY
             self.test_finish = True
 
@@ -183,7 +188,7 @@ class DutTestThread(Thread):
                                     (re.compile(self.expected[STACK_DESTROY]), handle_destroy),
                                     timeout=timeout_value)
             except DUT.ExpectTimeout:
-                logger.debug('%s, expect timeout on stage #%d (%s seconds)' % (self.tname, self.test_stage, timeout_value))
+                logger.debug('%s, expect timeout on stage #%d (%s seconds)', self.tname, self.test_stage, timeout_value)
                 self.test_finish = True
 
 
@@ -193,14 +198,14 @@ def test_check_mode(dut=None, mode_str=None, value=None):
     global logger
     try:
         opt = dut.app.get_sdkconfig()[mode_str]
-        logger.debug('%s {%s} = %s.\n' % (str(dut), mode_str, opt))
+        logger.debug('%s {%s} = %s.\n', str(dut), mode_str, opt)
         return value == opt
     except Exception:
-        logger.error('ENV_TEST_FAILURE: %s: Cannot find option %s in sdkconfig.' % (str(dut), mode_str))
+        logger.error('ENV_TEST_FAILURE: %s: Cannot find option %s in sdkconfig.', str(dut), mode_str)
     return False
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_Modbus_TCP')
+@ttfw_idf.idf_example_test(env_tag='Example_Modbus_TCP', target=['esp32'])
 def test_modbus_communication(env, comm_mode):
     global logger
 
@@ -235,7 +240,7 @@ def test_modbus_communication(env, comm_mode):
             master_name = TEST_MASTER_TCP
         else:
             logger.error('ENV_TEST_FAILURE: IP resolver mode do not match in the master and slave implementation.\n')
-            raise Exception('ENV_TEST_FAILURE: IP resolver mode do not match in the master and slave implementation.\n')
+            raise RuntimeError('ENV_TEST_FAILURE: IP resolver mode do not match in the master and slave implementation.\n')
         address = None
         if test_check_mode(dut_master, 'CONFIG_MB_SLAVE_IP_FROM_STDIN', 'y'):
             logger.info('ENV_TEST_INFO: Set slave IP address through STDIN.\n')
@@ -249,9 +254,9 @@ def test_modbus_communication(env, comm_mode):
             if address is not None:
                     print('Found IP slave address: %s' % address[0])
             else:
-                raise Exception('ENV_TEST_FAILURE: Slave IP address is not found in the output. Check network settings.\n')
+                raise RuntimeError('ENV_TEST_FAILURE: Slave IP address is not found in the output. Check network settings.\n')
         else:
-            raise Exception('ENV_TEST_FAILURE: Slave IP resolver is not configured correctly.\n')
+            raise RuntimeError('ENV_TEST_FAILURE: Slave IP resolver is not configured correctly.\n')
 
         # Create thread for each dut
         with DutTestThread(dut=dut_master, name=master_name, ip_addr=address[0], expect=pattern_dict_master) as dut_master_thread:
@@ -265,32 +270,32 @@ def test_modbus_communication(env, comm_mode):
                 dut_slave_thread.join(timeout=TEST_THREAD_JOIN_TIMEOUT)
                 dut_master_thread.join(timeout=TEST_THREAD_JOIN_TIMEOUT)
 
-                if dut_slave_thread.isAlive():
-                    logger.error('ENV_TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' %
-                                 (dut_slave_thread.tname, TEST_THREAD_JOIN_TIMEOUT))
-                    raise Exception('ENV_TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' %
-                                    (dut_slave_thread.tname, TEST_THREAD_JOIN_TIMEOUT))
-
-                if dut_master_thread.isAlive():
-                    logger.error('TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' %
-                                 (dut_master_thread.tname, TEST_THREAD_JOIN_TIMEOUT))
-                    raise Exception('TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' %
-                                    (dut_master_thread.tname, TEST_THREAD_JOIN_TIMEOUT))
-
-                logger.info('TEST_INFO: %s error count = %d, %s error count = %d.\n' %
-                            (dut_master_thread.tname, dut_master_thread.param_fail_count,
-                             dut_slave_thread.tname, dut_slave_thread.param_fail_count))
-                logger.info('TEST_INFO: %s ok count = %d, %s ok count = %d.\n' %
-                            (dut_master_thread.tname, dut_master_thread.param_ok_count,
-                             dut_slave_thread.tname, dut_slave_thread.param_ok_count))
+                if dut_slave_thread.is_alive():
+                    logger.error('ENV_TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n',
+                                 dut_slave_thread.tname, TEST_THREAD_JOIN_TIMEOUT)
+                    raise RuntimeError('ENV_TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' %
+                                       (dut_slave_thread.tname, TEST_THREAD_JOIN_TIMEOUT))
+
+                if dut_master_thread.is_alive():
+                    logger.error('TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n',
+                                 dut_master_thread.tname, TEST_THREAD_JOIN_TIMEOUT)
+                    raise RuntimeError('TEST_FAILURE: The thread %s is not completed successfully after %d seconds.\n' %
+                                       (dut_master_thread.tname, TEST_THREAD_JOIN_TIMEOUT))
+
+                logger.info('TEST_INFO: %s error count = %d, %s error count = %d.\n',
+                            dut_master_thread.tname, dut_master_thread.param_fail_count,
+                            dut_slave_thread.tname, dut_slave_thread.param_fail_count)
+                logger.info('TEST_INFO: %s ok count = %d, %s ok count = %d.\n',
+                            dut_master_thread.tname, dut_master_thread.param_ok_count,
+                            dut_slave_thread.tname, dut_slave_thread.param_ok_count)
 
                 if ((dut_master_thread.param_fail_count > TEST_READ_MAX_ERR_COUNT) or
                    (dut_slave_thread.param_fail_count > TEST_READ_MAX_ERR_COUNT) or
                    (dut_slave_thread.param_ok_count == 0) or
                    (dut_master_thread.param_ok_count == 0)):
-                    raise Exception('TEST_FAILURE: %s parameter read error(ok) count = %d(%d), %s parameter read error(ok) count = %d(%d).\n' %
-                                    (dut_master_thread.tname, dut_master_thread.param_fail_count, dut_master_thread.param_ok_count,
-                                     dut_slave_thread.tname, dut_slave_thread.param_fail_count, dut_slave_thread.param_ok_count))
+                    raise RuntimeError('TEST_FAILURE: %s parameter read error(ok) count = %d(%d), %s parameter read error(ok) count = %d(%d).\n' %
+                                       (dut_master_thread.tname, dut_master_thread.param_fail_count, dut_master_thread.param_ok_count,
+                                        dut_slave_thread.tname, dut_slave_thread.param_fail_count, dut_slave_thread.param_ok_count))
                 logger.info('TEST_SUCCESS: The Modbus parameter test is completed successfully.\n')
 
     finally:

+ 164 - 117
examples/protocols/modbus/tcp/mb_tcp_master/main/tcp_master.c

@@ -1,20 +1,14 @@
-// Copyright 2016-2019 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "string.h"
+/*
+ * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// FreeModbus Master Example ESP32
+
+#include <string.h>
+#include <sys/queue.h>
 #include "esp_log.h"
-#include "esp_check.h"
 #include "esp_system.h"
 #include "esp_wifi.h"
 #include "esp_event.h"
@@ -45,8 +39,6 @@
 #define POLL_TIMEOUT_TICS               (POLL_TIMEOUT_MS / portTICK_RATE_MS)
 #define MB_MDNS_PORT                    (502)
 
-#define MASTER_TAG "MASTER_TEST"
-
 // The macro to get offset for parameter in the appropriate structure
 #define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) + 1))
 #define INPUT_OFFSET(field) ((uint16_t)(offsetof(input_reg_params_t, field) + 1))
@@ -71,12 +63,14 @@
 #endif
 
 #define MB_MDNS_INSTANCE(pref) pref"mb_master_tcp"
+static const char *TAG = "MASTER_TEST";
 
 // Enumeration of modbus device addresses accessed by master device
 // Each address in the table is a index of TCP slave ip address in mb_communication_info_t::tcp_ip_addr table
 enum {
     MB_DEVICE_ADDR1 = 1, // Slave address 1
-    MB_DEVICE_COUNT
+    MB_DEVICE_ADDR2 = 200,
+    MB_DEVICE_ADDR3 = 35
 };
 
 // Enumeration of all supported CIDs for device (used in parameter definition table)
@@ -109,11 +103,11 @@ const mb_parameter_descriptor_t device_parameters[] = {
             HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
     { CID_INP_DATA_1, STR("Temperature_1"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 2, 2,
             INPUT_OFFSET(input_data1), PARAM_TYPE_FLOAT, 4, OPTS( -40, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
-    { CID_HOLD_DATA_1, STR("Humidity_2"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 2, 2,
+    { CID_HOLD_DATA_1, STR("Humidity_2"), STR("%rH"), MB_DEVICE_ADDR2, MB_PARAM_HOLDING, 2, 2,
             HOLD_OFFSET(holding_data1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
-    { CID_INP_DATA_2, STR("Temperature_2"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 4, 2,
+    { CID_INP_DATA_2, STR("Temperature_2"), STR("C"), MB_DEVICE_ADDR2, MB_PARAM_INPUT, 4, 2,
             INPUT_OFFSET(input_data2), PARAM_TYPE_FLOAT, 4, OPTS( -40, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
-    { CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 4, 2,
+    { CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR3, MB_PARAM_HOLDING, 4, 2,
             HOLD_OFFSET(holding_data2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
     { CID_RELAY_P1, STR("RelayP1"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 0, 8,
             COIL_OFFSET(coils_port0), PARAM_TYPE_U16, 2, OPTS( BIT1, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
@@ -122,20 +116,26 @@ const mb_parameter_descriptor_t device_parameters[] = {
 };
 
 // Calculate number of parameters in the table
-const uint16_t num_device_parameters = (sizeof(device_parameters)/sizeof(device_parameters[0]));
+const uint16_t num_device_parameters = (sizeof(device_parameters) / sizeof(device_parameters[0]));
 
 // This table represents slave IP addresses that correspond to the short address field of the slave in device_parameters structure
 // Modbus TCP stack shall use these addresses to be able to connect and read parameters from slave
-char* slave_ip_address_table[MB_DEVICE_COUNT] = {
+char* slave_ip_address_table[] = {
 #if CONFIG_MB_SLAVE_IP_FROM_STDIN
     "FROM_STDIN",     // Address corresponds to MB_DEVICE_ADDR1 and set to predefined value by user
-    NULL
+    "FROM_STDIN",     // Corresponds to characteristic MB_DEVICE_ADDR2
+    "FROM_STDIN",     // Corresponds to characteristic MB_DEVICE_ADDR3
+    NULL              // End of table condition (must be included)
 #elif CONFIG_MB_MDNS_IP_RESOLVER
+    NULL,
+    NULL,
     NULL,
     NULL
 #endif
 };
 
+const size_t ip_table_sz = (size_t)(sizeof(slave_ip_address_table) / sizeof(slave_ip_address_table[0]));
+
 #if CONFIG_MB_SLAVE_IP_FROM_STDIN
 
 // Scan IP address according to IPV settings
@@ -186,8 +186,8 @@ static int master_get_slave_ip_stdin(char** addr_table)
             fputc('\n', stdout);
             ip_str = master_scan_addr(&index, buf);
             if (ip_str != NULL) {
-                ESP_LOGI(MASTER_TAG, "IP(%d) = [%s] set from stdin.", ip_cnt, ip_str);
-                if ((ip_cnt >= MB_DEVICE_COUNT) || (index != ip_cnt)) {
+                ESP_LOGI(TAG, "IP(%d) = [%s] set from stdin.", ip_cnt, ip_str);
+                if ((ip_cnt >= ip_table_sz) || (index != ip_cnt)) {
                     addr_table[ip_cnt] = NULL;
                     break;
                 }
@@ -199,10 +199,10 @@ static int master_get_slave_ip_stdin(char** addr_table)
             }
         } else {
             if (addr_table[ip_cnt]) {
-                ESP_LOGI(MASTER_TAG, "Leave IP(%d) = [%s] set manually.", ip_cnt, addr_table[ip_cnt]);
+                ESP_LOGI(TAG, "Leave IP(%d) = [%s] set manually.", ip_cnt, addr_table[ip_cnt]);
                 ip_cnt++;
             } else {
-                ESP_LOGI(MASTER_TAG, "IP(%d) is not set in the table.", ip_cnt);
+                ESP_LOGI(TAG, "IP(%d) is not set in the table.", ip_cnt);
                 break;
             }
         }
@@ -212,6 +212,16 @@ static int master_get_slave_ip_stdin(char** addr_table)
 
 #elif CONFIG_MB_MDNS_IP_RESOLVER
 
+typedef struct slave_addr_entry_s {
+    uint16_t index;
+    char* ip_address;
+    uint8_t slave_addr;
+    void* p_data;
+    LIST_ENTRY(slave_addr_entry_s) entries;
+} slave_addr_entry_t;
+
+LIST_HEAD(slave_addr_, slave_addr_entry_s) slave_addr_list = LIST_HEAD_INITIALIZER(slave_addr_list);
+
 // convert MAC from binary format to string
 static inline char* gen_mac_str(const uint8_t* mac, char* pref, char* mac_str)
 {
@@ -235,7 +245,7 @@ static void master_start_mdns_service()
     ESP_ERROR_CHECK(mdns_init());
     // set mDNS hostname (required if you want to advertise services)
     ESP_ERROR_CHECK(mdns_hostname_set(hostname));
-    ESP_LOGI(MASTER_TAG, "mdns hostname set to: [%s]", hostname);
+    ESP_LOGI(TAG, "mdns hostname set to: [%s]", hostname);
 
     // set default mDNS instance name
     ESP_ERROR_CHECK(mdns_instance_name_set(MB_MDNS_INSTANCE("esp32_")));
@@ -276,15 +286,21 @@ static char* master_get_slave_ip_str(mdns_ip_addr_t* address, mb_tcp_addr_type_t
     return slave_ip_str;
 }
 
-static esp_err_t master_resolve_slave(const char* name, mdns_result_t* result, char** resolved_ip,
+static esp_err_t master_resolve_slave(uint8_t short_addr, mdns_result_t* result, char** resolved_ip,
                                         mb_tcp_addr_type_t addr_type)
 {
-    if (!name || !result) {
+    if (!short_addr || !result || !resolved_ip) {
         return ESP_ERR_INVALID_ARG;
     }
     mdns_result_t* r = result;
     int t;
     char* slave_ip = NULL;
+    char slave_name[22] = {0};
+
+    if (sprintf(slave_name, "mb_slave_tcp_%02X", short_addr) < 0) {
+        ESP_LOGE(TAG, "Fail to create instance name for index: %d", short_addr);
+        abort();
+    }
     for (; r ; r = r->next) {
         if ((r->ip_protocol == MDNS_IP_PROTOCOL_V4) && (addr_type == MB_IPV6)) {
             continue;
@@ -293,7 +309,7 @@ static esp_err_t master_resolve_slave(const char* name, mdns_result_t* result, c
         }
         // Check host name for Modbus short address and
         // append it into slave ip address table
-        if ((strcmp(r->instance_name, name) == 0) && (r->port == CONFIG_FMB_TCP_PORT_DEFAULT)) {
+        if ((strcmp(r->instance_name, slave_name) == 0) && (r->port == CONFIG_FMB_TCP_PORT_DEFAULT)) {
             printf("  PTR : %s\n", r->instance_name);
             if (r->txt_count) {
                 printf("  TXT : [%u] ", r->txt_count);
@@ -304,92 +320,124 @@ static esp_err_t master_resolve_slave(const char* name, mdns_result_t* result, c
             }
             slave_ip = master_get_slave_ip_str(r->addr, addr_type);
             if (slave_ip) {
-                ESP_LOGI(MASTER_TAG, "Resolved slave %s[%s]:%u", r->hostname, slave_ip, r->port);
+                ESP_LOGI(TAG, "Resolved slave %s[%s]:%u", r->hostname, slave_ip, r->port);
                 *resolved_ip = slave_ip;
                 return ESP_OK;
             }
         }
     }
     *resolved_ip = NULL;
-    ESP_LOGD(MASTER_TAG, "Fail to resolve slave: %s", name);
+    ESP_LOGD(TAG, "Fail to resolve slave: %s", slave_name);
     return ESP_ERR_NOT_FOUND;
 }
 
 static int master_create_slave_list(mdns_result_t* results, char** addr_table,
-                                        mb_tcp_addr_type_t addr_type)
+                                        int addr_table_size, mb_tcp_addr_type_t addr_type)
 {
     if (!results) {
         return -1;
     }
-    int i, addr, resolved = 0;
+    int i, slave_addr, cid_resolve_cnt = 0;
+    int ip_index = 0;
     const mb_parameter_descriptor_t* pdescr = &device_parameters[0];
     char** ip_table = addr_table;
-    char slave_name[22] = {0};
     char* slave_ip = NULL;
+    slave_addr_entry_t *it;
 
-    for (i = 0; (i < num_device_parameters && pdescr); i++, pdescr++) {
-        addr = pdescr->mb_slave_addr;
-        if (-1 == sprintf(slave_name, "mb_slave_tcp_%02X", addr)) {
-            ESP_LOGI(MASTER_TAG, "Fail to create instance name for index: %d", addr);
-            abort();
+    for (i = 0; (i < num_device_parameters && pdescr); i++, pdescr++)
+    {
+        slave_addr = pdescr->mb_slave_addr;
+
+        it = NULL;
+        // Is the slave address already registered?
+        LIST_FOREACH(it, &slave_addr_list, entries) {
+            if (slave_addr == it->slave_addr) {
+                break;
+            }
         }
-        if (!ip_table[addr - 1]) {
-            esp_err_t err = master_resolve_slave(slave_name, results, &slave_ip, addr_type);
+        if (!it) {
+            // Resolve new slave IP address using its short address
+            esp_err_t err = master_resolve_slave(slave_addr, results, &slave_ip, addr_type);
             if (err != ESP_OK) {
-                ESP_LOGE(MASTER_TAG, "Index: %d, sl_addr: %d, name:%s, failed to resolve!",
-                                        i, addr, slave_name);
+                ESP_LOGE(TAG, "Index: %d, sl_addr: %d, failed to resolve!", i, slave_addr);
                 // Set correspond index to NULL indicate host not resolved
-                ip_table[addr - 1] = NULL;
+                ip_table[ip_index] = NULL;
                 continue;
             }
-            ip_table[addr - 1] = slave_ip; //slave_name;
-            ESP_LOGI(MASTER_TAG, "Index: %d, sl_addr: %d, name:%s, resolve to IP: [%s]",
-                                    i, addr, slave_name, slave_ip);
-            resolved++;
+            // Register new slave address information
+            slave_addr_entry_t* new_slave_entry = (slave_addr_entry_t*) heap_caps_malloc(sizeof(slave_addr_entry_t),
+                                                       MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
+            MB_RETURN_ON_FALSE((new_slave_entry != NULL), ESP_ERR_NO_MEM,
+                                                 TAG, "Can not allocate memory for slave entry.");
+            new_slave_entry->index = i;
+            new_slave_entry->ip_address = slave_ip;
+            new_slave_entry->slave_addr = slave_addr;
+            new_slave_entry->p_data = NULL;
+            LIST_INSERT_HEAD(&slave_addr_list, new_slave_entry, entries);
+            ip_table[ip_index] = slave_ip;
+            ESP_LOGI(TAG, "Index: %d, sl_addr: %d, resolved to IP: [%s]",
+                                                i, slave_addr, slave_ip);
+            cid_resolve_cnt++;
+            if (ip_index < addr_table_size) {
+                ip_index++;
+            }
         } else {
-            ESP_LOGI(MASTER_TAG, "Index: %d, sl_addr: %d, name:%s, set to IP: [%s]",
-                                    i, addr, slave_name, ip_table[addr - 1]);
-            resolved++;
-        }
-    }
-    return resolved;
-}
-
-static void master_destroy_slave_list(char** table)
-{
-    for (int i = 0; ((i < MB_DEVICE_COUNT) && table[i] != NULL); i++) {
-        if (table[i]) {
-            free(table[i]);
-            table[i] = NULL;
+            ip_table[ip_index] = it ? it->ip_address : ip_table[ip_index];
+            ESP_LOGI(TAG, "Index: %d, sl_addr: %d, set to IP: [%s]",
+                                    i, slave_addr, ip_table[ip_index]);
+            cid_resolve_cnt++;
         }
     }
+    ESP_LOGI(TAG, "Resolved %d cids, with %d IP addresses", cid_resolve_cnt, ip_index);
+    return cid_resolve_cnt;
 }
 
 static int master_query_slave_service(const char * service_name, const char * proto,
                                         mb_tcp_addr_type_t addr_type)
 {
-    ESP_LOGI(MASTER_TAG, "Query PTR: %s.%s.local", service_name, proto);
+    ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto);
 
     mdns_result_t* results = NULL;
     int count = 0;
 
     esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results);
     if(err){
-        ESP_LOGE(MASTER_TAG, "Query Failed: %s", esp_err_to_name(err));
+        ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
         return count;
     }
     if(!results){
-        ESP_LOGW(MASTER_TAG, "No results found!");
+        ESP_LOGW(TAG, "No results found!");
         return count;
     }
 
-    count = master_create_slave_list(results, slave_ip_address_table, addr_type);
+    count = master_create_slave_list(results, slave_ip_address_table, ip_table_sz, addr_type);
 
     mdns_query_results_free(results);
     return count;
 }
 #endif
 
+static void master_destroy_slave_list(char** table, size_t ip_table_size)
+{
+#if CONFIG_MB_MDNS_IP_RESOLVER
+    slave_addr_entry_t *it;
+    LIST_FOREACH(it, &slave_addr_list, entries) {
+        LIST_REMOVE(it, entries);
+        free(it);
+    }
+#endif
+    for (int i = 0; ((i < ip_table_size) && table[i] != NULL); i++) {
+        if (table[i]) {
+#if CONFIG_MB_SLAVE_IP_FROM_STDIN
+            free(table[i]);
+            table[i] = "FROM_STDIN";
+#elif CONFIG_MB_MDNS_IP_RESOLVER
+            table[i] = NULL;
+#endif
+        }
+    }
+}
+
 // The function to get pointer to parameter storage (instance) according to parameter description table
 static void* master_get_param_data(const mb_parameter_descriptor_t* param_descriptor)
 {
@@ -415,7 +463,7 @@ static void* master_get_param_data(const mb_parameter_descriptor_t* param_descri
                break;
        }
     } else {
-        ESP_LOGE(MASTER_TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid);
+        ESP_LOGE(TAG, "Wrong parameter offset for CID #%d", param_descriptor->cid);
         assert(instance_ptr != NULL);
     }
     return instance_ptr;
@@ -429,7 +477,7 @@ static void master_operation_func(void *arg)
     bool alarm_state = false;
     const mb_parameter_descriptor_t* param_descriptor = NULL;
 
-    ESP_LOGI(MASTER_TAG, "Start modbus test...");
+    ESP_LOGI(TAG, "Start modbus test...");
 
     for(uint16_t retry = 0; retry <= MASTER_MAX_RETRY && (!alarm_state); retry++) {
         // Read all found characteristics from slave(s)
@@ -449,7 +497,7 @@ static void master_operation_func(void *arg)
                     *(float*)temp_data_ptr = value;
                     if ((param_descriptor->mb_param_type == MB_PARAM_HOLDING) ||
                         (param_descriptor->mb_param_type == MB_PARAM_INPUT)) {
-                        ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.",
+                        ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.",
                                         param_descriptor->cid,
                                         (char*)param_descriptor->param_key,
                                         (char*)param_descriptor->param_units,
@@ -463,7 +511,7 @@ static void master_operation_func(void *arg)
                     } else {
                         uint16_t state = *(uint16_t*)temp_data_ptr;
                         const char* rw_str = (state & param_descriptor->param_opts.opt1) ? "ON" : "OFF";
-                        ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.",
+                        ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %s (0x%x) read successful.",
                                         param_descriptor->cid,
                                         (char*)param_descriptor->param_key,
                                         (char*)param_descriptor->param_units,
@@ -475,7 +523,7 @@ static void master_operation_func(void *arg)
                         }
                     }
                 } else {
-                    ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = %d (%s).",
+                    ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = %d (%s).",
                                         param_descriptor->cid,
                                         (char*)param_descriptor->param_key,
                                         (int)err,
@@ -488,13 +536,13 @@ static void master_operation_func(void *arg)
     }
 
     if (alarm_state) {
-        ESP_LOGI(MASTER_TAG, "Alarm triggered by cid #%d.",
+        ESP_LOGI(TAG, "Alarm triggered by cid #%d.",
                                         param_descriptor->cid);
     } else {
-        ESP_LOGE(MASTER_TAG, "Alarm is not triggered after %d retries.",
+        ESP_LOGE(TAG, "Alarm is not triggered after %d retries.",
                                         MASTER_MAX_RETRY);
     }
-    ESP_LOGI(MASTER_TAG, "Destroy master...");
+    ESP_LOGI(TAG, "Destroy master...");
     vTaskDelay(100);
 }
 
@@ -505,18 +553,18 @@ static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type)
       ESP_ERROR_CHECK(nvs_flash_erase());
       result = nvs_flash_init();
     }
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                            MASTER_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "nvs_flash_init fail, returns(0x%x).",
                             (uint32_t)result);
     result = esp_netif_init();
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                            MASTER_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "esp_netif_init fail, returns(0x%x).",
                             (uint32_t)result);
     result = esp_event_loop_create_default();
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                            MASTER_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "esp_event_loop_create_default fail, returns(0x%x).",
                             (uint32_t)result);
 #if CONFIG_MB_MDNS_IP_RESOLVER
@@ -527,14 +575,14 @@ static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type)
     // Read "Establishing Wi-Fi or Ethernet Connection" section in
     // examples/protocols/README.md for more information about this function.
     result = example_connect();
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                                MASTER_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "example_connect fail, returns(0x%x).",
                                 (uint32_t)result);
 #if CONFIG_EXAMPLE_CONNECT_WIFI
    result = esp_wifi_set_ps(WIFI_PS_NONE);
-   ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                                   MASTER_TAG,
+   MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                                   TAG,
                                    "esp_wifi_set_ps fail, returns(0x%x).",
                                    (uint32_t)result);
 #endif
@@ -544,17 +592,17 @@ static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type)
         res = master_query_slave_service("_modbus", "_tcp", ip_addr_type);
     }
     if (res < num_device_parameters) {
-        ESP_LOGE(MASTER_TAG, "Could not resolve one or more slave IP addresses, resolved: %d out of %d.", res, num_device_parameters );
-        ESP_LOGE(MASTER_TAG, "Make sure you configured all slaves according to device parameter table and they alive in the network.");
+        ESP_LOGE(TAG, "Could not resolve one or more slave IP addresses, resolved: %d out of %d.", res, num_device_parameters );
+        ESP_LOGE(TAG, "Make sure you configured all slaves according to device parameter table and they alive in the network.");
         return ESP_ERR_NOT_FOUND;
     }
     mdns_free();
 #elif CONFIG_MB_SLAVE_IP_FROM_STDIN
     int ip_cnt = master_get_slave_ip_stdin(slave_ip_address_table);
     if (ip_cnt) {
-        ESP_LOGI(MASTER_TAG, "Configured %d IP addresse(s).", ip_cnt);
+        ESP_LOGI(TAG, "Configured %d IP addresse(s).", ip_cnt);
     } else {
-        ESP_LOGE(MASTER_TAG, "Fail to get IP address from stdin. Continue.");
+        ESP_LOGE(TAG, "Fail to get IP address from stdin. Continue.");
         return ESP_ERR_NOT_FOUND;
     }
 #endif
@@ -564,27 +612,26 @@ static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type)
 static esp_err_t destroy_services(void)
 {
     esp_err_t err = ESP_OK;
-#if CONFIG_MB_MDNS_IP_RESOLVER
-    master_destroy_slave_list(slave_ip_address_table);
-#endif
+    master_destroy_slave_list(slave_ip_address_table, ip_table_sz);
+
     err = example_disconnect();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                   MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                   TAG,
                                    "example_disconnect fail, returns(0x%x).",
                                    (uint32_t)err);
     err = esp_event_loop_delete_default();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                       MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                       TAG,
                                        "esp_event_loop_delete_default fail, returns(0x%x).",
                                        (uint32_t)err);
     err = esp_netif_deinit();
-    ESP_RETURN_ON_FALSE((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE,
-                                        MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE,
+                                        TAG,
                                         "esp_netif_deinit fail, returns(0x%x).",
                                         (uint32_t)err);
     err = nvs_flash_deinit();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "nvs_flash_deinit fail, returns(0x%x).",
                                 (uint32_t)err);
     return err;
@@ -596,30 +643,30 @@ static esp_err_t master_init(mb_communication_info_t* comm_info)
     void* master_handler = NULL;
 
     esp_err_t err = mbc_master_init_tcp(&master_handler);
-    ESP_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE,
-                                MASTER_TAG,
+    MB_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "mb controller initialization fail.");
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                            MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "mb controller initialization fail, returns(0x%x).",
                             (uint32_t)err);
 
     err = mbc_master_setup((void*)comm_info);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                            MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "mb controller setup fail, returns(0x%x).",
                             (uint32_t)err);
 
     err = mbc_master_set_descriptor(&device_parameters[0], num_device_parameters);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "mb controller set descriptor fail, returns(0x%x).",
                                 (uint32_t)err);
-    ESP_LOGI(MASTER_TAG, "Modbus master stack initialized...");
+    ESP_LOGI(TAG, "Modbus master stack initialized...");
 
     err = mbc_master_start();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                            MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "mb controller start fail, returns(0x%x).",
                             (uint32_t)err);
     vTaskDelay(5);
@@ -629,11 +676,11 @@ static esp_err_t master_init(mb_communication_info_t* comm_info)
 static esp_err_t master_destroy(void)
 {
     esp_err_t err = mbc_master_destroy();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                MASTER_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "mbc_master_destroy fail, returns(0x%x).",
                                 (uint32_t)err);
-    ESP_LOGI(MASTER_TAG, "Modbus master stack destroy...");
+    ESP_LOGI(TAG, "Modbus master stack destroy...");
     return err;
 }
 

+ 1 - 1
examples/protocols/modbus/tcp/mb_tcp_slave/main/Kconfig.projbuild

@@ -2,7 +2,7 @@ menu "Modbus Example Configuration"
 
     config MB_SLAVE_ADDR
         int "Modbus slave address"
-        range 1 127
+        range 1 255
         default 1
         help
             This is the Modbus slave address in the network.

+ 54 - 53
examples/protocols/modbus/tcp/mb_tcp_slave/main/tcp_slave.c

@@ -1,14 +1,15 @@
-/* FreeModbus Slave Example ESP32
+/*
+ * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// FreeModbus Slave Example ESP32
 
-   Unless required by applicable law or agreed to in writing, this
-   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-   CONDITIONS OF ANY KIND, either express or implied.
-*/
 #include <stdio.h>
 #include "esp_err.h"
 #include "sdkconfig.h"
 #include "esp_log.h"
-#include "esp_check.h"
 #include "esp_system.h"
 #include "esp_wifi.h"
 #include "esp_event.h"
@@ -47,7 +48,7 @@
                                                 | MB_EVENT_COILS_WR)
 #define MB_READ_WRITE_MASK                  (MB_READ_MASK | MB_WRITE_MASK)
 
-#define SLAVE_TAG "SLAVE_TEST"
+static const char *TAG = "SLAVE_TEST";
 
 static portMUX_TYPE param_lock = portMUX_INITIALIZER_UNLOCKED;
 
@@ -161,8 +162,8 @@ static void slave_operation_func(void *arg)
 {
     mb_param_info_t reg_info; // keeps the Modbus registers access information
 
-    ESP_LOGI(SLAVE_TAG, "Modbus slave stack initialized.");
-    ESP_LOGI(SLAVE_TAG, "Start modbus test...");
+    ESP_LOGI(TAG, "Modbus slave stack initialized.");
+    ESP_LOGI(TAG, "Start modbus test...");
     // The cycle below will be terminated when parameter holding_data0
     // incremented each access cycle reaches the CHAN_DATA_MAX_VAL value.
     for(;holding_reg_params.holding_data0 < MB_CHAN_DATA_MAX_VAL;) {
@@ -173,7 +174,7 @@ static void slave_operation_func(void *arg)
         if(event & (MB_EVENT_HOLDING_REG_WR | MB_EVENT_HOLDING_REG_RD)) {
             // Get parameter information from parameter queue
             ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, MB_PAR_INFO_GET_TOUT));
-            ESP_LOGI(SLAVE_TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
+            ESP_LOGI(TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
                     rw_str,
                     (uint32_t)reg_info.time_stamp,
                     (uint32_t)reg_info.mb_offset,
@@ -191,7 +192,7 @@ static void slave_operation_func(void *arg)
             }
         } else if (event & MB_EVENT_INPUT_REG_RD) {
             ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, MB_PAR_INFO_GET_TOUT));
-            ESP_LOGI(SLAVE_TAG, "INPUT READ (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
+            ESP_LOGI(TAG, "INPUT READ (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
                     (uint32_t)reg_info.time_stamp,
                     (uint32_t)reg_info.mb_offset,
                     (uint32_t)reg_info.type,
@@ -199,7 +200,7 @@ static void slave_operation_func(void *arg)
                     (uint32_t)reg_info.size);
         } else if (event & MB_EVENT_DISCRETE_RD) {
             ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, MB_PAR_INFO_GET_TOUT));
-            ESP_LOGI(SLAVE_TAG, "DISCRETE READ (%u us): ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
+            ESP_LOGI(TAG, "DISCRETE READ (%u us): ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
                                 (uint32_t)reg_info.time_stamp,
                                 (uint32_t)reg_info.mb_offset,
                                 (uint32_t)reg_info.type,
@@ -207,7 +208,7 @@ static void slave_operation_func(void *arg)
                                 (uint32_t)reg_info.size);
         } else if (event & (MB_EVENT_COILS_RD | MB_EVENT_COILS_WR)) {
             ESP_ERROR_CHECK(mbc_slave_get_param_info(&reg_info, MB_PAR_INFO_GET_TOUT));
-            ESP_LOGI(SLAVE_TAG, "COILS %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
+            ESP_LOGI(TAG, "COILS %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
                                 rw_str,
                                 (uint32_t)reg_info.time_stamp,
                                 (uint32_t)reg_info.mb_offset,
@@ -218,7 +219,7 @@ static void slave_operation_func(void *arg)
         }
     }
     // Destroy of Modbus controller on alarm
-    ESP_LOGI(SLAVE_TAG,"Modbus controller destroyed.");
+    ESP_LOGI(TAG,"Modbus controller destroyed.");
     vTaskDelay(100);
 }
 
@@ -229,18 +230,18 @@ static esp_err_t init_services(void)
       ESP_ERROR_CHECK(nvs_flash_erase());
       result = nvs_flash_init();
     }
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                            SLAVE_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "nvs_flash_init fail, returns(0x%x).",
                             (uint32_t)result);
     result = esp_netif_init();
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                            SLAVE_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "esp_netif_init fail, returns(0x%x).",
                             (uint32_t)result);
     result = esp_event_loop_create_default();
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                            SLAVE_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                            TAG,
                             "esp_event_loop_create_default fail, returns(0x%x).",
                             (uint32_t)result);
 #if CONFIG_MB_MDNS_IP_RESOLVER
@@ -251,14 +252,14 @@ static esp_err_t init_services(void)
     // Read "Establishing Wi-Fi or Ethernet Connection" section in
     // examples/protocols/README.md for more information about this function.
     result = example_connect();
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                                SLAVE_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "example_connect fail, returns(0x%x).",
                                 (uint32_t)result);
 #if CONFIG_EXAMPLE_CONNECT_WIFI
     result = esp_wifi_set_ps(WIFI_PS_NONE);
-    ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
-                                   SLAVE_TAG,
+    MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
+                                   TAG,
                                    "esp_wifi_set_ps fail, returns(0x%x).",
                                    (uint32_t)result);
 #endif
@@ -270,23 +271,23 @@ static esp_err_t destroy_services(void)
     esp_err_t err = ESP_OK;
 
     err = example_disconnect();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                   SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                   TAG,
                                    "example_disconnect fail, returns(0x%x).",
                                    (uint32_t)err);
     err = esp_event_loop_delete_default();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                       SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                       TAG,
                                        "esp_event_loop_delete_default fail, returns(0x%x).",
                                        (uint32_t)err);
     err = esp_netif_deinit();
-    ESP_RETURN_ON_FALSE((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE,
-                                        SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE,
+                                        TAG,
                                         "esp_netif_deinit fail, returns(0x%x).",
                                         (uint32_t)err);
     err = nvs_flash_deinit();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "nvs_flash_deinit fail, returns(0x%x).",
                                 (uint32_t)err);
 #if CONFIG_MB_MDNS_IP_RESOLVER
@@ -304,8 +305,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
 
     // Initialization of Modbus controller
     esp_err_t err = mbc_slave_init_tcp(&slave_handler);
-    ESP_RETURN_ON_FALSE((err == ESP_OK && slave_handler != NULL), ESP_ERR_INVALID_STATE,
-                                SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK && slave_handler != NULL), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "mb controller initialization fail.");
 
     comm_info->ip_addr = NULL; // Bind to any address
@@ -313,8 +314,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
 
     // Setup communication parameters and start stack
     err = mbc_slave_setup((void*)comm_info);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                        SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                        TAG,
                                         "mbc_slave_setup fail, returns(0x%x).",
                                         (uint32_t)err);
 
@@ -329,8 +330,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
     reg_area.address = (void*)&holding_reg_params.holding_data0; // Set pointer to storage instance
     reg_area.size = sizeof(float) << 2; // Set the size of register storage instance
     err = mbc_slave_set_descriptor(reg_area);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                    SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                    TAG,
                                     "mbc_slave_set_descriptor fail, returns(0x%x).",
                                     (uint32_t)err);
 
@@ -339,8 +340,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
     reg_area.address = (void*)&holding_reg_params.holding_data4; // Set pointer to storage instance
     reg_area.size = sizeof(float) << 2; // Set the size of register storage instance
     err = mbc_slave_set_descriptor(reg_area);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                    SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                    TAG,
                                     "mbc_slave_set_descriptor fail, returns(0x%x).",
                                     (uint32_t)err);
 
@@ -350,8 +351,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
     reg_area.address = (void*)&input_reg_params.input_data0;
     reg_area.size = sizeof(float) << 2;
     err = mbc_slave_set_descriptor(reg_area);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                        SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                        TAG,
                                         "mbc_slave_set_descriptor fail, returns(0x%x).",
                                         (uint32_t)err);
     reg_area.type = MB_PARAM_INPUT;
@@ -359,8 +360,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
     reg_area.address = (void*)&input_reg_params.input_data4;
     reg_area.size = sizeof(float) << 2;
     err = mbc_slave_set_descriptor(reg_area);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                        SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                        TAG,
                                         "mbc_slave_set_descriptor fail, returns(0x%x).",
                                         (uint32_t)err);
 
@@ -370,8 +371,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
     reg_area.address = (void*)&coil_reg_params;
     reg_area.size = sizeof(coil_reg_params);
     err = mbc_slave_set_descriptor(reg_area);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                    SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                    TAG,
                                     "mbc_slave_set_descriptor fail, returns(0x%x).",
                                     (uint32_t)err);
 
@@ -381,8 +382,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
     reg_area.address = (void*)&discrete_reg_params;
     reg_area.size = sizeof(discrete_reg_params);
     err = mbc_slave_set_descriptor(reg_area);
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                    SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                    TAG,
                                     "mbc_slave_set_descriptor fail, returns(0x%x).",
                                     (uint32_t)err);
 
@@ -391,8 +392,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
 
     // Starts of modbus controller and stack
     err = mbc_slave_start();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                        SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                        TAG,
                                         "mbc_slave_start fail, returns(0x%x).",
                                         (uint32_t)err);
     vTaskDelay(5);
@@ -402,8 +403,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
 static esp_err_t slave_destroy(void)
 {
     esp_err_t err = mbc_slave_destroy();
-    ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
-                                SLAVE_TAG,
+    MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
+                                TAG,
                                 "mbc_slave_destroy fail, returns(0x%x).",
                                 (uint32_t)err);
     return err;
@@ -418,7 +419,7 @@ void app_main(void)
     ESP_ERROR_CHECK(init_services());
 
     // Set UART log level
-    esp_log_level_set(SLAVE_TAG, ESP_LOG_INFO);
+    esp_log_level_set(TAG, ESP_LOG_INFO);
 
     mb_communication_info_t comm_info = { 0 };