Merge branch 'bugfix/freemodbus_tcp_master_fix_long_frame_buffer_issue' into 'master'

freemodbus: fix tcp master long frame buffer issue

See merge request espressif/esp-idf!11687
This commit is contained in:
Ivan Grokhotkov
2021-11-05 16:23:35 +00:00
5 changed files with 133 additions and 71 deletions
@@ -1,3 +1,9 @@
/*
* SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*=====================================================================================
* Description:
* The Modbus parameter structures used to define Modbus instances that
@@ -44,6 +50,7 @@ typedef struct
float input_data5;
float input_data6;
float input_data7;
uint16_t data_block1[150];
} input_reg_params_t;
#pragma pack(pop)
@@ -81,6 +81,7 @@ enum {
CID_HOLD_DATA_1,
CID_INP_DATA_2,
CID_HOLD_DATA_2,
CID_HOLD_TEST_REG,
CID_RELAY_P1,
CID_RELAY_P2,
CID_COUNT
@@ -109,10 +110,12 @@ const mb_parameter_descriptor_t device_parameters[] = {
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,
HOLD_OFFSET(holding_data2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_HOLD_TEST_REG, STR("Test_regs"), STR("__"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 8, 100,
HOLD_OFFSET(test_regs), PARAM_TYPE_ASCII, 200, 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 },
COIL_OFFSET(coils_port0), PARAM_TYPE_U16, 1, OPTS( BIT1, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
{ CID_RELAY_P2, STR("RelayP2"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 8, 8,
COIL_OFFSET(coils_port1), PARAM_TYPE_U16, 2, OPTS( BIT0, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER }
COIL_OFFSET(coils_port1), PARAM_TYPE_U16, 1, OPTS( BIT0, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER }
};
// Calculate number of parameters in the table
@@ -437,43 +440,83 @@ static void master_operation_func(void *arg)
void* temp_data_ptr = master_get_param_data(param_descriptor);
assert(temp_data_ptr);
uint8_t type = 0;
err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
(uint8_t*)&value, &type);
if (err == ESP_OK) {
*(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.",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(char*)param_descriptor->param_units,
value,
*(uint32_t*)temp_data_ptr);
if (((value > param_descriptor->param_opts.max) ||
(value < param_descriptor->param_opts.min))) {
alarm_state = true;
break;
if ((param_descriptor->param_type == PARAM_TYPE_ASCII) &&
(param_descriptor->cid == CID_HOLD_TEST_REG)) {
// Check for long array of registers of type PARAM_TYPE_ASCII
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.",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(char*)param_descriptor->param_units,
*(uint32_t*)temp_data_ptr);
// Initialize data of test array and write to slave
if (*(uint32_t*)temp_data_ptr != 0xAAAAAAAA) {
memset((void*)temp_data_ptr, 0xAA, param_descriptor->param_size);
*(uint32_t*)temp_data_ptr = 0xAAAAAAAA;
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.",
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).",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(int)err,
(char*)esp_err_to_name(err));
}
}
} 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.",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(char*)param_descriptor->param_units,
(const char*)rw_str,
*(uint16_t*)temp_data_ptr);
if (state & param_descriptor->param_opts.opt1) {
alarm_state = true;
break;
}
ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(int)err,
(char*)esp_err_to_name(err));
}
} else {
ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = %d (%s).",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(int)err,
(char*)esp_err_to_name(err));
err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
(uint8_t*)temp_data_ptr, &type);
if (err == ESP_OK) {
if ((param_descriptor->mb_param_type == MB_PARAM_HOLDING) ||
(param_descriptor->mb_param_type == MB_PARAM_INPUT)) {
value = *(float*)temp_data_ptr;
ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = %f (0x%x) read successful.",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(char*)param_descriptor->param_units,
value,
*(uint32_t*)temp_data_ptr);
if (((value > param_descriptor->param_opts.max) ||
(value < param_descriptor->param_opts.min))) {
alarm_state = true;
break;
}
} else {
uint8_t state = *(uint8_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.",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(char*)param_descriptor->param_units,
(const char*)rw_str,
*(uint8_t*)temp_data_ptr);
if (state & param_descriptor->param_opts.opt1) {
alarm_state = true;
break;
}
}
} else {
ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
param_descriptor->cid,
(char*)param_descriptor->param_key,
(int)err,
(char*)esp_err_to_name(err));
}
}
vTaskDelay(POLL_TIMEOUT_TICS); // timeout between polls
}
@@ -329,7 +329,7 @@ static esp_err_t slave_init(mb_communication_info_t* comm_info)
reg_area.type = MB_PARAM_HOLDING; // Set type of register area
reg_area.start_offset = MB_REG_HOLDING_START_AREA0; // Offset of register area in Modbus protocol
reg_area.address = (void*)&holding_reg_params.holding_data0; // Set pointer to storage instance
reg_area.size = sizeof(float) << 2; // Set the size of register storage instance
reg_area.size = (MB_REG_HOLDING_START_AREA1 - MB_REG_HOLDING_START_AREA0) << 1; // Set the size of register storage instance
err = mbc_slave_set_descriptor(reg_area);
ESP_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE,
SLAVE_TAG,