feature modbus tcp master slave v2

This commit is contained in:
Alex Lisitsyn
2024-09-02 03:12:36 +08:00
parent d4345f8cd7
commit 2e2be467f6
109 changed files with 4454 additions and 2319 deletions
+16 -7
View File
@@ -1,18 +1,27 @@
tcp/mb_tcp_master:
disable_test:
- if: IDF_TARGET != "esp32"
- if: IDF_TARGET != "esp32" or CONFIG_NAME == "dummy_config"
reason: only manual test is performed
disable:
# TCP port is not supported for now
- if: CONFIG_NAME == "wifi" or CONFIG_NAME == "ethernet"
# - if: CONFIG_NAME == "wifi" and SOC_WIFI_SUPPORTED != 1
- if: CONFIG_NAME == "wifi" and SOC_WIFI_SUPPORTED != 1
tcp/mb_tcp_slave:
disable_test:
- if: IDF_TARGET != "esp32"
- if: IDF_TARGET != "esp32" or CONFIG_NAME == "dummy_config"
reason: only manual test is performed
disable:
- if: CONFIG_NAME == "wifi" or CONFIG_NAME == "ethernet"
# - if: CONFIG_NAME == "wifi" and SOC_WIFI_SUPPORTED != 1
- if: CONFIG_NAME == "wifi" and SOC_WIFI_SUPPORTED != 1
serial/mb_serial_master:
disable_test:
- if: IDF_TARGET != "esp32" or CONFIG_NAME == "dummy_config"
reason: only manual test is performed
disable:
- if: CONFIG_NAME == "default" and SOC_WIFI_SUPPORTED != 1
serial/mb_serial_slave:
disable_test:
- if: IDF_TARGET != "esp32" or CONFIG_NAME == "dummy_config"
reason: only manual test is performed
+7 -1
View File
@@ -39,7 +39,7 @@ class ModbusTestDut(IdfDut):
TEST_IP_PROMPT = r'Waiting IP([0-9]{1,2}) from stdin:\r\r\n'
TEST_IP_SET_CONFIRM = r'.*IP\([0-9]+\) = \[([0-9a-zA-Z\.\:]+)\] set from stdin.*'
TEST_IP_ADDRESS_REGEXP = r'.*example_[a-z]+: .* IPv4 [a-z]+:.* ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*'
TEST_APP_NAME = r'.*Project name: ([_a-z]*)'
TEST_APP_NAME = r'I \([0-9]+\) [a-z_]+: Project name:\s+([_a-z]*)'
TEST_EXPECT_STR_TIMEOUT = 120
TEST_ACK_TIMEOUT = 60
@@ -294,6 +294,7 @@ def build_dir(app_path: str, target: Optional[str], config: Optional[str]) -> st
valid build directory
"""
check_dirs = []
if target is not None and config is not None:
check_dirs.append(f'build_{target}_{config}')
if target is not None:
@@ -312,8 +313,13 @@ def build_dir(app_path: str, target: Optional[str], config: Optional[str]) -> st
'checking binary path: %s... missing... try another place', binary_path
)
if config is not None and 'dummy' in config:
logging.warning('no build dir valid for application: %s, config: %s. Skip test.', binary_path, config)
return None
recommend_place = check_dirs[0]
logging.error(
f'no build dir valid. Please build the binary via "idf.py -B {recommend_place} build" and run pytest again'
)
sys.exit(1)
@@ -1,7 +1,7 @@
dependencies:
idf: ">=4.1"
espressif/esp-modbus:
version: "^2.0"
version: "^2.0.0-beta"
override_path: "../../../../"
mb_example_common:
path: "../../../mb_example_common"
@@ -44,8 +44,13 @@
#define TEST_INPUT_REG_START(field) (INPUT_OFFSET(field) >> 1)
#define TEST_INPUT_REG_SIZE(field) (sizeof(((input_reg_params_t *)0)->field) >> 1)
#define TEST_VALUE 12345 // default test value
#define TEST_ASCII_BIN 0xAAAAAAAA
#define TEST_VALUE (12345) // default test value
#define TEST_ASCII_BIN (0xAAAAAAAA)
#define TEST_ARR_REG_SZ (58)
#define TEST_HUMI_MIN (-40)
#define TEST_HUMI_MAX (50)
#define TEST_TEMP_MIN (0)
#define TEST_TEMP_MAX (100)
// 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 }
@@ -107,31 +112,31 @@ const mb_parameter_descriptor_t device_parameters[] = {
{ CID_INP_DATA_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_INPUT,
TEST_INPUT_REG_START(input_data0), TEST_INPUT_REG_SIZE(input_data0),
INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_TEMP_MIN, TEST_TEMP_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_DATA_0, STR("Humidity_1"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(holding_data0), TEST_HOLD_REG_SIZE(holding_data0),
HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_HUMI_MIN, TEST_HUMI_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_INP_DATA_1, STR("Temperature_1"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT,
TEST_INPUT_REG_START(input_data1), TEST_INPUT_REG_SIZE(input_data1),
INPUT_OFFSET(input_data1), PARAM_TYPE_FLOAT, 4,
OPTS( -40, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_TEMP_MIN, TEST_TEMP_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_DATA_1, STR("Humidity_2"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(holding_data1), TEST_HOLD_REG_SIZE(holding_data1),
HOLD_OFFSET(holding_data1), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_HUMI_MIN, TEST_HUMI_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_INP_DATA_2, STR("Temperature_2"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT,
TEST_INPUT_REG_START(input_data2), TEST_INPUT_REG_SIZE(input_data2),
INPUT_OFFSET(input_data2), PARAM_TYPE_FLOAT, 4,
OPTS( -40, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_TEMP_MIN, TEST_TEMP_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(holding_data2), TEST_HOLD_REG_SIZE(holding_data2),
HOLD_OFFSET(holding_data2), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_HUMI_MIN, TEST_HUMI_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_TEST_REG, STR("Test_regs"), STR("__"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(test_regs), 58,
HOLD_OFFSET(test_regs), PARAM_TYPE_ASCII, 116,
OPTS( 0, 100, TEST_ASCII_BIN ), PAR_PERMS_READ_WRITE_TRIGGER },
TEST_HOLD_REG_START(test_regs), TEST_ARR_REG_SZ,
HOLD_OFFSET(test_regs), PARAM_TYPE_ASCII, (TEST_ARR_REG_SZ * 2),
OPTS( TEST_TEMP_MIN, TEST_TEMP_MAX, TEST_ASCII_BIN ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_RELAY_P1, STR("RelayP1"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 2, 6,
COIL_OFFSET(coils_port0), PARAM_TYPE_U8, 1,
OPTS( 0xAA, 0x15, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
@@ -427,10 +432,9 @@ static void master_operation_func(void *arg)
}
if (alarm_state) {
ESP_LOGI(TAG, "Alarm triggered by cid #%d.",
(int)param_descriptor->cid);
ESP_LOGI(TAG, "Alarm triggered by cid #%u.", param_descriptor->cid);
} else {
ESP_LOGE(TAG, "Alarm is not triggered after %d retries.",
ESP_LOGE(TAG, "Alarm is not triggered after %u retries.",
MASTER_MAX_RETRY);
}
ESP_LOGI(TAG, "Destroy master...");
+3 -3
View File
@@ -3,9 +3,9 @@
# Modbus Slave Example
This example demonstrates using the port of the FreeModbus stack on an ESP32 target where the ESP32 target is operating as a network slave. The example allows an external Modbus host to read/write device parameters on the ESP32 target using the Modbus protocol. The parameters accessible through Modbus are located in `mb_example_common/modbus_params.h\c` source/header files that users can update to add/remove their own custom parameters.
This example demonstrates using the port of the esp-modbus stack on an ESP32 target where the ESP32 target is operating as a network slave. The example allows an external Modbus host to read/write device parameters on the ESP32 target using the Modbus protocol. The parameters accessible through Modbus are located in `mb_example_common/modbus_params.h\c` source/header files that users can update to add/remove their own custom parameters.
These are represented in structures `holding_reg_params`, `input_reg_params`, `coil_reg_params`, `discrete_reg_params` for holding registers, input parameters, coils and discrete inputs accordingly. The app_main application demonstrates how to setup Modbus stack and use notifications about parameters change from host system.
The FreeModbus stack located in `components/freemodbus` folder and contains the `/port` folder where the stack's port to the ESP32 is situated. There are some parameters of the port that can be configured in KConfig file to start stack correctly (See description below for more information).
The FreeModbus stack located in `modbus` folder and supports the ESP32 targets. There are some parameters of the port that can be configured in KConfig file to start stack correctly (See description below for more information).
The slave example uses shared parameter structures defined in `examples/protocols/modbus/mb_example_common` folder.
@@ -59,7 +59,7 @@ Note: Each target chip has different GPIO pins available for UART connection. Pl
Define the ```Modbus communiction mode``` for slave in Kconfig - CONFIG_MB_COMM_MODE (must be the same for master and slave application).
Set ```Modbus slave address``` for the example application (by default for example script is set to 1).
The communication parameters of freemodbus stack (Component config->Modbus configuration) allow to configure it appropriately but usually it is enough to use default settings.
The communication parameters of esp-modbus stack (Component config->Modbus configuration) allow to configure it appropriately but usually it is enough to use default settings.
See the help strings of parameters for more information.
### Setup external Modbus master software
@@ -98,7 +98,7 @@ menu "Modbus Example Configuration"
config MB_SLAVE_ADDR
int "Modbus slave address"
range 1 127
range 1 247
default 1
help
This is the Modbus slave address in the network.
@@ -1,7 +1,7 @@
dependencies:
idf: ">=4.1"
espressif/esp-modbus:
version: "^2.0"
version: "^2.0.0-beta"
override_path: "../../../../"
mb_example_common:
path: "../../../mb_example_common"
@@ -35,7 +35,7 @@
#define MB_PAR_INFO_GET_TOUT (10) // Timeout for get parameter info
#define MB_CHAN_DATA_MAX_VAL (6)
#define MB_CHAN_DATA_OFFSET (0.2f)
#define MB_CHAN_DATA_OFFSET (1.2f)
#define MB_READ_MASK (MB_EVENT_INPUT_REG_RD \
| MB_EVENT_HOLDING_REG_RD \
| MB_EVENT_DISCRETE_RD \
@@ -124,7 +124,7 @@ 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.
// An example application of Modbus slave. It is based on esp-modbus 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.
+6 -1
View File
@@ -63,4 +63,9 @@ def test_modbus_serial_communication(config: str, dut: Tuple[ModbusTestDut, Modb
dut_master.dut_test_start(dictionary=pattern_dict_master)
dut_slave.dut_check_errors()
dut_master.dut_check_errors()
dut_master.dut_check_errors()
@pytest.mark.multi_dut_modbus_generic
@pytest.mark.parametrize('config', ['dummy_config'])
def test_modbus_serial_generic() -> None:
print('The generic serial example tests are not provided yet.')
@@ -2,7 +2,7 @@ dependencies:
idf:
version: ">=4.1.0"
espressif/esp-modbus:
version: "^2.0"
version: "^2.0.0-beta"
override_path: "../../../../"
espressif/mdns:
version: "^1.0.0"
+42 -35
View File
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
// FreeModbus Master Example ESP32
// esp-modbus Master Example ESP32
#include <string.h>
#include <sys/queue.h>
@@ -30,7 +30,7 @@
#define MASTER_MAX_CIDS num_device_parameters
// Number of reading of parameters from slave
#define MASTER_MAX_RETRY (30)
#define MASTER_MAX_RETRY (10)
// Timeout to update cid over Modbus
#define UPDATE_CIDS_TIMEOUT_MS (500)
@@ -54,8 +54,13 @@
#define TEST_INPUT_REG_START(field) (INPUT_OFFSET(field) >> 1)
#define TEST_INPUT_REG_SIZE(field) (sizeof(((input_reg_params_t *)0)->field) >> 1)
#define TEST_VALUE 12345 // default test value
#define TEST_ASCII_BIN 0xAAAAAAAA
#define TEST_VALUE (12345) // default test value
#define TEST_ASCII_BIN (0xAAAAAAAA)
#define TEST_ARR_REG_SZ (58)
#define TEST_HUMI_MIN (-40)
#define TEST_HUMI_MAX (50)
#define TEST_TEMP_MIN (0)
#define TEST_TEMP_MAX (100)
// 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 }
@@ -84,8 +89,9 @@ static const char *TAG = "MASTER_TEST";
// 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 UID = 1
MB_DEVICE_ADDR2 = 200,
MB_DEVICE_ADDR3 = 35
MB_DEVICE_ADDR2,
MB_DEVICE_ADDR3,
MB_DEVICE_COUNT = 3
};
// Enumeration of all supported CIDs for device (used in parameter definition table)
@@ -135,31 +141,31 @@ const mb_parameter_descriptor_t device_parameters[] = {
{ CID_INP_DATA_0, STR("Data_channel_0"), STR("Volts"), MB_DEVICE_ADDR1, MB_PARAM_INPUT,
TEST_INPUT_REG_START(input_data0), TEST_INPUT_REG_SIZE(input_data0),
INPUT_OFFSET(input_data0), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_TEMP_MIN, TEST_TEMP_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_DATA_0, STR("Humidity_1"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(holding_data0), TEST_HOLD_REG_SIZE(holding_data0),
HOLD_OFFSET(holding_data0), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_HUMI_MIN, TEST_HUMI_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_INP_DATA_1, STR("Temperature_1"), STR("C"), MB_DEVICE_ADDR1, MB_PARAM_INPUT,
TEST_INPUT_REG_START(input_data1), TEST_INPUT_REG_SIZE(input_data1),
INPUT_OFFSET(input_data1), PARAM_TYPE_FLOAT, 4,
OPTS( -40, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_TEMP_MIN, TEST_TEMP_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_DATA_1, STR("Humidity_2"), STR("%rH"), MB_DEVICE_ADDR2, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(holding_data1), TEST_HOLD_REG_SIZE(holding_data1),
HOLD_OFFSET(holding_data1), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_HUMI_MIN, TEST_HUMI_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_INP_DATA_2, STR("Temperature_2"), STR("C"), MB_DEVICE_ADDR2, MB_PARAM_INPUT,
TEST_INPUT_REG_START(input_data2), TEST_INPUT_REG_SIZE(input_data2),
INPUT_OFFSET(input_data2), PARAM_TYPE_FLOAT, 4,
OPTS( -40, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_TEMP_MIN, TEST_TEMP_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR3, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(holding_data2), TEST_HOLD_REG_SIZE(holding_data2),
HOLD_OFFSET(holding_data2), PARAM_TYPE_FLOAT, 4,
OPTS( 0, 100, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
OPTS( TEST_HUMI_MIN, TEST_HUMI_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_TEST_REG, STR("Test_regs"), STR("__"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING,
TEST_HOLD_REG_START(test_regs), 58,
HOLD_OFFSET(test_regs), PARAM_TYPE_ASCII, 116,
OPTS( 0, 100, TEST_ASCII_BIN ), PAR_PERMS_READ_WRITE_TRIGGER },
TEST_HOLD_REG_START(test_regs), TEST_ARR_REG_SZ,
HOLD_OFFSET(test_regs), PARAM_TYPE_ASCII, (TEST_ARR_REG_SZ * 2),
OPTS( TEST_TEMP_MIN, TEST_TEMP_MAX, TEST_ASCII_BIN ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_RELAY_P1, STR("RelayP1"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 2, 6,
COIL_OFFSET(coils_port0), PARAM_TYPE_U8, 1,
OPTS( 0xAA, 0x15, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
@@ -244,17 +250,27 @@ static void* master_handle = NULL;
const size_t ip_table_sz;
#if CONFIG_MB_SLAVE_IP_FROM_STDIN
// 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[] = {
char* slave_ip_address_table[MB_DEVICE_COUNT + 1] = {
#if CONFIG_MB_SLAVE_IP_FROM_STDIN
"FROM_STDIN", // Address corresponds to MB_DEVICE_ADDR1 and set to predefined value by user
//"FROM_STDIN", // Corresponds to characteristic MB_DEVICE_ADDR2
//"FROM_STDIN", // Corresponds to characteristic MB_DEVICE_ADDR3
"FROM_STDIN", // Address corresponds to MB_DEVICE_ADDR2 and set to predefined value by user
"FROM_STDIN", // Address corresponds to MB_DEVICE_ADDR3 and set to predefined value by user
NULL // End of table condition (must be included)
#elif CONFIG_MB_MDNS_IP_RESOLVER
// This is workaround for the test to use the same slave for all CIDs and ignore UID setting in the slave
"01;mb_slave_tcp_01;1502",
"02;mb_slave_tcp_01;1502",
"03;mb_slave_tcp_01;1502",
NULL // End of table condition (must be included)
#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
char *master_scan_addr(int *index, char *buffer)
{
@@ -262,20 +278,21 @@ char *master_scan_addr(int *index, char *buffer)
int a[8] = {0};
int buf_cnt = 0;
#if !CONFIG_EXAMPLE_CONNECT_IPV6
buf_cnt = sscanf(buffer, "IP%d="IPSTR, index, &a[0], &a[1], &a[2], &a[3]);
buf_cnt = sscanf(buffer, "IP%d=" IPSTR, index, &a[0], &a[1], &a[2], &a[3]);
if (buf_cnt == 5) {
if (-1 == asprintf(&ip_str, IPSTR, a[0], a[1], a[2], a[3])) {
if (-1 == asprintf(&ip_str, "%02x;" IPSTR, (int)(*index + 1), a[0], a[1], a[2], a[3])) {
abort();
}
}
#else
buf_cnt = sscanf(buffer, "IP%d="IPV6STR, index, &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]);
if (buf_cnt == 9) {
if (-1 == asprintf(&ip_str, IPV6STR, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7])) {
if (-1 == asprintf(&ip_str, "%02x;" IPV6STR, (int)(*index + 1), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7])) {
abort();
}
}
#endif
printf("IP string: %s", ip_str);
return ip_str;
}
@@ -327,19 +344,8 @@ static int master_get_slave_ip_stdin(char **addr_table)
return ip_cnt;
}
#elif CONFIG_MB_MDNS_IP_RESOLVER
char *slave_ip_address_table[] = {
"01;mb_slave_tcp_01;502", // Corresponds to characteristic MB_DEVICE_ADDR1 "mb_slave_tcp_01"
// "200;mb_slave_tcp_c8;1502", // Corresponds to characteristic MB_DEVICE_ADDR2 "mb_slave_tcp_C8"
// "35;mb_slave_tcp_23;1502",
NULL // End of table condition (must be included)
};
#endif
const size_t ip_table_sz = (size_t)(sizeof(slave_ip_address_table) / sizeof(slave_ip_address_table[0]));
static void master_destroy_slave_list(char **table, size_t ip_table_size)
{
for (int i = 0; ((i < ip_table_size) && table[i] != NULL); i++) {
@@ -572,7 +578,7 @@ static void master_operation_func(void *arg)
MASTER_MAX_RETRY);
}
ESP_LOGI(TAG, "Destroy master...");
vTaskDelay(100);
vTaskDelay(1);
}
static esp_err_t init_services(mb_tcp_addr_type_t ip_addr_type)
@@ -709,6 +715,7 @@ void app_main(void)
.tcp_opts.uid = 0,
.tcp_opts.start_disconnected = false,
.tcp_opts.response_tout_ms = CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND,
.tcp_opts.ip_netif_ptr = (void*)get_example_netif()
};
ESP_ERROR_CHECK(master_init(&tcp_master_config));
@@ -2,7 +2,7 @@
# Modbus configuration
#
CONFIG_FMB_COMM_MODE_TCP_EN=y
CONFIG_FMB_TCP_PORT_DEFAULT=502
CONFIG_FMB_TCP_PORT_DEFAULT=1502
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20
CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
CONFIG_FMB_PORT_TASK_PRIO=10
@@ -12,7 +12,6 @@ CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=300
CONFIG_FMB_TCP_UID_ENABLED=n
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
CONFIG_MB_MDNS_IP_RESOLVER=n
CONFIG_MB_SLAVE_IP_FROM_STDIN=y
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_FMB_EXT_TYPE_SUPPORT=y
+1 -2
View File
@@ -1,5 +1,5 @@
CONFIG_FMB_COMM_MODE_TCP_EN=y
CONFIG_FMB_TCP_PORT_DEFAULT=502
CONFIG_FMB_TCP_PORT_DEFAULT=1502
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20
CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
CONFIG_FMB_PORT_TASK_PRIO=10
@@ -9,7 +9,6 @@ CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=300
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_FMB_TCP_UID_ENABLED=n
CONFIG_MB_MDNS_IP_RESOLVER=n
CONFIG_MB_SLAVE_IP_FROM_STDIN=y
CONFIG_EXAMPLE_CONNECT_IPV6=n
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
@@ -2,7 +2,7 @@
# Modbus configuration
#
CONFIG_FMB_COMM_MODE_TCP_EN=y
CONFIG_FMB_TCP_PORT_DEFAULT=502
CONFIG_FMB_TCP_PORT_DEFAULT=1502
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20
CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
CONFIG_FMB_PORT_TASK_PRIO=10
@@ -11,7 +11,6 @@ CONFIG_FMB_COMM_MODE_ASCII_EN=n
CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=2000
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=300
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
CONFIG_MB_MDNS_IP_RESOLVER=n
CONFIG_FMB_TCP_UID_ENABLED=n
CONFIG_MB_SLAVE_IP_FROM_STDIN=y
CONFIG_FMB_EXT_TYPE_SUPPORT=y
+3 -4
View File
@@ -2,10 +2,9 @@
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
# Modbus Slave Example
This example demonstrates using of FreeModbus TCP slave stack port implementation for supported ESP32 target chips. The external Modbus host is able to read/write device parameters using Modbus protocol transport. The parameters accessible thorough Modbus are located in `mb_example_common/modbus_params.h\c` files and can be updated by user.
The stack located in `modbus` folder and includes support for ESP32 target chips. There are some parameters that can be configured in KConfig file to start stack correctly (See description below for more information). The external Modbus host is able to read/write device parameters using Modbus protocol transport. The parameters accessible thorough Modbus are located in `mb_example_common/modbus_params.h\c` files and can be updated by user.
These are represented in structures holding_reg_params, input_reg_params, coil_reg_params, discrete_reg_params for holding registers, input parameters, coils and discrete inputs accordingly. The app_main application demonstrates how to setup Modbus stack and use notifications about parameters change from host system.
The FreeModbus stack located in `components/freemodbus` folder and contain `/port` folder inside which contains FreeModbus stack port for ESP32 target chips. There are some parameters that can be configured in KConfig file to start stack correctly (See description below for more information).
The slave example uses shared parameter structures defined in ```examples/protocols/modbus/mb_example_common``` folder.
@@ -28,7 +27,7 @@ idf.py menuconfig
To configure the example to use Wi-Fi or Ethernet connection, open the project configuration menu and navigate to "Example Connection Configuration" menu. Select either "Wi-Fi" or "Ethernet" in the "Connect using" choice.
Follow the instructions in `examples/common_components/protocol_examples_common` for further configuration.
The communication parameters of freemodbus stack (Component config->Modbus configuration) allow to configure it appropriately but usually it is enough to use default settings.
The communication parameters of esp-modbus stack (Component config->Modbus configuration) allow to configure it appropriately but usually it is enough to use default settings.
See the help strings of parameters for more information.
### Setup external Modbus master software
@@ -9,11 +9,4 @@ menu "Modbus Example Configuration"
This is the Modbus slave address in the network.
The address is used as an index to resolve slave ip address.
config MB_MDNS_IP_RESOLVER
bool "Resolve slave addresses using mDNS service"
default y
help
This option allows to use mDNS service to resolve IP addresses of the Modbus slaves.
If the option is disabled the ip addresses of slaves are defined in static table.
endmenu
@@ -1,7 +1,7 @@
dependencies:
idf: ">=4.1"
espressif/esp-modbus:
version: "^2.0"
version: "^2.0.0-beta"
override_path: "../../../../"
espressif/mdns:
version: "^1.0.0"
+72 -95
View File
@@ -13,7 +13,6 @@
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "mdns.h"
#include "esp_netif.h"
@@ -28,7 +27,6 @@
#include "modbus_params.h" // for modbus parameters structures
#define MB_TCP_PORT_NUMBER (CONFIG_FMB_TCP_PORT_DEFAULT)
#define MB_MDNS_PORT (502)
// Defines below are used to define register start address for each type of Modbus registers
#define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) >> 1))
@@ -38,7 +36,11 @@
#define MB_REG_INPUT_START_AREA0 (INPUT_OFFSET(input_data0)) // register offset input area 0
#define MB_REG_INPUT_START_AREA1 (INPUT_OFFSET(input_data4)) // register offset input area 1
#define MB_REG_HOLDING_START_AREA0 (HOLD_OFFSET(holding_data0))
#define MB_REG_HOLDING_START_AREA0_SIZE ((size_t)((HOLD_OFFSET(holding_data4) - HOLD_OFFSET(holding_data0)) << 1))
#define MB_REG_HOLDING_START_AREA1 (HOLD_OFFSET(holding_data4))
#define MB_REG_HOLDING_START_AREA1_SIZE ((size_t)((HOLD_OFFSET(holding_area1_end) - HOLD_OFFSET(holding_data4)) << 1))
#define MB_REG_HOLDING_START_AREA2 (HOLD_OFFSET(holding_u8_a))
#define MB_REG_HOLDING_START_AREA2_SIZE ((size_t)((HOLD_OFFSET(holding_area2_end) - HOLD_OFFSET(holding_u8_a)) << 1))
#define MB_PAR_INFO_GET_TOUT (10) // Timeout for get parameter info
#define MB_CHAN_DATA_MAX_VAL (10)
@@ -51,82 +53,13 @@
#define MB_WRITE_MASK (MB_EVENT_HOLDING_REG_WR \
| MB_EVENT_COILS_WR)
#define MB_READ_WRITE_MASK (MB_READ_MASK | MB_WRITE_MASK)
#define MB_SLAVE_ADDR (CONFIG_MB_SLAVE_ADDR)
#define MB_TEST_VALUE (12345.0)
#define MB_SLAVE_ADDR (CONFIG_MB_SLAVE_ADDR)
static const char *TAG = "SLAVE_TEST";
static void *slave_handle = NULL;
#if CONFIG_MB_MDNS_IP_RESOLVER
#define MB_ID_BYTE0(id) ((uint8_t)(id))
#define MB_ID_BYTE1(id) ((uint8_t)(((uint16_t)(id) >> 8) & 0xFF))
#define MB_ID_BYTE2(id) ((uint8_t)(((uint32_t)(id) >> 16) & 0xFF))
#define MB_ID_BYTE3(id) ((uint8_t)(((uint32_t)(id) >> 24) & 0xFF))
#define MB_ID2STR(id) MB_ID_BYTE0(id), MB_ID_BYTE1(id), MB_ID_BYTE2(id), MB_ID_BYTE3(id)
#if CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT
#define MB_DEVICE_ID (uint32_t)CONFIG_FMB_CONTROLLER_SLAVE_ID
#endif
#define MB_MDNS_INSTANCE(pref) pref"mb_slave_tcp"
// convert mac from binary format to string
static inline char* gen_mac_str(const uint8_t* mac, char* pref, char* mac_str)
{
sprintf(mac_str, "%s%02X%02X%02X%02X%02X%02X", pref, MAC2STR(mac));
return mac_str;
}
static inline char* gen_id_str(char* service_name, char* slave_id_str)
{
sprintf(slave_id_str, "%s%02X%02X%02X%02X", service_name, MB_ID2STR(MB_DEVICE_ID));
return slave_id_str;
}
static inline char* gen_host_name_str(char* service_name, char* name)
{
sprintf(name, "%s_%02X", service_name, MB_SLAVE_ADDR);
return name;
}
static void start_mdns_service(void)
{
char temp_str[32] = {0};
uint8_t sta_mac[6] = {0};
ESP_ERROR_CHECK(esp_read_mac(sta_mac, ESP_MAC_WIFI_STA));
char* hostname = gen_host_name_str(MB_MDNS_INSTANCE(""), temp_str);
//initialize mDNS
ESP_ERROR_CHECK(mdns_init());
//set mDNS hostname (required if you want to advertise services)
ESP_ERROR_CHECK(mdns_hostname_set(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_")));
//structure with TXT records
mdns_txt_item_t serviceTxtData[] = {
{"board","esp32"}
};
//initialize service
ESP_ERROR_CHECK(mdns_service_add(hostname, "_modbus", "_tcp", MB_MDNS_PORT, serviceTxtData, 1));
//add mac key string text item
ESP_ERROR_CHECK(mdns_service_txt_item_set("_modbus", "_tcp", "mac", gen_mac_str(sta_mac, "\0", temp_str)));
//add slave id key txt item
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
static void setup_reg_data(void)
{
@@ -150,6 +83,44 @@ static void setup_reg_data(void)
holding_reg_params.holding_data6 = 7.79;
holding_reg_params.holding_data7 = 8.80;
#if CONFIG_FMB_EXT_TYPE_SUPPORT
mb_set_uint8_a((val_16_arr *)&holding_reg_params.holding_u8_a[0], (uint8_t)0x55);
mb_set_uint8_a((val_16_arr *)&holding_reg_params.holding_u8_a[1], (uint8_t)0x55);
mb_set_uint8_b((val_16_arr *)&holding_reg_params.holding_u8_b[0], (uint8_t)0x55);
mb_set_uint8_b((val_16_arr *)&holding_reg_params.holding_u8_b[1], (uint8_t)0x55);
mb_set_uint16_ab((val_16_arr *)&holding_reg_params.holding_u16_ab[1], (uint16_t)MB_TEST_VALUE);
mb_set_uint16_ab((val_16_arr *)&holding_reg_params.holding_u16_ab[0], (uint16_t)MB_TEST_VALUE);
mb_set_uint16_ba((val_16_arr *)&holding_reg_params.holding_u16_ba[0], (uint16_t)MB_TEST_VALUE);
mb_set_uint16_ba((val_16_arr *)&holding_reg_params.holding_u16_ba[1], (uint16_t)MB_TEST_VALUE);
mb_set_float_abcd((val_32_arr *)&holding_reg_params.holding_float_abcd[0], (float)MB_TEST_VALUE);
mb_set_float_abcd((val_32_arr *)&holding_reg_params.holding_float_abcd[1], (float)MB_TEST_VALUE);
mb_set_float_cdab((val_32_arr *)&holding_reg_params.holding_float_cdab[0], (float)MB_TEST_VALUE);
mb_set_float_cdab((val_32_arr *)&holding_reg_params.holding_float_cdab[1], (float)MB_TEST_VALUE);
mb_set_float_badc((val_32_arr *)&holding_reg_params.holding_float_badc[0], (float)MB_TEST_VALUE);
mb_set_float_badc((val_32_arr *)&holding_reg_params.holding_float_badc[1], (float)MB_TEST_VALUE);
mb_set_float_dcba((val_32_arr *)&holding_reg_params.holding_float_dcba[0], (float)MB_TEST_VALUE);
mb_set_float_dcba((val_32_arr *)&holding_reg_params.holding_float_dcba[1], (float)MB_TEST_VALUE);
mb_set_uint32_abcd((val_32_arr *)&holding_reg_params.holding_uint32_abcd[0], (uint32_t)MB_TEST_VALUE);
mb_set_uint32_abcd((val_32_arr *)&holding_reg_params.holding_uint32_abcd[1], (uint32_t)MB_TEST_VALUE);
mb_set_uint32_cdab((val_32_arr *)&holding_reg_params.holding_uint32_cdab[0], (uint32_t)MB_TEST_VALUE);
mb_set_uint32_cdab((val_32_arr *)&holding_reg_params.holding_uint32_cdab[1], (uint32_t)MB_TEST_VALUE);
mb_set_uint32_badc((val_32_arr *)&holding_reg_params.holding_uint32_badc[0], (uint32_t)MB_TEST_VALUE);
mb_set_uint32_badc((val_32_arr *)&holding_reg_params.holding_uint32_badc[1], (uint32_t)MB_TEST_VALUE);
mb_set_uint32_dcba((val_32_arr *)&holding_reg_params.holding_uint32_dcba[0], (uint32_t)MB_TEST_VALUE);
mb_set_uint32_dcba((val_32_arr *)&holding_reg_params.holding_uint32_dcba[1], (uint32_t)MB_TEST_VALUE);
mb_set_double_abcdefgh((val_64_arr *)&holding_reg_params.holding_double_abcdefgh[0], (double)MB_TEST_VALUE);
mb_set_double_abcdefgh((val_64_arr *)&holding_reg_params.holding_double_abcdefgh[1], (double)MB_TEST_VALUE);
mb_set_double_hgfedcba((val_64_arr *)&holding_reg_params.holding_double_hgfedcba[0], (double)MB_TEST_VALUE);
mb_set_double_hgfedcba((val_64_arr *)&holding_reg_params.holding_double_hgfedcba[1], (double)MB_TEST_VALUE);
mb_set_double_ghefcdab((val_64_arr *)&holding_reg_params.holding_double_ghefcdab[0], (double)MB_TEST_VALUE);
mb_set_double_ghefcdab((val_64_arr *)&holding_reg_params.holding_double_ghefcdab[1], (double)MB_TEST_VALUE);
mb_set_double_badcfehg((val_64_arr *)&holding_reg_params.holding_double_badcfehg[0], (double)MB_TEST_VALUE);
mb_set_double_badcfehg((val_64_arr *)&holding_reg_params.holding_double_badcfehg[1], (double)MB_TEST_VALUE);
#endif
coil_reg_params.coils_port0 = 0x55;
coil_reg_params.coils_port1 = 0xAA;
@@ -157,7 +128,6 @@ static void setup_reg_data(void)
input_reg_params.input_data1 = 2.34;
input_reg_params.input_data2 = 3.56;
input_reg_params.input_data3 = 4.78;
input_reg_params.input_data4 = 1.12;
input_reg_params.input_data5 = 2.34;
input_reg_params.input_data6 = 3.56;
@@ -175,24 +145,25 @@ static void slave_operation_func(void *arg)
for(;holding_reg_params.holding_data0 < MB_CHAN_DATA_MAX_VAL;) {
// Check for read/write events of Modbus master for certain events
(void)mbc_slave_check_event(slave_handle, MB_READ_WRITE_MASK);
// Get parameter information from parameter queue
ESP_ERROR_CHECK(mbc_slave_get_param_info(slave_handle, &reg_info, MB_PAR_INFO_GET_TOUT));
ESP_ERROR_CHECK_WITHOUT_ABORT(mbc_slave_get_param_info(slave_handle, &reg_info, MB_PAR_INFO_GET_TOUT));
const char* rw_str = (reg_info.type & MB_READ_MASK) ? "READ" : "WRITE";
// Filter events and process them accordingly
if(reg_info.type & (MB_EVENT_HOLDING_REG_WR | MB_EVENT_HOLDING_REG_RD)) {
ESP_LOGI(TAG, "HOLDING %s (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
rw_str,
reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
(unsigned)reg_info.type,
(uint32_t)reg_info.address,
(unsigned)reg_info.size);
// Get parameter information from parameter queue
ESP_LOGI(TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
rw_str,
(unsigned)reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
(unsigned)reg_info.type,
(int)reg_info.address,
(unsigned)reg_info.size);
if (reg_info.address == (uint8_t*)&holding_reg_params.holding_data0)
{
(void)mbc_slave_unlock(slave_handle);
holding_reg_params.holding_data0 += MB_CHAN_DATA_OFFSET;
if (holding_reg_params.holding_data0 >= (MB_CHAN_DATA_MAX_VAL - MB_CHAN_DATA_OFFSET)) {
coil_reg_params.coils_port1 = 0xFF;
ESP_LOGI(TAG, "Riched maximum value");
}
(void)mbc_slave_unlock(slave_handle);
}
@@ -218,9 +189,10 @@ static void slave_operation_func(void *arg)
(unsigned)reg_info.type,
(uint32_t)reg_info.address,
(unsigned)reg_info.size);
if (coil_reg_params.coils_port1 == 0xFF) break;
if (coil_reg_params.coils_port1 == 0xFF) {
ESP_LOGI(TAG, "Stop polling.");
break;
}
}
}
// Destroy of Modbus controller on alarm
@@ -249,10 +221,6 @@ static esp_err_t init_services(void)
TAG,
"esp_event_loop_create_default fail, returns(0x%x).",
(int)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.
@@ -295,9 +263,6 @@ static esp_err_t destroy_services(void)
TAG,
"nvs_flash_deinit fail, returns(0x%x).",
(int)err);
#if CONFIG_MB_MDNS_IP_RESOLVER
stop_mdns_service();
#endif
return err;
}
@@ -338,6 +303,19 @@ static esp_err_t slave_init(mb_communication_info_t *pcomm_info)
"mbc_slave_set_descriptor fail, returns(0x%x).",
(int)err);
#if CONFIG_FMB_EXT_TYPE_SUPPORT
// The extended parameters register area
reg_area.type = MB_PARAM_HOLDING;
reg_area.start_offset = MB_REG_HOLDING_START_AREA2;
reg_area.address = (void*)&holding_reg_params.holding_u8_a;
reg_area.size = MB_REG_HOLDING_START_AREA2_SIZE;
err = mbc_slave_set_descriptor(slave_handle, reg_area);
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
TAG,
"mbc_slave_set_descriptor fail, returns(0x%x).",
(int)err);
#endif
// Initialization of Input Registers area
reg_area.type = MB_PARAM_INPUT;
reg_area.start_offset = MB_REG_INPUT_START_AREA0;
@@ -403,7 +381,7 @@ static esp_err_t slave_destroy(void)
return err;
}
// An example application of Modbus slave. It is based on freemodbus stack.
// An example application of Modbus slave. It is based on esp-modbus 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.
@@ -412,7 +390,6 @@ void app_main(void)
ESP_ERROR_CHECK(init_services());
// Set UART log level
esp_log_level_set(TAG, ESP_LOG_INFO);
mb_communication_info_t tcp_slave_config = {
@@ -2,7 +2,7 @@
# Modbus configuration
#
CONFIG_FMB_COMM_MODE_TCP_EN=y
CONFIG_FMB_TCP_PORT_DEFAULT=502
CONFIG_FMB_TCP_PORT_DEFAULT=1502
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20
CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
CONFIG_FMB_PORT_TASK_PRIO=10
@@ -10,9 +10,9 @@ CONFIG_FMB_COMM_MODE_RTU_EN=n
CONFIG_FMB_COMM_MODE_ASCII_EN=n
CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=300
CONFIG_FMB_EXT_TYPE_SUPPORT=y
CONFIG_FMB_TCP_UID_ENABLED=n
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
CONFIG_MB_MDNS_IP_RESOLVER=n
CONFIG_MB_SLAVE_ADDR=1
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_EXAMPLE_CONNECT_IPV6=n
+2 -2
View File
@@ -1,15 +1,15 @@
CONFIG_FMB_COMM_MODE_TCP_EN=y
CONFIG_FMB_TCP_PORT_DEFAULT=502
CONFIG_FMB_TCP_PORT_DEFAULT=1502
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20
CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
CONFIG_FMB_PORT_TASK_PRIO=10
CONFIG_FMB_COMM_MODE_RTU_EN=n
CONFIG_FMB_COMM_MODE_ASCII_EN=n
CONFIG_FMB_EXT_TYPE_SUPPORT=y
CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=3000
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=300
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_FMB_TCP_UID_ENABLED=n
CONFIG_MB_MDNS_IP_RESOLVER=n
CONFIG_MB_SLAVE_ADDR=1
CONFIG_EXAMPLE_CONNECT_IPV6=n
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
+1 -2
View File
@@ -2,7 +2,7 @@
# Modbus configuration
#
CONFIG_FMB_COMM_MODE_TCP_EN=y
CONFIG_FMB_TCP_PORT_DEFAULT=502
CONFIG_FMB_TCP_PORT_DEFAULT=1502
CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20
CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
CONFIG_FMB_PORT_TASK_PRIO=10
@@ -10,7 +10,6 @@ CONFIG_FMB_COMM_MODE_RTU_EN=n
CONFIG_FMB_COMM_MODE_ASCII_EN=n
CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=2000
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=300
CONFIG_MB_MDNS_IP_RESOLVER=n
CONFIG_FMB_TCP_UID_ENABLED=n
CONFIG_MB_SLAVE_ADDR=1
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
+10 -5
View File
@@ -12,8 +12,8 @@ import pytest
from conftest import ModbusTestDut, Stages
pattern_dict_slave = {Stages.STACK_IPV4: (r'I \([0-9]+\) example_connect: - IPv4 address: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})'),
Stages.STACK_IPV6: (r'I \([0-9]+\) example_connect: - IPv6 address: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})'),
pattern_dict_slave = {Stages.STACK_IPV4: (r'I \([0-9]+\) example_[a-z]+: - IPv4 address: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})'),
Stages.STACK_IPV6: (r'I \([0-9]+\) example_[a-z]+: - IPv6 address: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})'),
Stages.STACK_INIT: (r'I \(([0-9]+)\) MB_TCP_SLAVE_PORT: (Protocol stack initialized).'),
Stages.STACK_CONNECT: (r'I\s\(([0-9]+)\) MB_TCP_SLAVE_PORT: Socket \(#[0-9]+\), accept client connection from address: '
r'([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})'),
@@ -23,8 +23,8 @@ pattern_dict_slave = {Stages.STACK_IPV4: (r'I \([0-9]+\) example_connect: - IPv4
Stages.STACK_PAR_FAIL: (r'E \(([0-9]+)\) SLAVE_TEST: Response time exceeds configured [0-9]+ [ms], ignore packet'),
Stages.STACK_DESTROY: (r'I\s\(([0-9]+)\) SLAVE_TEST: (Modbus controller destroyed).')}
pattern_dict_master = {Stages.STACK_IPV4: (r'I \([0-9]+\) example_connect: - IPv4 address: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})'),
Stages.STACK_IPV6: (r'I \([0-9]+\) example_connect: - IPv6 address: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})'),
pattern_dict_master = {Stages.STACK_IPV4: (r'I \([0-9]+\) example_[a-z]+: - IPv4 address: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})'),
Stages.STACK_IPV6: (r'I \([0-9]+\) example_[a-z]+: - IPv6 address: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})'),
Stages.STACK_INIT: (r'I \(([0-9]+)\) MASTER_TEST: (Modbus master stack initialized)'),
Stages.STACK_CONNECT: (r'I\s\(([0-9]+)\) MB_TCP_MASTER_PORT: (Connected [0-9]+ slaves), start polling'),
Stages.STACK_START: (r'I \(([0-9]+)\) MASTER_TEST: (Start modbus test)'),
@@ -66,4 +66,9 @@ def test_modbus_tcp_communication(dut: Tuple[ModbusTestDut, ModbusTestDut]) -> N
dut_master.dut_test_start(dictionary=pattern_dict_master)
dut_slave.dut_check_errors()
dut_master.dut_check_errors()
dut_master.dut_check_errors()
@pytest.mark.multi_dut_modbus_generic
@pytest.mark.parametrize('config', ['dummy_config'])
def test_modbus_tcp_generic() -> None:
print('The generic tcp example tests are not provided yet.')