forked from espressif/esp-modbus
feature modbus tcp master slave v2
This commit is contained in:
+10
-9
@@ -22,11 +22,11 @@ extern "C" {
|
||||
typedef struct mb_base_t mb_base_t; /*!< Type of modbus object */
|
||||
typedef struct mb_port_base_t mb_port_base_t;
|
||||
|
||||
bool mb_port_evt_get(mb_port_base_t *inst, mb_event_t *pevent);
|
||||
bool mb_port_evt_post(mb_port_base_t *inst, mb_event_t event);
|
||||
bool mb_port_evt_res_take(mb_port_base_t *inst, uint32_t timeout);
|
||||
void mb_port_evt_res_release(mb_port_base_t *inst);
|
||||
mb_err_enum_t mb_port_evt_wait_req_finish(mb_port_base_t *inst);
|
||||
bool mb_port_event_get(mb_port_base_t *inst, mb_event_t *pevent);
|
||||
bool mb_port_event_post(mb_port_base_t *inst, mb_event_t event);
|
||||
bool mb_port_event_res_take(mb_port_base_t *inst, uint32_t timeout);
|
||||
void mb_port_event_res_release(mb_port_base_t *inst);
|
||||
mb_err_enum_t mb_port_event_wait_req_finish(mb_port_base_t *inst);
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_ASCII_EN || CONFIG_FMB_COMM_MODE_RTU_EN)
|
||||
|
||||
@@ -91,6 +91,10 @@ mb_exception_t mbs_fn_rw_multi_holding_reg(mb_base_t *inst, uint8_t *frame_ptr,u
|
||||
|
||||
#endif
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_TCP_EN)
|
||||
|
||||
typedef struct _port_tcp_opts mb_tcp_opts_t;
|
||||
|
||||
mb_err_enum_t mbs_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj);
|
||||
|
||||
mb_err_enum_t mbs_delete(mb_base_t *inst);
|
||||
@@ -99,11 +103,8 @@ mb_err_enum_t mbs_disable(mb_base_t *inst);
|
||||
mb_err_enum_t mbs_poll(mb_base_t *inst);
|
||||
mb_err_enum_t mbs_set_slv_id(mb_base_t *inst, uint8_t slv_id, bool is_running, uint8_t const *slv_idstr, uint16_t slv_idstr_len);
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_TCP_EN)
|
||||
|
||||
typedef struct _port_tcp_opts mb_tcp_opts_t;
|
||||
|
||||
mb_err_enum_t mbm_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj);
|
||||
mb_uid_info_t *mbm_port_tcp_get_slave_info(mb_port_base_t *inst, uint8_t slave_addr, mb_sock_state_t exp_state);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dependencies:
|
||||
idf: ">=4.3"
|
||||
espressif/esp-modbus:
|
||||
version: "^2.0"
|
||||
version: "^2.0.0-beta"
|
||||
override_path: "../../../../"
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
|
||||
#define TEST_MASTER_RESPOND_TOUT_MS CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND
|
||||
|
||||
#define TAG "MODBUS_SERIAL_TEST"
|
||||
#define TAG "MODBUS_CONTROLLER_COMMON_TEST"
|
||||
|
||||
// The workaround to statically link whole test library
|
||||
__attribute__((unused)) bool mb_test_include_impl = 1;
|
||||
__attribute__((unused)) bool mb_test_include_impl = true;
|
||||
|
||||
enum {
|
||||
CID_DEV_REG0_INPUT,
|
||||
@@ -34,7 +34,8 @@ enum {
|
||||
CID_DEV_REG1_INPUT,
|
||||
CID_DEV_REG0_COIL,
|
||||
CID_DEV_REG0_DISCRITE,
|
||||
CID_DEV_REG_CNT
|
||||
CID_DEV_REG_CNT,
|
||||
CID_ITEMS_CNT
|
||||
};
|
||||
|
||||
// Example Data (Object) Dictionary for Modbus parameters
|
||||
@@ -68,7 +69,42 @@ TEST_TEAR_DOWN(unit_test_controller)
|
||||
test_common_stop();
|
||||
}
|
||||
|
||||
TEST(unit_test_controller, test_setup_destroy_master)
|
||||
#if (CONFIG_FMB_COMM_MODE_TCP_EN)
|
||||
|
||||
TEST(unit_test_controller, test_setup_destroy_master_tcp)
|
||||
{
|
||||
mb_communication_info_t master_config = {
|
||||
.tcp_opts.port = TEST_TCP_PORT_NUM,
|
||||
.tcp_opts.mode = MB_TCP,
|
||||
.tcp_opts.addr_type = MB_IPV4,
|
||||
.tcp_opts.ip_addr_table = (void *)(0x44332211),
|
||||
.tcp_opts.uid = MB_DEVICE_ADDR1,
|
||||
.tcp_opts.start_disconnected = true,
|
||||
.tcp_opts.response_tout_ms = 1,
|
||||
.tcp_opts.test_tout_us = TEST_SLAVE_SEND_TOUT_US,
|
||||
.tcp_opts.ip_netif_ptr = (void *)(0x11223344)
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "TEST: Verify master create-destroy sequence TCP.");
|
||||
|
||||
void *mbm_handle = NULL;
|
||||
mb_base_t *pmb_base = NULL;
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_tcp_create(&master_config.tcp_opts, (void *)&pmb_base));
|
||||
|
||||
mbm_tcp_create_ExpectAnyArgsAndReturn(MB_ENOERR);
|
||||
mbm_tcp_create_ReturnThruPtr_in_out_obj((void **)&pmb_base);
|
||||
mbm_port_tcp_get_slave_info_IgnoreAndReturn((void *)(0x11223344));
|
||||
TEST_ESP_OK(mbc_master_create_tcp(&master_config, &mbm_handle));
|
||||
TEST_ESP_OK(mbc_master_set_descriptor(mbm_handle, &descriptors[0], num_descriptors));
|
||||
TEST_ESP_OK(mbc_master_delete(mbm_handle));
|
||||
ESP_LOGI(TAG, "Test passed successfully.");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_RTU_EN || CONFIG_FMB_COMM_MODE_ASCII_EN)
|
||||
|
||||
TEST(unit_test_controller, test_setup_destroy_master_serial)
|
||||
{
|
||||
mb_communication_info_t master_config = {
|
||||
.ser_opts.port = TEST_SER_PORT_NUM,
|
||||
@@ -86,7 +122,7 @@ TEST(unit_test_controller, test_setup_destroy_master)
|
||||
|
||||
void *mbm_handle = NULL;
|
||||
mb_base_t *pmb_base = NULL;
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_serial_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
|
||||
mbm_rtu_create_ExpectAnyArgsAndReturn(MB_ENOERR);
|
||||
mbm_rtu_create_ReturnThruPtr_in_out_obj((void **)&pmb_base);
|
||||
@@ -105,7 +141,7 @@ TEST(unit_test_controller, test_setup_destroy_master)
|
||||
ESP_LOGI(TAG, "Test passed successfully.");
|
||||
}
|
||||
|
||||
TEST(unit_test_controller, test_setup_destroy_slave)
|
||||
TEST(unit_test_controller, test_setup_destroy_slave_serial)
|
||||
{
|
||||
// Initialize and start Modbus controller
|
||||
mb_communication_info_t slave_config = {
|
||||
@@ -122,7 +158,7 @@ TEST(unit_test_controller, test_setup_destroy_slave)
|
||||
ESP_LOGI(TAG, "TEST: Verify slave create-destroy sequence.");
|
||||
void *mbs_handle = NULL;
|
||||
mb_base_t *pmb_base = mbs_handle;
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_create(&slave_config.ser_opts, (void *)&pmb_base));
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_serial_create(&slave_config.ser_opts, (void *)&pmb_base));
|
||||
mbs_rtu_create_ExpectAndReturn(&slave_config.ser_opts, (void *)pmb_base, MB_ENOERR);
|
||||
mbs_rtu_create_IgnoreArg_in_out_obj();
|
||||
mbs_rtu_create_ReturnThruPtr_in_out_obj((void **)&pmb_base);
|
||||
@@ -153,14 +189,14 @@ esp_err_t test_master_registers(int par_index, mb_err_enum_t mb_err)
|
||||
mb_base_t *pmb_base = NULL; // fake mb_base handle
|
||||
void *mbm_handle = NULL;
|
||||
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_serial_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
pmb_base->port_obj = (mb_port_base_t *)0x44556677;
|
||||
mbm_rtu_create_ExpectAnyArgsAndReturn(MB_ENOERR);
|
||||
mbm_rtu_create_ReturnThruPtr_in_out_obj((void **)&pmb_base);
|
||||
TEST_ESP_OK(mbc_master_create_serial(&master_config, &mbm_handle));
|
||||
TEST_ESP_OK(mbc_master_set_descriptor(mbm_handle, &descriptors[0], num_descriptors));
|
||||
mb_port_evt_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_evt_res_release_ExpectAnyArgs();
|
||||
mb_port_event_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_event_res_release_ExpectAnyArgs();
|
||||
TEST_ESP_OK(mbc_master_start(mbm_handle));
|
||||
|
||||
const mb_parameter_descriptor_t *param_descriptor = NULL;
|
||||
@@ -225,7 +261,7 @@ esp_err_t test_master_registers(int par_index, mb_err_enum_t mb_err)
|
||||
// Check if modbus controller object forms correct modbus request from data dictionary
|
||||
// and is able to transfer data using mb_object. Check possible errors returned back from
|
||||
// mb_object and make sure the modbus controller handles them correctly.
|
||||
TEST(unit_test_controller, test_master_send_request)
|
||||
TEST(unit_test_controller, test_master_send_request_serial)
|
||||
{
|
||||
TEST_ESP_ERR(ESP_OK, test_master_registers(CID_DEV_REG0_INPUT, MB_ENOERR));
|
||||
TEST_ESP_ERR(ESP_ERR_TIMEOUT, test_master_registers(CID_DEV_REG0_INPUT, MB_ETIMEDOUT));
|
||||
@@ -237,9 +273,19 @@ TEST(unit_test_controller, test_master_send_request)
|
||||
TEST_ESP_ERR(ESP_ERR_TIMEOUT, test_master_registers(CID_DEV_REG0_DISCRITE, MB_ETIMEDOUT));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST_GROUP_RUNNER(unit_test_controller)
|
||||
{
|
||||
RUN_TEST_CASE(unit_test_controller, test_setup_destroy_master);
|
||||
RUN_TEST_CASE(unit_test_controller, test_setup_destroy_slave);
|
||||
RUN_TEST_CASE(unit_test_controller, test_master_send_request);
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_RTU_EN || CONFIG_FMB_COMM_MODE_ASCII_EN)
|
||||
RUN_TEST_CASE(unit_test_controller, test_setup_destroy_master_serial);
|
||||
RUN_TEST_CASE(unit_test_controller, test_setup_destroy_slave_serial);
|
||||
RUN_TEST_CASE(unit_test_controller, test_master_send_request_serial);
|
||||
#endif
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_TCP_EN)
|
||||
RUN_TEST_CASE(unit_test_controller, test_setup_destroy_master_tcp);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ from pytest_embedded import Dut
|
||||
|
||||
|
||||
CONFIGS = [
|
||||
pytest.param('serial', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32c3]),
|
||||
pytest.param('generic', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32c3]),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.generic_multi_device
|
||||
@pytest.mark.multi_dut_modbus_generic
|
||||
@pytest.mark.parametrize('config', CONFIGS, indirect=True)
|
||||
def test_modbus_controller_common(dut: Dut) -> None:
|
||||
dut.expect_unity_test_output()
|
||||
|
||||
+2
-2
@@ -9,12 +9,12 @@ CONFIG_FMB_PORT_TASK_STACK_SIZE=4096
|
||||
CONFIG_FMB_PORT_TASK_PRIO=10
|
||||
CONFIG_FMB_COMM_MODE_RTU_EN=y
|
||||
CONFIG_FMB_COMM_MODE_ASCII_EN=y
|
||||
CONFIG_FMB_COMM_MODE_TCP_EN=n
|
||||
CONFIG_FMB_COMM_MODE_TCP_EN=y
|
||||
CONFIG_FMB_TCP_UID_ENABLED=y
|
||||
CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=2000
|
||||
CONFIG_FMB_MASTER_DELAY_MS_CONVERT=300
|
||||
CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD=y
|
||||
CONFIG_MB_PORT_ADAPTER_EN=y
|
||||
CONFIG_MB_PORT_ADAPTER_EN=n
|
||||
CONFIG_MB_TEST_SLAVE_TASK_PRIO=4
|
||||
CONFIG_MB_TEST_MASTER_TASK_PRIO=4
|
||||
CONFIG_MB_TEST_COMM_CYCLE_COUNTER=10
|
||||
+5
-5
@@ -73,11 +73,11 @@ extern "C" {
|
||||
typedef struct mb_base_t mb_base_t; /*!< Type of modbus object */
|
||||
typedef struct mb_port_base_t mb_port_base_t;
|
||||
|
||||
bool mb_port_evt_get(mb_port_base_t *inst, mb_event_t *pevent);
|
||||
bool mb_port_evt_post(mb_port_base_t *inst, mb_event_t event);
|
||||
bool mb_port_evt_res_take(mb_port_base_t *inst, uint32_t timeout);
|
||||
void mb_port_evt_res_release(mb_port_base_t *inst);
|
||||
mb_err_enum_t mb_port_evt_wait_req_finish(mb_port_base_t *inst);
|
||||
bool mb_port_event_get(mb_port_base_t *inst, mb_event_t *pevent);
|
||||
bool mb_port_event_post(mb_port_base_t *inst, mb_event_t event);
|
||||
bool mb_port_event_res_take(mb_port_base_t *inst, uint32_t timeout);
|
||||
void mb_port_event_res_release(mb_port_base_t *inst);
|
||||
mb_err_enum_t mb_port_event_wait_req_finish(mb_port_base_t *inst);
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_ASCII_EN || CONFIG_FMB_COMM_MODE_RTU_EN)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dependencies:
|
||||
idf: ">=4.3"
|
||||
espressif/esp-modbus:
|
||||
version: "^2.0"
|
||||
version: "^2.0.0-beta"
|
||||
override_path: "../../../../"
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#define TAG "MB_CONTROLLER_TEST"
|
||||
|
||||
// The workaround to statically link whole test library
|
||||
__attribute__((unused)) bool mb_test_include_impl = 1;
|
||||
__attribute__((unused)) bool mb_test_include_impl = true;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -106,7 +106,7 @@ static void test_slave_check_descriptor(int par_index)
|
||||
void *mbs_handle = NULL;
|
||||
mb_base_t *pmb_base = NULL; // fake mb_base handle
|
||||
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_create(&slave_config.ser_opts, (void *)&pmb_base));
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_serial_create(&slave_config.ser_opts, (void *)&pmb_base));
|
||||
pmb_base->port_obj = (mb_port_base_t *)0x44556677;
|
||||
mbs_rtu_create_ExpectAnyArgsAndReturn(MB_ENOERR);
|
||||
mbs_rtu_create_ReturnThruPtr_in_out_obj((void **)&pmb_base);
|
||||
@@ -173,15 +173,15 @@ static esp_err_t test_master_read_req(int par_index, mb_err_enum_t mb_err)
|
||||
mb_base_t *pmb_base = NULL; // fake mb_base handle
|
||||
void *mbm_handle = NULL;
|
||||
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_serial_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
pmb_base->port_obj = (mb_port_base_t *)0x44556677;
|
||||
mbm_rtu_create_ExpectAnyArgsAndReturn(MB_ENOERR);
|
||||
mbm_rtu_create_ReturnThruPtr_in_out_obj((void **)&pmb_base);
|
||||
TEST_ESP_OK(mbc_master_create_serial(&master_config, &mbm_handle));
|
||||
TEST_ESP_OK(mbc_master_set_descriptor(mbm_handle, &descriptors[0], num_descriptors));
|
||||
mb_port_evt_post_ExpectAndReturn(pmb_base->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START), true);
|
||||
mb_port_event_post_ExpectAndReturn(pmb_base->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START), true);
|
||||
TEST_ESP_OK(mbc_master_start(mbm_handle));
|
||||
mb_port_evt_wait_req_finish_ExpectAndReturn(pmb_base->port_obj, mb_err);
|
||||
mb_port_event_wait_req_finish_ExpectAndReturn(pmb_base->port_obj, mb_err);
|
||||
|
||||
const mb_parameter_descriptor_t *param_descriptor = NULL;
|
||||
TEST_ESP_OK(mbc_master_get_cid_info(mbm_handle, par_index, ¶m_descriptor));
|
||||
@@ -189,10 +189,10 @@ static esp_err_t test_master_read_req(int par_index, mb_err_enum_t mb_err)
|
||||
uint8_t type = 0; // type of parameter from dictionary
|
||||
uint8_t pdata[100] = {0};
|
||||
ESP_LOGI(TAG, "Test CID #%d, %s, %s", param_descriptor->cid, param_descriptor->param_key, param_descriptor->param_units);
|
||||
mb_port_evt_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_evt_res_release_ExpectAnyArgs();
|
||||
mb_port_evt_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_evt_res_release_ExpectAnyArgs();
|
||||
mb_port_event_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_event_res_release_ExpectAnyArgs();
|
||||
mb_port_event_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_event_res_release_ExpectAnyArgs();
|
||||
|
||||
// Call the read method of modbus controller
|
||||
esp_err_t err = mbc_master_get_parameter(mbm_handle, par_index, pdata, &type);
|
||||
@@ -264,14 +264,14 @@ static esp_err_t test_master_write_req(int par_index, mb_err_enum_t mb_err)
|
||||
mb_base_t *pmb_base = NULL; // fake mb_base handle
|
||||
void *mbm_handle = NULL;
|
||||
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_serial_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
pmb_base->port_obj = (mb_port_base_t *)0x44556677;
|
||||
mbm_rtu_create_ExpectAnyArgsAndReturn(MB_ENOERR);
|
||||
mbm_rtu_create_ReturnThruPtr_in_out_obj((void **)&pmb_base);
|
||||
TEST_ESP_OK(mbc_master_create_serial(&master_config, &mbm_handle));
|
||||
TEST_ESP_OK(mbc_master_set_descriptor(mbm_handle, &descriptors[0], num_descriptors));
|
||||
mb_port_evt_post_ExpectAndReturn(pmb_base->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START), true);
|
||||
mb_port_evt_wait_req_finish_ExpectAndReturn(pmb_base->port_obj, mb_err);
|
||||
mb_port_event_post_ExpectAndReturn(pmb_base->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START), true);
|
||||
mb_port_event_wait_req_finish_ExpectAndReturn(pmb_base->port_obj, mb_err);
|
||||
TEST_ESP_OK(mbc_master_start(mbm_handle));
|
||||
|
||||
const mb_parameter_descriptor_t *param_descriptor = NULL;
|
||||
@@ -280,10 +280,10 @@ static esp_err_t test_master_write_req(int par_index, mb_err_enum_t mb_err)
|
||||
uint8_t type = 0; // type of parameter from dictionary
|
||||
uint8_t reg_data[] = {0x11, 0x22, 0x33, 0x44};
|
||||
ESP_LOGI(TAG, "Test CID #%d, %s, %s", param_descriptor->cid, param_descriptor->param_key, param_descriptor->param_units);
|
||||
mb_port_evt_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_evt_res_release_ExpectAnyArgs();
|
||||
mb_port_evt_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_evt_res_release_ExpectAnyArgs();
|
||||
mb_port_event_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_event_res_release_ExpectAnyArgs();
|
||||
mb_port_event_res_take_ExpectAnyArgsAndReturn(true);
|
||||
mb_port_event_res_release_ExpectAnyArgs();
|
||||
|
||||
// Call the read method of modbus controller
|
||||
esp_err_t err = mbc_master_set_parameter(mbm_handle, par_index, reg_data, &type);
|
||||
@@ -350,7 +350,7 @@ static esp_err_t test_master_check_callback(int par_index, mb_err_enum_t mb_err)
|
||||
mb_base_t *pmb_base = NULL; // fake mb_base handle
|
||||
void *mbm_handle = NULL;
|
||||
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
TEST_ESP_ERR(MB_ENOERR, mb_stub_serial_create(&master_config.ser_opts, (void *)&pmb_base));
|
||||
pmb_base->port_obj = (mb_port_base_t *)0x44556677;
|
||||
mbm_rtu_create_ExpectAnyArgsAndReturn(MB_ENOERR);
|
||||
mbm_rtu_create_ReturnThruPtr_in_out_obj((void **)&pmb_base);
|
||||
|
||||
@@ -10,7 +10,7 @@ CONFIGS = [
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.generic_multi_device
|
||||
@pytest.mark.multi_dut_modbus_generic
|
||||
@pytest.mark.parametrize('config', CONFIGS, indirect=True)
|
||||
def test_modbus_controller_mapping(dut: Dut) -> None:
|
||||
dut.expect_unity_test_output()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dependencies:
|
||||
idf: ">=4.3"
|
||||
espressif/esp-modbus:
|
||||
version: "^2.0"
|
||||
version: "^2.0.0-beta"
|
||||
override_path: "../../../../"
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
#@pytest.mark.supported_targets
|
||||
@pytest.mark.esp32 # test on esp32 for now
|
||||
@pytest.mark.multi_dut_modbus_generic
|
||||
def test_mb_endianness_utils(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
@@ -11,4 +11,10 @@
|
||||
#include "mb_common.h"
|
||||
#include "mb_port_types.h"
|
||||
|
||||
mb_err_enum_t mb_stub_create(mb_serial_opts_t *ser_opts, void **in_out_obj);
|
||||
#if (CONFIG_FMB_COMM_MODE_TCP_EN)
|
||||
mb_err_enum_t mb_stub_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj);
|
||||
#endif
|
||||
|
||||
#if (MB_MASTER_ASCII_ENABLED || MB_MASTER_RTU_ENABLED)
|
||||
mb_err_enum_t mb_stub_serial_create(mb_serial_opts_t *ser_opts, void **in_out_obj);
|
||||
#endif
|
||||
|
||||
@@ -24,10 +24,9 @@ typedef struct
|
||||
mb_base_t base;
|
||||
uint16_t pdu_snd_len;
|
||||
uint8_t dst_addr;
|
||||
uint8_t snd_buf[MB_RTU_SER_PDU_SIZE_MAX];
|
||||
uint8_t snd_buf[MB_BUFFER_SIZE];
|
||||
} mb_object_t;
|
||||
|
||||
mb_err_enum_t mb_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj);
|
||||
|
||||
mb_err_enum_t mb_delete(mb_base_t *inst);
|
||||
mb_err_enum_t mb_enable(mb_base_t *inst);
|
||||
@@ -40,11 +39,49 @@ static void mb_set_dest_addr(mb_base_t *inst, uint8_t dest_addr);
|
||||
static uint8_t mb_get_dest_addr(mb_base_t *inst);
|
||||
static void mb_get_pdu_send_buf(mb_base_t *inst, uint8_t **pbuf);
|
||||
|
||||
//mb_err_enum_t mb_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj);
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_TCP_EN)
|
||||
|
||||
mb_err_enum_t mb_stub_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj)
|
||||
{
|
||||
MB_RETURN_ON_FALSE((tcp_opts && in_out_obj), MB_EINVAL, TAG, "invalid options for the instance.");
|
||||
mb_err_enum_t ret = MB_ENOERR;
|
||||
mb_object_t *mb_obj = NULL;
|
||||
mb_obj = (mb_object_t *)calloc(1, sizeof(mb_object_t));
|
||||
MB_GOTO_ON_FALSE((mb_obj), MB_EILLSTATE, error, TAG, "no mem for mb master instance.");
|
||||
CRITICAL_SECTION_INIT(mb_obj->base.lock);
|
||||
ESP_LOGW(TAG, "Create fake mb_base object.");
|
||||
mb_obj->base.delete = mb_delete;
|
||||
mb_obj->base.enable = mb_enable;
|
||||
mb_obj->base.disable = mb_disable;
|
||||
mb_obj->base.poll = mb_poll;
|
||||
mb_obj->base.set_dest_addr = mb_set_dest_addr;
|
||||
mb_obj->base.get_dest_addr = mb_get_dest_addr;
|
||||
mb_obj->base.set_send_len = mb_set_pdu_send_length;
|
||||
mb_obj->base.get_send_len = mb_get_pdu_send_length;
|
||||
mb_obj->base.get_send_buf = mb_get_pdu_send_buf;
|
||||
mb_obj->base.descr.parent = *in_out_obj;
|
||||
mb_obj->base.descr.is_master = true;
|
||||
mb_obj->base.descr.obj_name = (char *)TAG;
|
||||
mb_obj->base.descr.inst_index = mb_port_get_inst_counter_inc();
|
||||
*in_out_obj = (void *)mb_obj;
|
||||
return MB_ENOERR;
|
||||
|
||||
error:
|
||||
CRITICAL_SECTION_CLOSE(mb_obj->base.lock);
|
||||
free(mb_obj);
|
||||
mb_port_get_inst_counter_dec();
|
||||
ESP_LOGW(TAG, "Delete fake mb_base object.");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (MB_MASTER_ASCII_ENABLED || MB_MASTER_RTU_ENABLED)
|
||||
|
||||
typedef struct _port_serial_opts mb_serial_opts_t;
|
||||
|
||||
mb_err_enum_t mb_stub_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
|
||||
mb_err_enum_t mb_stub_serial_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
|
||||
{
|
||||
MB_RETURN_ON_FALSE((ser_opts && in_out_obj), MB_EINVAL, TAG, "invalid options for the instance.");
|
||||
mb_err_enum_t ret = MB_ENOERR;
|
||||
@@ -146,13 +183,7 @@ mb_err_enum_t mb_poll(mb_base_t *inst)
|
||||
{
|
||||
mb_err_enum_t status = MB_ENOERR;
|
||||
ESP_LOGW(TAG, "Poll function called of fake mb_base object.");
|
||||
//mb_object_t *mb_obj = __containerof(inst, mb_object_t, base);
|
||||
vTaskDelay(1);
|
||||
//mb_port_evt_get_ExpectAnyArgsAndReturn(true);
|
||||
// mb_event_t event = {0};
|
||||
// if (mb_port_evt_get(mb_obj->base.port_obj, &event)) {
|
||||
|
||||
// }
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ typedef struct
|
||||
uint16_t snd_buf_cnt;
|
||||
uint16_t rcv_buf_pos;
|
||||
bool frame_is_broadcast;
|
||||
volatile mb_tmr_mode_enum_t cur_tmr_mode;
|
||||
volatile mb_timer_mode_enum_t cur_timer_mode;
|
||||
mb_rtu_state_enum_t state;
|
||||
} mbm_rtu_transp_t;
|
||||
|
||||
@@ -36,7 +36,7 @@ static mb_err_enum_t mbm_rtu_transp_receive(mb_trans_base_t *inst, uint8_t *rcv_
|
||||
static mb_err_enum_t mbm_rtu_transp_send(mb_trans_base_t *inst, uint8_t slv_addr, const uint8_t *frame_ptr, uint16_t len);
|
||||
static bool mbm_rtu_transp_rcv_fsm(mb_trans_base_t *inst);
|
||||
static bool mbm_rtu_transp_snd_fsm(mb_trans_base_t *inst);
|
||||
static bool mbm_rtu_transp_tmr_35_expired(void *inst);
|
||||
static bool mbm_rtu_transp_timer_expired(void *inst);
|
||||
static void mbm_rtu_transp_get_snd_buf(mb_trans_base_t *inst, uint8_t **frame_ptr_buf);
|
||||
static void mbm_rtu_transp_get_rcv_buf(mb_trans_base_t *inst, uint8_t **frame_ptr_buf);
|
||||
// static uint16_t mbm_rtu_transp_get_snd_len(mb_trans_base_t *inst);
|
||||
@@ -67,17 +67,17 @@ mb_err_enum_t mbm_rtu_transp_create(mb_serial_opts_t *ser_opts, void **in_out_in
|
||||
mb_port_base_t *port_obj = (mb_port_base_t *)*in_out_inst;
|
||||
ret = mb_port_ser_create(ser_opts, &port_obj);
|
||||
MB_GOTO_ON_FALSE((ret == MB_ENOERR), MB_EILLSTATE, error, TAG, "serial port creation, err: %d", ret);
|
||||
ret = mb_port_tmr_create(port_obj, MB_RTU_GET_T35_VAL(ser_opts->baudrate));
|
||||
ret = mb_port_timer_create(port_obj, MB_RTU_GET_T35_VAL(ser_opts->baudrate));
|
||||
MB_GOTO_ON_FALSE((ret == MB_ENOERR), MB_EILLSTATE, error, TAG, "timer port creation, err: %d", ret);
|
||||
// Override default response time if defined
|
||||
if (ser_opts->response_tout_ms) {
|
||||
mb_port_tmr_set_response_time(port_obj, ser_opts->response_tout_ms);
|
||||
mb_port_timer_set_response_time(port_obj, ser_opts->response_tout_ms);
|
||||
}
|
||||
ret = mb_port_evt_create(port_obj);
|
||||
ret = mb_port_event_create(port_obj);
|
||||
MB_GOTO_ON_FALSE((ret == MB_ENOERR), MB_EILLSTATE, error, TAG, "event port creation, err: %d", ret);
|
||||
transp->base.port_obj = port_obj;
|
||||
// Set callback function pointer for the timer
|
||||
port_obj->cb.tmr_expired = mbm_rtu_transp_tmr_35_expired;
|
||||
port_obj->cb.tmr_expired = mbm_rtu_transp_timer_expired;
|
||||
port_obj->cb.tx_empty = NULL;
|
||||
port_obj->cb.byte_rcvd = NULL;
|
||||
port_obj->arg = (void *)transp;
|
||||
@@ -89,10 +89,10 @@ mb_err_enum_t mbm_rtu_transp_create(mb_serial_opts_t *ser_opts, void **in_out_in
|
||||
|
||||
error:
|
||||
if (port_obj->timer_obj) {
|
||||
mb_port_tmr_delete(port_obj);
|
||||
mb_port_timer_delete(port_obj);
|
||||
}
|
||||
if (port_obj->event_obj) {
|
||||
mb_port_evt_delete(port_obj);
|
||||
mb_port_event_delete(port_obj);
|
||||
}
|
||||
if (port_obj) {
|
||||
mb_port_ser_delete(port_obj);
|
||||
@@ -106,8 +106,8 @@ bool mbm_rtu_transp_delete(mb_trans_base_t *inst)
|
||||
{
|
||||
mbm_rtu_transp_t *transp = __containerof(inst, mbm_rtu_transp_t, base);
|
||||
mb_port_ser_delete(transp->base.port_obj);
|
||||
mb_port_tmr_delete(transp->base.port_obj);
|
||||
mb_port_evt_delete(transp->base.port_obj);
|
||||
mb_port_timer_delete(transp->base.port_obj);
|
||||
mb_port_event_delete(transp->base.port_obj);
|
||||
CRITICAL_SECTION_CLOSE(inst->lock);
|
||||
free(transp);
|
||||
return true;
|
||||
@@ -119,17 +119,17 @@ static void mbm_rtu_transp_start(mb_trans_base_t *inst)
|
||||
transp->state = MB_RTU_STATE_INIT;
|
||||
CRITICAL_SECTION(inst->lock) {
|
||||
mb_port_ser_enable(inst->port_obj);
|
||||
mb_port_tmr_enable(inst->port_obj);
|
||||
mb_port_timer_enable(inst->port_obj);
|
||||
};
|
||||
/* No special startup required for RTU. */
|
||||
(void)mb_port_evt_post(transp->base.port_obj, EVENT(EV_READY));
|
||||
(void)mb_port_event_post(transp->base.port_obj, EVENT(EV_READY));
|
||||
}
|
||||
|
||||
static void mbm_rtu_transp_stop(mb_trans_base_t *inst)
|
||||
{
|
||||
CRITICAL_SECTION(inst->lock) {
|
||||
mb_port_ser_disable(inst->port_obj);
|
||||
mb_port_tmr_disable(inst->port_obj);
|
||||
mb_port_timer_disable(inst->port_obj);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -207,9 +207,9 @@ static mb_err_enum_t mbm_rtu_transp_send(mb_trans_base_t *inst, uint8_t slv_addr
|
||||
// If the frame is broadcast, master will enable timer of convert delay,
|
||||
// else master will enable timer of respond timeout. */
|
||||
if (transp->frame_is_broadcast) {
|
||||
mb_port_tmr_convert_delay_enable(transp->base.port_obj);
|
||||
mb_port_timer_convert_delay_enable(transp->base.port_obj);
|
||||
} else {
|
||||
mb_port_tmr_respond_timeout_enable(transp->base.port_obj);
|
||||
mb_port_timer_respond_timeout_enable(transp->base.port_obj);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -231,35 +231,35 @@ static bool mbm_rtu_transp_snd_fsm(mb_trans_base_t *inst)
|
||||
}
|
||||
|
||||
|
||||
static bool mbm_rtu_transp_tmr_35_expired(void *inst)
|
||||
static bool mbm_rtu_transp_timer_expired(void *inst)
|
||||
{
|
||||
mbm_rtu_transp_t *transp = __containerof(inst, mbm_rtu_transp_t, base);
|
||||
|
||||
bool need_poll = false;
|
||||
mb_tmr_mode_enum_t timer_mode = mb_port_get_cur_tmr_mode(transp->base.port_obj);
|
||||
mb_timer_mode_enum_t timer_mode = mb_port_get_cur_timer_mode(transp->base.port_obj);
|
||||
|
||||
mb_port_tmr_disable(transp->base.port_obj);
|
||||
mb_port_timer_disable(transp->base.port_obj);
|
||||
|
||||
switch(timer_mode) {
|
||||
case MB_TMODE_T35:
|
||||
//need_poll = mb_port_evt_post(transp->base.port_obj, EVENT(EV_READY));
|
||||
//need_poll = mb_port_event_post(transp->base.port_obj, EVENT(EV_READY));
|
||||
//ESP_EARLY_LOGD(TAG, "%p:EV_READY", transp->base.descr.parent);
|
||||
break;
|
||||
|
||||
case MB_TMODE_RESPOND_TIMEOUT:
|
||||
mb_port_evt_set_err_type(transp->base.port_obj, EV_ERROR_RESPOND_TIMEOUT);
|
||||
need_poll = mb_port_evt_post(transp->base.port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
mb_port_event_set_err_type(transp->base.port_obj, EV_ERROR_RESPOND_TIMEOUT);
|
||||
need_poll = mb_port_event_post(transp->base.port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
ESP_EARLY_LOGW(TAG, "%p:EV_ERROR_RESPOND_TIMEOUT", transp->base.descr.parent);
|
||||
break;
|
||||
|
||||
case MB_TMODE_CONVERT_DELAY:
|
||||
/* If timer mode is convert delay, the master event then turns EV_MASTER_EXECUTE status. */
|
||||
need_poll = mb_port_evt_post(transp->base.port_obj, EVENT(EV_EXECUTE));
|
||||
need_poll = mb_port_event_post(transp->base.port_obj, EVENT(EV_EXECUTE));
|
||||
ESP_EARLY_LOGD(TAG, "%p:MB_TMODE_CONVERT_DELAY", transp->base.descr.parent);
|
||||
break;
|
||||
|
||||
default:
|
||||
need_poll = mb_port_evt_post(transp->base.port_obj, EVENT(EV_READY));
|
||||
need_poll = mb_port_event_post(transp->base.port_obj, EVENT(EV_READY));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user