Main modbus examples complying with conftest

This commit is contained in:
Octavio Godoy
2025-11-06 10:23:04 +01:00
parent ee92969136
commit 8e1a140233
13 changed files with 234 additions and 183 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -312,55 +312,60 @@ static void *master_get_param_data(const mb_parameter_descriptor_t *param_descri
return instance_ptr;
}
#define TEST_VERIFY_VALUES(handle, descr, inst) (__extension__( \
{ \
assert(inst); \
assert(descr); \
uint8_t type = 0; \
esp_err_t err = ESP_FAIL; \
err = mbc_master_get_parameter(handle, descr->cid, \
(uint8_t *)inst, &type); \
if (err == ESP_OK) { \
bool is_correct = true; \
if (descr->param_opts.opt3) { \
for EACH_ITEM(inst, descr->param_size / sizeof(*item_ptr)) { \
if (*item_ptr != (typeof(*(inst)))descr->param_opts.opt3) { \
*item_ptr = (typeof(*(inst)))descr->param_opts.opt3; \
ESP_LOGD(TAG, "Characteristic #%d (%s), initialize to 0x%" PRIx16 ".", \
(int)descr->cid, \
(char *)descr->param_key, \
(uint16_t)descr->param_opts.opt3); \
is_correct = false; \
} \
} \
} \
if (!is_correct) { \
ESP_LOGE(TAG, "Characteristic #%d (%s), initialize.", \
(int)descr->cid, \
(char *)descr->param_key); \
err = mbc_master_set_parameter(handle, cid, (uint8_t *)inst, &type); \
if (err != ESP_OK) { \
ESP_LOGE(TAG, "Characteristic #%d (%s) write fail, err = 0x%x (%s).", \
(int)descr->cid, \
(char *)descr->param_key, \
(int)err, \
(char *)esp_err_to_name(err)); \
} else { \
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (..) write successful.", \
(int)descr->cid, \
(char *)descr->param_key, \
(char *)descr->param_units); \
} \
} \
} else { \
ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).", \
(int)descr->cid, \
(char *)descr->param_key, \
(int)err, \
(char *)esp_err_to_name(err)); \
} \
(err); \
} \
#define TEST_VERIFY_VALUES(handle, pdescr, pinst) (__extension__( \
{ \
assert(pinst); \
assert(pdescr); \
uint8_t type = 0; \
esp_err_t err = ESP_FAIL; \
err = mbc_master_get_parameter(handle, pdescr->cid, \
(uint8_t *)pinst, &type); \
if (err == ESP_OK) { \
bool is_correct = true; \
if (pdescr->param_opts.opt3) { \
for EACH_ITEM(pinst, pdescr->param_size / sizeof(*item_ptr)) { \
if (*item_ptr != (typeof(*(pinst)))pdescr->param_opts.opt3) { \
*item_ptr = (typeof(*(pinst)))pdescr->param_opts.opt3; \
ESP_LOGD(TAG, "%p Characteristic #%d (%s), initialize to 0x%" PRIx16 ".", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key, \
(uint16_t)pdescr->param_opts.opt3); \
is_correct = false; \
} \
} \
} \
if (!is_correct) { \
ESP_LOGE(TAG, "%p Characteristic #%d (%s), initialize.", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key); \
err = mbc_master_set_parameter(handle, cid, (uint8_t *)pinst, &type); \
if (err != ESP_OK) { \
ESP_LOGE(TAG, "%p Characteristic #%d (%s) write fail, err = 0x%x (%s).", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key, \
(int)err, \
(char *)esp_err_to_name(err)); \
} else { \
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = (..) write successful.", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key, \
(char *)pdescr->param_units); \
} \
} \
} else { \
ESP_LOGE(TAG, "%p Characteristic #%d (%s) read fail, err = 0x%x (%s).", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key, \
(int)err, \
(char *)esp_err_to_name(err)); \
} \
(err); \
} \
))
// User operation function to read slave values and check alarm
@@ -426,7 +431,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_TEST_REG)) {
// Check test parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (uint32_t *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%" PRIx32 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = (0x%" PRIx32 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -437,7 +443,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_U16_BA)) {
// Check the uint16 parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (uint16_t *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%" PRIx16 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = (0x%" PRIx16 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -447,7 +454,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_U8_B)) {
// Check the uint8 parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (uint16_t *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%" PRIx16 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = (0x%" PRIx16 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -457,7 +465,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_UINT32_DCBA)) {
// Check the uint32 parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (uint32_t *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %" PRIu32 " (0x%" PRIx32 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %" PRIu32 " (0x%" PRIx32 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -468,7 +477,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_FLOAT_DCBA)) {
// Check the float parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (float *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%" PRIx32 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %f (0x%" PRIx32 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -478,7 +488,8 @@ static void master_operation_func(void *arg)
} else if (param_descriptor->cid >= CID_HOLD_DOUBLE_ABCDEFGH) {
// Check the double parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (double *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %lf (0x%" PRIx64 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %lf (0x%" PRIx64 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -488,7 +499,8 @@ static void master_operation_func(void *arg)
#endif
} else if (cid <= CID_HOLD_DATA_2) {
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (float *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%" PRIx32 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %f (0x%" PRIx32 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -506,14 +518,16 @@ static void master_operation_func(void *arg)
uint8_t state = *(uint8_t *)temp_data_ptr;
const char *rw_str = (state & param_descriptor->param_opts.opt1) ? "ON" : "OFF";
if ((state & param_descriptor->param_opts.opt2) == param_descriptor->param_opts.opt2) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %s (0x%" PRIx8 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %s (0x%" PRIx8 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
(const char *)rw_str,
*(uint8_t *)temp_data_ptr);
} else {
ESP_LOGE(TAG, "Characteristic #%d %s (%s) value = %s (0x%" PRIx8 "), unexpected value.",
ESP_LOGE(TAG, "%p Characteristic #%d %s (%s) value = %s (0x%" PRIx8 "), unexpected value.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -629,4 +643,5 @@ void app_main(void)
vTaskDelay(10);
master_operation_func(NULL);
ESP_LOGI(TAG, "Master Serial is completed. (%s).", __func__);
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -306,7 +306,8 @@ void app_main(void)
// 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",
ESP_LOGI(TAG, "OBJ %p, HOLDING %s (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
mbc_slave_handle,
rw_str,
reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
@@ -322,21 +323,24 @@ void app_main(void)
(void)mbc_slave_unlock(mbc_slave_handle);
}
} else if (reg_info.type & MB_EVENT_INPUT_REG_RD) {
ESP_LOGI(TAG, "INPUT READ (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
ESP_LOGI(TAG, "OBJ %p, INPUT READ (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
mbc_slave_handle,
reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
(unsigned)reg_info.type,
(uint32_t)reg_info.address,
(unsigned)reg_info.size);
} else if (reg_info.type & MB_EVENT_DISCRETE_RD) {
ESP_LOGI(TAG, "DISCRETE READ (%" PRIu32 " us): ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
ESP_LOGI(TAG, "OBJ %p, DISCRETE READ (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
mbc_slave_handle,
reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
(unsigned)reg_info.type,
(uint32_t)reg_info.address,
(unsigned)reg_info.size);
} else if (reg_info.type & (MB_EVENT_COILS_RD | MB_EVENT_COILS_WR)) {
ESP_LOGI(TAG, "COILS %s (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
ESP_LOGI(TAG, "OBJ %p, COILS %s (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
mbc_slave_handle,
rw_str,
reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
@@ -350,7 +354,7 @@ void app_main(void)
}
}
// Destroy of Modbus controller on alarm
ESP_LOGI(TAG, "Modbus controller destroyed.");
ESP_LOGI(TAG, "Destroy slave.");
vTaskDelay(100);
ESP_ERROR_CHECK(mbc_slave_delete(mbc_slave_handle));
}
+86 -70
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -26,6 +26,7 @@
#define MB_TCP_PORT (CONFIG_FMB_TCP_PORT_DEFAULT) // TCP port used by example
// The number of parameters that intended to be used in the particular control process
#define MASTER_MAX_CIDS num_device_parameters
@@ -91,9 +92,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,
MB_DEVICE_ADDR3,
MB_DEVICE_COUNT = 3
//MB_DEVICE_ADDR1,
//MB_DEVICE_ADDR3,
MB_DEVICE_COUNT = 2
};
// Enumeration of all supported CIDs for device (used in parameter definition table)
@@ -160,19 +161,19 @@ const mb_parameter_descriptor_t device_parameters[] = {
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,
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( 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,
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( 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,
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( TEST_HUMI_MIN, TEST_HUMI_MAX, 0 ), PAR_PERMS_READ_WRITE_TRIGGER
@@ -316,14 +317,14 @@ const size_t ip_table_sz;
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", // 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
//"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",
// "02;mb_slave_tcp_01;502",
//"03;mb_slave_tcp_01;1502",
NULL // End of table condition (must be included)
#endif
};
@@ -452,54 +453,59 @@ static void *master_get_param_data(const mb_parameter_descriptor_t *param_descri
return instance_ptr;
}
#define TEST_VERIFY_VALUES(handle, descr, inst) (__extension__( \
{ \
assert(inst); \
assert(descr); \
uint8_t type = 0; \
esp_err_t err = ESP_FAIL; \
err = mbc_master_get_parameter(handle, descr->cid, (uint8_t *)inst, &type); \
if (err == ESP_OK) { \
bool is_correct = true; \
if (descr->param_opts.opt3) { \
for EACH_ITEM(inst, descr->param_size / sizeof(*item_ptr)) { \
if (*item_ptr != (typeof(*(inst)))descr->param_opts.opt3) { \
*item_ptr = (typeof(*(inst)))descr->param_opts.opt3; \
ESP_LOGD(TAG, "Characteristic #%d (%s), initialize to 0x%" PRIx16 ".", \
(int)descr->cid, \
(char *)descr->param_key, \
(uint16_t)descr->param_opts.opt3); \
is_correct = false; \
} \
} \
} \
if (!is_correct) { \
ESP_LOGE(TAG, "Characteristic #%d (%s), initialize.", \
(int)descr->cid, \
(char *)descr->param_key); \
err = mbc_master_set_parameter(handle, cid, (uint8_t *)inst, &type); \
if (err != ESP_OK) { \
ESP_LOGE(TAG, "Characteristic #%d (%s) write fail, err = 0x%x (%s).", \
(int)descr->cid, \
(char *)descr->param_key, \
(int)err, \
(char *)esp_err_to_name(err)); \
} else { \
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (..) write successful.", \
(int)descr->cid, \
(char *)descr->param_key, \
(char *)descr->param_units); \
} \
} \
} else { \
ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).", \
(int)descr->cid, \
(char *)descr->param_key, \
(int)err, \
(char *)esp_err_to_name(err)); \
} \
(err); \
} \
#define TEST_VERIFY_VALUES(handle, pdescr, pinst) (__extension__( \
{ \
assert(pinst); \
assert(pdescr); \
uint8_t type = 0; \
esp_err_t err = ESP_FAIL; \
err = mbc_master_get_parameter(handle, pdescr->cid, (uint8_t *)pinst, &type); \
if (err == ESP_OK) { \
bool is_correct = true; \
if (pdescr->param_opts.opt3) { \
for EACH_ITEM(pinst, pdescr->param_size / sizeof(*item_ptr)) { \
if (*item_ptr != (typeof(*(pinst)))pdescr->param_opts.opt3) { \
*item_ptr = (typeof(*(pinst)))pdescr->param_opts.opt3; \
ESP_LOGD(TAG, "%p Characteristic #%d (%s), initialize to 0x%" PRIx16 ".", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key, \
(uint16_t)pdescr->param_opts.opt3); \
is_correct = false; \
} \
} \
} \
if (!is_correct) { \
ESP_LOGE(TAG, "%p Characteristic #%d (%s), initialize.", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key); \
err = mbc_master_set_parameter(handle, cid, (uint8_t *)pinst, &type); \
if (err != ESP_OK) { \
ESP_LOGE(TAG, "%p Characteristic #%d (%s) write fail, err = 0x%x (%s).", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key, \
(int)err, \
(char *)esp_err_to_name(err)); \
} else { \
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = (..) write successful.", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key, \
(char *)pdescr->param_units); \
} \
} \
} else { \
ESP_LOGE(TAG, "%p Characteristic #%d (%s) read fail, err = 0x%x (%s).", \
master_handle, \
(int)pdescr->cid, \
(char *)pdescr->param_key, \
(int)err, \
(char *)esp_err_to_name(err)); \
} \
(err); \
} \
))
// User operation function to read slave values and check alarm
@@ -509,7 +515,7 @@ static void master_operation_func(void *arg)
bool alarm_state = false;
const mb_parameter_descriptor_t *param_descriptor = NULL;
ESP_LOGI(TAG, "Start modbus test...");
ESP_LOGI(TAG, "Master TCP is started.");
char *pcustom_string = "Master";
mb_param_request_t req = {
@@ -539,7 +545,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_TEST_REG)) {
// Check test parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (uint32_t *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%" PRIx32 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = (0x%" PRIx32 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -550,7 +557,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_U16_BA)) {
// Check the uint16 parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (uint16_t *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%" PRIx16 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = (0x%" PRIx16 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -560,7 +568,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_U8_B)) {
// Check the uint8 parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (uint16_t *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = (0x%" PRIx16 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = (0x%" PRIx16 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -570,7 +579,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_UINT32_DCBA)) {
// Check the uint32 parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (uint32_t *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %" PRIu32 " (0x%" PRIx32 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %" PRIu32 " (0x%" PRIx32 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -581,7 +591,8 @@ static void master_operation_func(void *arg)
&& (param_descriptor->cid <= CID_HOLD_FLOAT_DCBA)) {
// Check the float parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (float *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%" PRIx32 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %f (0x%" PRIx32 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -591,7 +602,8 @@ static void master_operation_func(void *arg)
} else if (param_descriptor->cid >= CID_HOLD_DOUBLE_ABCDEFGH) {
// Check the double parameters
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (double *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %lf (0x%" PRIx64 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %lf (0x%" PRIx64 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -601,7 +613,8 @@ static void master_operation_func(void *arg)
#endif
} else if (cid <= CID_HOLD_DATA_2) {
if (TEST_VERIFY_VALUES(master_handle, param_descriptor, (float *)temp_data_ptr) == ESP_OK) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%" PRIx32 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %f (0x%" PRIx32 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -619,14 +632,16 @@ static void master_operation_func(void *arg)
uint8_t state = *(uint8_t *)temp_data_ptr;
const char *rw_str = (state & param_descriptor->param_opts.opt1) ? "ON" : "OFF";
if ((state & param_descriptor->param_opts.opt2) == param_descriptor->param_opts.opt2) {
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %s (0x%" PRIx8 ") read successful.",
ESP_LOGI(TAG, "%p Characteristic #%d %s (%s) value = %s (0x%" PRIx8 ") read successful.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
(const char *)rw_str,
*(uint8_t *)temp_data_ptr);
} else {
ESP_LOGE(TAG, "Characteristic #%d %s (%s) value = %s (0x%" PRIx8 "), unexpected value.",
ESP_LOGE(TAG, "%p Characteristic #%d %s (%s) value = %s (0x%" PRIx8 "), unexpected value.",
master_handle,
(int)param_descriptor->cid,
(char *)param_descriptor->param_key,
(char *)param_descriptor->param_units,
@@ -798,7 +813,7 @@ static esp_err_t master_destroy(void)
TAG,
"mbc_master_destroy fail, returns(0x%x).",
(int)err);
ESP_LOGI(TAG, "Modbus master stack destroy...");
ESP_LOGI(TAG, "Destroy master stack");
return err;
}
@@ -828,4 +843,5 @@ void app_main(void)
master_operation_func(NULL);
ESP_ERROR_CHECK(master_destroy());
ESP_ERROR_CHECK(destroy_services());
ESP_LOGI(TAG, "Master TCP is completed. (%s).", __func__);
}
@@ -10,10 +10,10 @@ 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_TCP_UID_ENABLED=n
CONFIG_FMB_TCP_UID_ENABLED=y
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
CONFIG_MB_SLAVE_IP_FROM_STDIN=y
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y # intentionally keep it here to change when needed
CONFIG_MB_SLAVE_IP_FROM_STDIN=n
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_FMB_EXT_TYPE_SUPPORT=y
CONFIG_EXAMPLE_CONNECT_IPV6=n
+3 -3
View File
@@ -7,9 +7,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_LOG_DEFAULT_LEVEL_DEBUG=y # intentionally keep it here to change when needed
CONFIG_FMB_TCP_UID_ENABLED=n
CONFIG_MB_SLAVE_IP_FROM_STDIN=y
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_FMB_TCP_UID_ENABLED=y
CONFIG_MB_SLAVE_IP_FROM_STDIN=n
CONFIG_EXAMPLE_CONNECT_IPV6=n
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
CONFIG_FMB_EXT_TYPE_SUPPORT=y
@@ -11,8 +11,8 @@ 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_FMB_TCP_UID_ENABLED=n
CONFIG_MB_SLAVE_IP_FROM_STDIN=y
CONFIG_FMB_TCP_UID_ENABLED=y
CONFIG_MB_SLAVE_IP_FROM_STDIN=n
CONFIG_FMB_EXT_TYPE_SUPPORT=y
CONFIG_EXAMPLE_CONNECT_IPV6=n
CONFIG_EXAMPLE_CONNECT_ETHERNET=n
+33 -20
View File
@@ -1,9 +1,13 @@
/*
* SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// esp-modbus Slave Example ESP32
#include <stdio.h>
#include "esp_err.h"
#include "sdkconfig.h"
@@ -55,6 +59,7 @@
#define MB_SLAVE_ADDR (CONFIG_MB_SLAVE_ADDR)
#define MB_CUST_DATA_MAX_LEN (100)
static const char *TAG = "SLAVE_TEST";
static void *slave_handle = NULL;
@@ -123,33 +128,35 @@ static void setup_reg_data(void)
coil_reg_params.coils_port0 = 0x55;
coil_reg_params.coils_port1 = 0xAA;
input_reg_params.input_data0 = 1.12F;
input_reg_params.input_data1 = 2.34F;
input_reg_params.input_data2 = 3.56F;
input_reg_params.input_data3 = 4.78F;
input_reg_params.input_data4 = 1.12F;
input_reg_params.input_data5 = 2.34F;
input_reg_params.input_data6 = 3.56F;
input_reg_params.input_data7 = 4.78F;
input_reg_params.input_data0 = 1.12;
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 = 6.12;
input_reg_params.input_data5 = 7.34;
input_reg_params.input_data6 = 8.56;
input_reg_params.input_data7 = 9.78;
}
static void slave_operation_func(void *arg)
{
mb_param_info_t reg_info; // keeps the Modbus registers access information
ESP_LOGI(TAG, "Modbus slave stack initialized.");
ESP_LOGI(TAG, "Slave TCP is started");
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;) {
// Check for read/write events of Modbus master for certain events
(void)mbc_slave_check_event(slave_handle, MB_READ_WRITE_MASK);
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";
(void)mbc_slave_check_event(slave_handle, MB_READ_WRITE_MASK); // checks every type of event from specific slave , parameter queue
ESP_ERROR_CHECK_WITHOUT_ABORT(mbc_slave_get_param_info(slave_handle, &reg_info, MB_PAR_INFO_GET_TOUT)); // get latest info from parameter queue
const char *rw_str = (reg_info.type & MB_READ_MASK) ? "READ" : "WRITE"; //only checks read mask, assumes write if not
// Filter events and process them accordingly
if (reg_info.type & (MB_EVENT_HOLDING_REG_WR | MB_EVENT_HOLDING_REG_RD)) {
// Get parameter information from parameter queue
ESP_LOGI(TAG, "HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
ESP_LOGI(TAG, "OBJ %p, HOLDING %s (%u us), ADDR:%u, TYPE:%u, INST_ADDR:0x%.4x, SIZE:%u",
slave_handle,
rw_str,
(unsigned)reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
@@ -166,21 +173,24 @@ static void slave_operation_func(void *arg)
(void)mbc_slave_unlock(slave_handle);
}
} else if (reg_info.type & MB_EVENT_INPUT_REG_RD) {
ESP_LOGI(TAG, "INPUT READ (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
ESP_LOGI(TAG, "OBJ %p, INPUT READ (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
slave_handle,
reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
(unsigned)reg_info.type,
(uint32_t)reg_info.address,
(unsigned)reg_info.size);
} else if (reg_info.type & MB_EVENT_DISCRETE_RD) {
ESP_LOGI(TAG, "DISCRETE READ (%" PRIu32 " us): ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
ESP_LOGI(TAG, "OBJ %p, DISCRETE READ (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
slave_handle,
reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
(unsigned)reg_info.type,
(uint32_t)reg_info.address,
(unsigned)reg_info.size);
} else if (reg_info.type & (MB_EVENT_COILS_RD | MB_EVENT_COILS_WR)) {
ESP_LOGI(TAG, "COILS %s (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
ESP_LOGI(TAG, "OBJ %p, COILS %s (%" PRIu32 " us), ADDR:%u, TYPE:%u, INST_ADDR:0x%" PRIx32 ", SIZE:%u",
slave_handle,
rw_str,
reg_info.time_stamp,
(unsigned)reg_info.mb_offset,
@@ -194,7 +204,7 @@ static void slave_operation_func(void *arg)
}
}
// Destroy of Modbus controller on alarm
ESP_LOGI(TAG, "Modbus controller destroyed.");
ESP_LOGI(TAG, "Destroy slave.");
vTaskDelay(100);
}
@@ -428,7 +438,7 @@ void app_main(void)
// Set UART log level
esp_log_level_set(TAG, ESP_LOG_INFO);
mb_communication_info_t tcp_slave_config = {
mb_communication_info_t tcp_slave_config_1 = {
.tcp_opts.port = MB_TCP_PORT_NUMBER,
.tcp_opts.mode = MB_TCP,
#if !CONFIG_EXAMPLE_CONNECT_IPV6
@@ -441,7 +451,10 @@ void app_main(void)
.tcp_opts.uid = MB_SLAVE_ADDR
};
ESP_ERROR_CHECK(slave_init(&tcp_slave_config));
ESP_ERROR_CHECK(slave_init(&tcp_slave_config_1));
ESP_LOGI(TAG, "Slave TCP #1 is started (%s)", __func__);
// The Modbus slave logic is located in this function (user handling of Modbus)
slave_operation_func(NULL);
@@ -11,7 +11,7 @@ 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_TCP_UID_ENABLED=y
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
CONFIG_MB_SLAVE_ADDR=1
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y # intentionally keep it here to change when needed!
+2 -2
View File
@@ -8,8 +8,8 @@ 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 # intentionally keep it here to change when needed!
CONFIG_FMB_TCP_UID_ENABLED=n
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_FMB_TCP_UID_ENABLED=y
CONFIG_MB_SLAVE_ADDR=1
CONFIG_EXAMPLE_CONNECT_IPV6=n
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
+1 -1
View File
@@ -10,7 +10,7 @@ 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_FMB_TCP_UID_ENABLED=n
CONFIG_FMB_TCP_UID_ENABLED=y
CONFIG_MB_SLAVE_ADDR=1
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
CONFIG_EXAMPLE_CONNECT_IPV6=n
@@ -181,10 +181,12 @@ esp_err_t mbc_master_set_descriptor(void *ctx, const mb_parameter_descriptor_t *
esp_err_t error = ESP_OK;
MB_RETURN_ON_FALSE(ctx, ESP_ERR_INVALID_STATE, TAG,
"Master interface is not correctly initialized.");
mbm_controller_iface_t *mbm_controller = MB_MASTER_GET_IFACE(ctx);
MB_RETURN_ON_FALSE(mbm_controller->set_descriptor,
ESP_ERR_INVALID_STATE, TAG,
"Master interface is not correctly configured.");
error = mbm_controller->set_descriptor(ctx, descriptor, num_elements);
MB_RETURN_ON_FALSE((error == ESP_OK), error, TAG,
"Master set descriptor failure, error=(0x%x) (%s).",
@@ -319,6 +319,7 @@ static esp_err_t mbc_serial_master_get_parameter(void *ctx, uint16_t cid, uint8_
{
MB_RETURN_ON_FALSE((type), ESP_ERR_INVALID_ARG, TAG, "type pointer is incorrect.");
MB_RETURN_ON_FALSE((value), ESP_ERR_INVALID_ARG, TAG, "value pointer is incorrect.");
mbm_controller_iface_t *mbm_controller_iface = MB_MASTER_GET_IFACE(ctx);
esp_err_t error = ESP_ERR_INVALID_RESPONSE;
mb_param_request_t request ;
mb_parameter_descriptor_t reg_info = { 0 };
@@ -339,23 +340,23 @@ static esp_err_t mbc_serial_master_get_parameter(void *ctx, uint16_t cid, uint8_
error = mbc_master_set_param_data((void *)value, (void *)data_ptr,
reg_info.param_type, reg_info.param_size);
if (error != ESP_OK) {
ESP_LOGE(TAG, "fail to set parameter data.");
ESP_LOGE(TAG, "%p fail to set parameter data.", mbm_controller_iface);
error = ESP_ERR_INVALID_STATE;
} else {
ESP_LOGD(TAG, "%s: Good response for get cid(%u) = %s",
__FUNCTION__, (unsigned)reg_info.cid, (char *)esp_err_to_name(error));
ESP_LOGD(TAG, "%s: %p Good response for get cid(%u) = %s",
__FUNCTION__, mbm_controller_iface, (unsigned)reg_info.cid, (char *)esp_err_to_name(error));
}
}
} else {
ESP_LOGD(TAG, "%s: Bad response to get cid(%u) = %s",
__FUNCTION__, (unsigned)reg_info.cid, (char *)esp_err_to_name(error));
ESP_LOGD(TAG, "%s: %p Bad response to get cid(%u) = %s",
__FUNCTION__, mbm_controller_iface, (unsigned)reg_info.cid, (char *)esp_err_to_name(error));
}
free(data_ptr);
// Set the type of parameter found in the table
*type = reg_info.param_type;
} else {
ESP_LOGE(TAG, "%s: The cid(%u) not found in the data dictionary.",
__FUNCTION__, (unsigned)reg_info.cid);
ESP_LOGE(TAG, "%s: %p The cid(%u) not found in the data dictionary.",
__FUNCTION__, mbm_controller_iface, (unsigned)reg_info.cid);
error = ESP_ERR_INVALID_ARG;
}
return error;
+9 -9
View File
@@ -331,8 +331,8 @@ static esp_err_t mbc_tcp_master_get_parameter(void *ctx, uint16_t cid, uint8_t *
mb_uid_info_t *addr_info = mbm_port_tcp_get_slave_info(mbm_controller_iface->mb_base->port_obj,
request.slave_addr, MB_SOCK_STATE_CONNECTED);
if (!addr_info) {
ESP_LOGW(TAG, "Try to send request for cid #%u with uid = %d, node is disconnected.",
(unsigned)reg_info.cid, (int)request.slave_addr);
ESP_LOGW(TAG, "%p Try to send request for cid #%u with uid = %d, node is disconnected.",
mbm_controller_iface, (unsigned)reg_info.cid, (int)request.slave_addr);
}
MB_MASTER_ASSERT(xPortGetFreeHeapSize() > (reg_info.mb_size << 1));
// alloc buffer to store parameter data
@@ -347,23 +347,23 @@ static esp_err_t mbc_tcp_master_get_parameter(void *ctx, uint16_t cid, uint8_t *
error = mbc_master_set_param_data((void *)value, (void *)data_ptr,
reg_info.param_type, reg_info.param_size);
if (error != ESP_OK) {
ESP_LOGE(TAG, "fail to set parameter data.");
ESP_LOGE(TAG, "%p fail to set parameter data.", mbm_controller_iface);
error = ESP_ERR_INVALID_STATE;
} else {
ESP_LOGD(TAG, "%s: Good response for get cid(%u) = %s",
__FUNCTION__, (unsigned)reg_info.cid, (char *)esp_err_to_name(error));
ESP_LOGD(TAG, "%s: %p Good response for get cid(%u) = %s",
__FUNCTION__, mbm_controller_iface, (unsigned)reg_info.cid, (char *)esp_err_to_name(error));
}
}
} else {
ESP_LOGD(TAG, "%s: Bad response to get cid(%u) = %s",
__FUNCTION__, (unsigned)reg_info.cid, (char *)esp_err_to_name(error));
ESP_LOGD(TAG, "%s: %p Bad response to get cid(%u) = %s",
__FUNCTION__, mbm_controller_iface, (unsigned)reg_info.cid, (char *)esp_err_to_name(error));
}
free(data_ptr);
// Set the type of parameter found in the table
*type = reg_info.param_type;
} else {
ESP_LOGE(TAG, "%s: The cid(%u) not found in the data dictionary.",
__FUNCTION__, (unsigned)reg_info.cid);
ESP_LOGE(TAG, "%s: %p The cid(%u) not found in the data dictionary.",
__FUNCTION__, mbm_controller_iface, (unsigned)reg_info.cid);
error = ESP_ERR_INVALID_ARG;
}
return error;