mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-28 04:05:39 +00:00
freemodbus: allow address gaps in master data dictionary (support of UID field in MBAP) (backport v4.3)
This commit is contained in:
committed by
Jiang Jiang Jian
parent
5bad27d0d5
commit
073da59d27
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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(®_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(®_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(®_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(®_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());
|
||||
}
|
||||
|
||||
@@ -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_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.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))
|
||||
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))
|
||||
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:
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "string.h"
|
||||
// FreeModbus Master Example ESP32
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/queue.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
@@ -44,14 +47,6 @@
|
||||
#define POLL_TIMEOUT_TICS (POLL_TIMEOUT_MS / portTICK_RATE_MS)
|
||||
#define MB_MDNS_PORT (502)
|
||||
|
||||
#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))
|
||||
@@ -76,12 +71,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)
|
||||
@@ -114,11 +111,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 },
|
||||
@@ -127,20 +124,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
|
||||
@@ -191,8 +194,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;
|
||||
}
|
||||
@@ -204,10 +207,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;
|
||||
}
|
||||
}
|
||||
@@ -217,6 +220,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)
|
||||
{
|
||||
@@ -240,7 +253,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_")));
|
||||
@@ -281,15 +294,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;
|
||||
@@ -298,7 +317,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);
|
||||
@@ -309,92 +328,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)
|
||||
{
|
||||
@@ -420,7 +471,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;
|
||||
@@ -434,7 +485,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)
|
||||
@@ -454,7 +505,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,
|
||||
@@ -468,7 +519,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,
|
||||
@@ -480,7 +531,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,
|
||||
@@ -493,13 +544,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);
|
||||
}
|
||||
|
||||
@@ -510,15 +561,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();
|
||||
}
|
||||
MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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
|
||||
@@ -529,12 +583,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();
|
||||
MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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);
|
||||
MASTER_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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 +600,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,23 +620,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();
|
||||
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
MASTER_CHECK((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"nvs_flash_deinit fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
return err;
|
||||
@@ -592,25 +651,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);
|
||||
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_info);
|
||||
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);
|
||||
|
||||
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...");
|
||||
|
||||
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);
|
||||
vTaskDelay(5);
|
||||
@@ -620,10 +684,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();
|
||||
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
@@ -47,13 +46,7 @@
|
||||
| MB_EVENT_COILS_WR)
|
||||
#define MB_READ_WRITE_MASK (MB_READ_MASK | MB_WRITE_MASK)
|
||||
|
||||
#define SLAVE_TAG "SLAVE_TEST"
|
||||
|
||||
#define SLAVE_CHECK(a, ret_val, str, ...) \
|
||||
if (!(a)) { \
|
||||
ESP_LOGE(SLAVE_TAG, "%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
return (ret_val); \
|
||||
}
|
||||
static const char *TAG = "SLAVE_TEST";
|
||||
|
||||
static portMUX_TYPE param_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
@@ -167,8 +160,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;) {
|
||||
@@ -179,7 +172,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(®_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,
|
||||
@@ -197,7 +190,7 @@ static void slave_operation_func(void *arg)
|
||||
}
|
||||
} else if (event & MB_EVENT_INPUT_REG_RD) {
|
||||
ESP_ERROR_CHECK(mbc_slave_get_param_info(®_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,
|
||||
@@ -205,7 +198,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(®_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,
|
||||
@@ -213,7 +206,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(®_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,
|
||||
@@ -224,7 +217,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);
|
||||
}
|
||||
|
||||
@@ -235,15 +228,18 @@ static esp_err_t init_services(void)
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
result = nvs_flash_init();
|
||||
}
|
||||
SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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
|
||||
@@ -254,12 +250,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();
|
||||
SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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);
|
||||
SLAVE_CHECK((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((result == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"esp_wifi_set_ps fail, returns(0x%x).",
|
||||
(uint32_t)result);
|
||||
#endif
|
||||
@@ -271,19 +269,23 @@ static esp_err_t destroy_services(void)
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
err = example_disconnect();
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
SLAVE_CHECK((err == ESP_OK || err == ESP_ERR_NOT_SUPPORTED), ESP_ERR_INVALID_STATE,
|
||||
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();
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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
|
||||
@@ -301,7 +303,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);
|
||||
SLAVE_CHECK((err == ESP_OK && slave_handler != NULL), ESP_ERR_INVALID_STATE,
|
||||
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
|
||||
@@ -309,7 +312,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);
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"mbc_slave_setup fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
|
||||
@@ -324,7 +328,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);
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"mbc_slave_set_descriptor fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
|
||||
@@ -333,7 +338,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);
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"mbc_slave_set_descriptor fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
|
||||
@@ -343,7 +349,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);
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
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;
|
||||
@@ -351,7 +358,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);
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"mbc_slave_set_descriptor fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
|
||||
@@ -361,7 +369,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);
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"mbc_slave_set_descriptor fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
|
||||
@@ -371,7 +380,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);
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"mbc_slave_set_descriptor fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
|
||||
@@ -380,7 +390,8 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
|
||||
|
||||
// Starts of modbus controller and stack
|
||||
err = mbc_slave_start();
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"mbc_slave_start fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
vTaskDelay(5);
|
||||
@@ -390,7 +401,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();
|
||||
SLAVE_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||
TAG,
|
||||
"mbc_slave_destroy fail, returns(0x%x).",
|
||||
(uint32_t)err);
|
||||
return err;
|
||||
@@ -405,7 +417,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 };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user