Merge branch 'bugfix/modbus_fix_stack_reinitialization_sequence' into 'master'

freemodbus: fix TCP stack/examples reinitialization sequence

Closes IDFGH-4432

See merge request espressif/esp-idf!12123
This commit is contained in:
Alex Lisitsyn
2021-09-17 11:13:57 +00:00
6 changed files with 411 additions and 173 deletions

View File

@@ -14,6 +14,7 @@
#include "string.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
@@ -46,12 +47,6 @@
#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))
@@ -365,6 +360,7 @@ 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;
}
}
}
@@ -500,48 +496,52 @@ static void master_operation_func(void *arg)
}
ESP_LOGI(MASTER_TAG, "Destroy master...");
vTaskDelay(100);
ESP_ERROR_CHECK(mbc_master_destroy());
}
// Modbus master initialization
static esp_err_t master_init(void)
static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type)
{
esp_err_t result = nvs_flash_init();
if (result == ESP_ERR_NVS_NO_FREE_PAGES || result == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
result = nvs_flash_init();
}
ESP_ERROR_CHECK(result);
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
MASTER_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,
"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,
"esp_event_loop_create_default fail, returns(0x%x).",
(uint32_t)result);
#if CONFIG_MB_MDNS_IP_RESOLVER
// Start mdns service and register device
master_start_mdns_service();
#endif
// This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
// Read "Establishing Wi-Fi or Ethernet Connection" section in
// examples/protocols/README.md for more information about this function.
ESP_ERROR_CHECK(example_connect());
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
mb_communication_info_t comm_info = { 0 };
comm_info.ip_port = MB_TCP_PORT;
#if !CONFIG_EXAMPLE_CONNECT_IPV6
comm_info.ip_addr_type = MB_IPV4;
#else
comm_info.ip_addr_type = MB_IPV6;
result = example_connect();
ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
MASTER_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,
"esp_wifi_set_ps fail, returns(0x%x).",
(uint32_t)result);
#endif
comm_info.ip_mode = MB_MODE_TCP;
comm_info.ip_addr = (void*)slave_ip_address_table;
comm_info.ip_netif_ptr = (void*)get_example_netif();
#if CONFIG_MB_MDNS_IP_RESOLVER
int res = 0;
for (int retry = 0; (res < num_device_parameters) && (retry < 10); retry++) {
res = master_query_slave_service("_modbus", "_tcp", comm_info.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 );
@@ -555,46 +555,109 @@ static esp_err_t master_init(void)
ESP_LOGI(MASTER_TAG, "Configured %d IP addresse(s).", ip_cnt);
} else {
ESP_LOGE(MASTER_TAG, "Fail to get IP address from stdin. Continue.");
return ESP_ERR_NOT_FOUND;
}
#endif
return ESP_OK;
}
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
err = example_disconnect();
ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
MASTER_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,
"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,
"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,
"nvs_flash_deinit fail, returns(0x%x).",
(uint32_t)err);
return err;
}
// Modbus master initialization
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);
MASTER_CHECK((master_handler != NULL), ESP_ERR_INVALID_STATE,
ESP_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE,
MASTER_TAG,
"mb controller initialization fail.");
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
MASTER_TAG,
"mb controller initialization fail, returns(0x%x).",
(uint32_t)err);
err = mbc_master_setup((void*)&comm_info);
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
err = mbc_master_setup((void*)comm_info);
ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
MASTER_TAG,
"mb controller setup fail, returns(0x%x).",
(uint32_t)err);
err = mbc_master_set_descriptor(&device_parameters[0], num_device_parameters);
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
MASTER_TAG,
"mb controller set descriptor fail, returns(0x%x).",
(uint32_t)err);
ESP_LOGI(MASTER_TAG, "Modbus master stack initialized...");
err = mbc_master_start();
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
MASTER_TAG,
"mb controller start fail, returns(0x%x).",
(uint32_t)err);
vTaskDelay(5);
return err;
}
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,
"mbc_master_destroy fail, returns(0x%x).",
(uint32_t)err);
ESP_LOGI(MASTER_TAG, "Modbus master stack destroy...");
return err;
}
void app_main(void)
{
// Initialization of device peripheral and objects
ESP_ERROR_CHECK(master_init());
vTaskDelay(10);
mb_tcp_addr_type_t ip_addr_type;
#if !CONFIG_EXAMPLE_CONNECT_IPV6
ip_addr_type = MB_IPV4;
#else
ip_addr_type = MB_IPV6;
#endif
ESP_ERROR_CHECK(init_services(ip_addr_type));
mb_communication_info_t comm_info = { 0 };
comm_info.ip_port = MB_TCP_PORT;
comm_info.ip_addr_type = ip_addr_type;
comm_info.ip_mode = MB_MODE_TCP;
comm_info.ip_addr = (void*)slave_ip_address_table;
comm_info.ip_netif_ptr = (void*)get_example_netif();
ESP_ERROR_CHECK(master_init(&comm_info));
vTaskDelay(50);
master_operation_func(NULL);
#if CONFIG_MB_MDNS_IP_RESOLVER
master_destroy_slave_list(slave_ip_address_table);
#endif
ESP_ERROR_CHECK(master_destroy());
ESP_ERROR_CHECK(destroy_services());
}

View File

@@ -8,7 +8,7 @@
#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"
@@ -87,7 +87,7 @@ static inline char* gen_host_name_str(char* service_name, char* name)
return name;
}
static void start_mdns_service()
static void start_mdns_service(void)
{
char temp_str[32] = {0};
uint8_t sta_mac[6] = {0};
@@ -115,6 +115,11 @@ static void start_mdns_service()
ESP_ERROR_CHECK( mdns_service_txt_item_set("_modbus", "_tcp", "mb_id", gen_id_str("\0", temp_str)));
}
static void stop_mdns_service(void)
{
mdns_free();
}
#endif
// Set register values into known state
@@ -152,104 +157,9 @@ static void setup_reg_data(void)
input_reg_params.input_data7 = 4.78;
}
// An example application of Modbus slave. It is based on freemodbus stack.
// See deviceparams.h file for more information about assigned Modbus parameters.
// These parameters can be accessed from main application and also can be changed
// by external Modbus master host.
void app_main(void)
static void slave_operation_func(void *arg)
{
esp_err_t result = nvs_flash_init();
if (result == ESP_ERR_NVS_NO_FREE_PAGES || result == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
result = nvs_flash_init();
}
ESP_ERROR_CHECK(result);
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
#if CONFIG_MB_MDNS_IP_RESOLVER
start_mdns_service();
#endif
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
// Set UART log level
esp_log_level_set(SLAVE_TAG, ESP_LOG_INFO);
void* mbc_slave_handler = NULL;
ESP_ERROR_CHECK(mbc_slave_init_tcp(&mbc_slave_handler)); // Initialization of Modbus controller
mb_param_info_t reg_info; // keeps the Modbus registers access information
mb_register_area_descriptor_t reg_area; // Modbus register area descriptor structure
mb_communication_info_t comm_info = { 0 };
comm_info.ip_port = MB_TCP_PORT_NUMBER;
#if !CONFIG_EXAMPLE_CONNECT_IPV6
comm_info.ip_addr_type = MB_IPV4;
#else
comm_info.ip_addr_type = MB_IPV6;
#endif
comm_info.ip_mode = MB_MODE_TCP;
comm_info.ip_addr = NULL;
comm_info.ip_netif_ptr = (void*)get_example_netif();
// Setup communication parameters and start stack
ESP_ERROR_CHECK(mbc_slave_setup((void*)&comm_info));
// The code below initializes Modbus register area descriptors
// for Modbus Holding Registers, Input Registers, Coils and Discrete Inputs
// Initialization should be done for each supported Modbus register area according to register map.
// When external master trying to access the register in the area that is not initialized
// by mbc_slave_set_descriptor() API call then Modbus stack
// will send exception response for this register area.
reg_area.type = MB_PARAM_HOLDING; // Set type of register area
reg_area.start_offset = MB_REG_HOLDING_START_AREA0; // Offset of register area in Modbus protocol
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
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
reg_area.type = MB_PARAM_HOLDING; // Set type of register area
reg_area.start_offset = MB_REG_HOLDING_START_AREA1; // Offset of register area in Modbus protocol
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
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
// Initialization of Input Registers area
reg_area.type = MB_PARAM_INPUT;
reg_area.start_offset = MB_REG_INPUT_START_AREA0;
reg_area.address = (void*)&input_reg_params.input_data0;
reg_area.size = sizeof(float) << 2;
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
// Initialization of Input Registers area
reg_area.type = MB_PARAM_INPUT;
reg_area.start_offset = MB_REG_INPUT_START_AREA1;
reg_area.address = (void*)&input_reg_params.input_data4;
reg_area.size = sizeof(float) << 2;
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
// Initialization of Coils register area
reg_area.type = MB_PARAM_COIL;
reg_area.start_offset = MB_REG_COILS_START;
reg_area.address = (void*)&coil_reg_params;
reg_area.size = sizeof(coil_reg_params);
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
// Initialization of Discrete Inputs register area
reg_area.type = MB_PARAM_DISCRETE;
reg_area.start_offset = MB_REG_DISCRETE_INPUT_START;
reg_area.address = (void*)&discrete_reg_params;
reg_area.size = sizeof(discrete_reg_params);
ESP_ERROR_CHECK(mbc_slave_set_descriptor(reg_area));
setup_reg_data(); // Set values into known state
// Starts of modbus controller and stack
ESP_ERROR_CHECK(mbc_slave_start());
ESP_LOGI(SLAVE_TAG, "Modbus slave stack initialized.");
ESP_LOGI(SLAVE_TAG, "Start modbus test...");
@@ -310,8 +220,221 @@ void app_main(void)
// Destroy of Modbus controller on alarm
ESP_LOGI(SLAVE_TAG,"Modbus controller destroyed.");
vTaskDelay(100);
ESP_ERROR_CHECK(mbc_slave_destroy());
#if CONFIG_MB_MDNS_IP_RESOLVER
mdns_free();
#endif
}
static esp_err_t init_services(void)
{
esp_err_t result = nvs_flash_init();
if (result == ESP_ERR_NVS_NO_FREE_PAGES || result == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
result = nvs_flash_init();
}
ESP_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
SLAVE_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,
"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,
"esp_event_loop_create_default fail, returns(0x%x).",
(uint32_t)result);
#if CONFIG_MB_MDNS_IP_RESOLVER
// Start mdns service and register device
start_mdns_service();
#endif
// This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
// 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,
"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,
"esp_wifi_set_ps fail, returns(0x%x).",
(uint32_t)result);
#endif
return ESP_OK;
}
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,
"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,
"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,
"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,
"nvs_flash_deinit fail, returns(0x%x).",
(uint32_t)err);
#if CONFIG_MB_MDNS_IP_RESOLVER
stop_mdns_service();
#endif
return err;
}
// Modbus slave initialization
static esp_err_t slave_init(mb_communication_info_t* comm_info)
{
mb_register_area_descriptor_t reg_area; // Modbus register area descriptor structure
void* slave_handler = NULL;
// 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 controller initialization fail.");
comm_info->ip_addr = NULL; // Bind to any address
comm_info->ip_netif_ptr = (void*)get_example_netif();
// 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,
"mbc_slave_setup fail, returns(0x%x).",
(uint32_t)err);
// The code below initializes Modbus register area descriptors
// for Modbus Holding Registers, Input Registers, Coils and Discrete Inputs
// Initialization should be done for each supported Modbus register area according to register map.
// When external master trying to access the register in the area that is not initialized
// by mbc_slave_set_descriptor() API call then Modbus stack
// will send exception response for this register area.
reg_area.type = MB_PARAM_HOLDING; // Set type of register area
reg_area.start_offset = MB_REG_HOLDING_START_AREA0; // Offset of register area in Modbus protocol
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,
"mbc_slave_set_descriptor fail, returns(0x%x).",
(uint32_t)err);
reg_area.type = MB_PARAM_HOLDING; // Set type of register area
reg_area.start_offset = MB_REG_HOLDING_START_AREA1; // Offset of register area in Modbus protocol
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,
"mbc_slave_set_descriptor fail, returns(0x%x).",
(uint32_t)err);
// Initialization of Input Registers area
reg_area.type = MB_PARAM_INPUT;
reg_area.start_offset = MB_REG_INPUT_START_AREA0;
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,
"mbc_slave_set_descriptor fail, returns(0x%x).",
(uint32_t)err);
reg_area.type = MB_PARAM_INPUT;
reg_area.start_offset = MB_REG_INPUT_START_AREA1;
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,
"mbc_slave_set_descriptor fail, returns(0x%x).",
(uint32_t)err);
// Initialization of Coils register area
reg_area.type = MB_PARAM_COIL;
reg_area.start_offset = MB_REG_COILS_START;
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,
"mbc_slave_set_descriptor fail, returns(0x%x).",
(uint32_t)err);
// Initialization of Discrete Inputs register area
reg_area.type = MB_PARAM_DISCRETE;
reg_area.start_offset = MB_REG_DISCRETE_INPUT_START;
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,
"mbc_slave_set_descriptor fail, returns(0x%x).",
(uint32_t)err);
// Set values into known state
setup_reg_data();
// Starts of modbus controller and stack
err = mbc_slave_start();
ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
SLAVE_TAG,
"mbc_slave_start fail, returns(0x%x).",
(uint32_t)err);
vTaskDelay(5);
return err;
}
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,
"mbc_slave_destroy fail, returns(0x%x).",
(uint32_t)err);
return err;
}
// An example application of Modbus slave. It is based on freemodbus stack.
// See deviceparams.h file for more information about assigned Modbus parameters.
// These parameters can be accessed from main application and also can be changed
// by external Modbus master host.
void app_main(void)
{
ESP_ERROR_CHECK(init_services());
// Set UART log level
esp_log_level_set(SLAVE_TAG, ESP_LOG_INFO);
mb_communication_info_t comm_info = { 0 };
#if !CONFIG_EXAMPLE_CONNECT_IPV6
comm_info.ip_addr_type = MB_IPV4;
#else
comm_info.ip_addr_type = MB_IPV6;
#endif
comm_info.ip_mode = MB_MODE_TCP;
comm_info.ip_port = MB_TCP_PORT_NUMBER;
ESP_ERROR_CHECK(slave_init(&comm_info));
// The Modbus slave logic is located in this function (user handling of Modbus)
slave_operation_func(NULL);
ESP_ERROR_CHECK(slave_destroy());
ESP_ERROR_CHECK(destroy_services());
}