forked from espressif/esp-modbus
Merge branch 'feature/add_slave_id_command_v2' into 'main'
add slave report id command for master and slave (backport v2) See merge request idf/esp-modbus!97
This commit is contained in:
commit
877d331b4b
31 files changed
+663
-167
No files matched your search
@@ -73,7 +73,6 @@ mb_exception_t mbs_fn_write_holding_reg(mb_base_t *inst, uint8_t *frame_ptr, uin
|
||||
reg_addr = (uint16_t)(frame_ptr[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8);
|
||||
reg_addr |= (uint16_t)(frame_ptr[MB_PDU_FUNC_WRITE_ADDR_OFF + 1]);
|
||||
reg_addr++;
|
||||
|
||||
/* Make callback to update the value. */
|
||||
if (inst->rw_cbs.reg_holding_cb) {
|
||||
reg_status = inst->rw_cbs.reg_holding_cb(inst, &frame_ptr[MB_PDU_FUNC_WRITE_VALUE_OFF], reg_addr, 1, MB_REG_WRITE);
|
||||
|
||||
@@ -28,29 +28,109 @@
|
||||
*
|
||||
* File: $Id: mbfuncother.c, v 1.8 2006/12/07 22:10:34 wolti Exp $
|
||||
*/
|
||||
|
||||
#include <mb_common.h>
|
||||
#include <mb_proto.h>
|
||||
#include <sys/param.h>
|
||||
#include "mb_common.h"
|
||||
#include "mb_proto.h"
|
||||
#include "mb_slave.h"
|
||||
#include "mb_master.h"
|
||||
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED && MB_FUNC_OTHER_REP_SLAVEID_BUF
|
||||
|
||||
#define MB_PDU_BYTECNT_OFF (MB_PDU_DATA_OFF + 0)
|
||||
#define MB_PDU_FUNC_DATA_OFF (MB_PDU_DATA_OFF + 1)
|
||||
#define MB_CMD_SL_ID_LEN (1)
|
||||
#define MB_SLAVE_ID_CHUNK_SIZE (MIN(MB_FUNC_OTHER_REP_SLAVEID_BUF, 32))
|
||||
|
||||
/* ----------------------- Start implementation -----------------------------*/
|
||||
mb_err_enum_t mb_set_slv_id(mb_base_t *inst, uint8_t slv_id, bool is_running, uint8_t const *slv_idstr, uint16_t slv_idstr_len)
|
||||
{
|
||||
mb_err_enum_t status = MB_ENOERR;
|
||||
mb_exception_t mb_error_to_exception(mb_err_enum_t error_code);
|
||||
|
||||
/* the first byte and second byte in the buffer is reserved for
|
||||
* the parameter slv_id and the running flag. The rest of
|
||||
* the buffer is available for additional data. */
|
||||
if (slv_idstr_len + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF) {
|
||||
inst->slave_id_len = 0;
|
||||
inst->slave_id[inst->slave_id_len++] = slv_id;
|
||||
inst->slave_id[inst->slave_id_len++] = (uint8_t)(is_running ? 0xFF : 0x00);
|
||||
if (slv_idstr_len > 0) {
|
||||
memcpy(&inst->slave_id[inst->slave_id_len], slv_idstr,
|
||||
(size_t)slv_idstr_len);
|
||||
inst->slave_id_len += slv_idstr_len;
|
||||
mb_err_enum_t mbm_rq_report_slave_id(mb_base_t *inst, uint8_t slave_addr, uint32_t timeout)
|
||||
{
|
||||
uint8_t *mb_frame_ptr = NULL;
|
||||
mb_err_enum_t err = MB_ENOERR;
|
||||
if (!inst || !inst->port_obj || (slave_addr > MB_ADDRESS_MAX)) {
|
||||
err = MB_EINVAL;
|
||||
} else if (!mb_port_event_res_take(inst->port_obj, timeout)) {
|
||||
err = MB_EBUSY;
|
||||
} else {
|
||||
inst->get_send_buf(inst, &mb_frame_ptr);
|
||||
inst->set_dest_addr(inst, slave_addr);
|
||||
mb_frame_ptr[MB_PDU_FUNC_OFF] = MB_FUNC_OTHER_REPORT_SLAVEID;
|
||||
inst->set_send_len(inst, MB_CMD_SL_ID_LEN);
|
||||
(void)mb_port_event_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START));
|
||||
err = mb_port_event_wait_req_finish(inst->port_obj);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
mb_exception_t mbm_fn_report_slave_id(mb_base_t *inst, uint8_t *pframe, uint16_t *plen)
|
||||
{
|
||||
uint8_t byte_count = 0;
|
||||
mb_exception_t status = MB_EX_NONE;
|
||||
mb_err_enum_t err;
|
||||
|
||||
if (!inst || !plen || !pframe) {
|
||||
status = MB_EX_SLAVE_DEVICE_FAILURE;
|
||||
} else if (*plen <= MB_BUFFER_SIZE - 2) {
|
||||
byte_count = pframe[MB_PDU_BYTECNT_OFF];
|
||||
// Transfer data from command buffer.
|
||||
err = mbc_reg_common_cb(inst, &pframe[MB_PDU_FUNC_DATA_OFF], 0, byte_count);
|
||||
// If an err occured convert it into a Modbus exception.
|
||||
if (err != MB_ENOERR) {
|
||||
status = mb_error_to_exception(err);
|
||||
}
|
||||
} else {
|
||||
// Can't be a valid request because the length is incorrect.
|
||||
status = MB_EX_ILLEGAL_DATA_VALUE;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
mb_exception_t mbs_fn_report_slave_id(mb_base_t *inst, uint8_t *pframe, uint16_t *plen_buf)
|
||||
{
|
||||
mb_exception_t status = MB_EX_NONE;
|
||||
if (!inst || !pframe || !plen_buf || !inst->pobj_id || !inst->obj_id_len) {
|
||||
status = MB_EX_SLAVE_DEVICE_FAILURE;
|
||||
} else if ((inst->obj_id_len <= MB_BUFFER_SIZE - 2)
|
||||
&& (*plen_buf == MB_CMD_SL_ID_LEN)) {
|
||||
CRITICAL_SECTION(inst->lock) {
|
||||
pframe[MB_PDU_FUNC_OFF] = MB_FUNC_OTHER_REPORT_SLAVEID; // rewrite the FC
|
||||
*plen_buf = (uint16_t)(inst->obj_id_len);
|
||||
pframe[MB_PDU_BYTECNT_OFF] = *plen_buf;
|
||||
memcpy(&pframe[MB_PDU_FUNC_DATA_OFF], inst->pobj_id, (size_t)inst->obj_id_len);
|
||||
*plen_buf += 2; // count function code + length in frame length
|
||||
}
|
||||
} else {
|
||||
status = MB_EX_ILLEGAL_DATA_VALUE;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
mb_err_enum_t mbs_set_slave_id(mb_base_t *inst, uint8_t slave_id, bool is_running, uint8_t const *pdata, uint8_t data_len)
|
||||
{
|
||||
mb_err_enum_t status = MB_ENOERR;
|
||||
// the first byte and second byte in the buffer is reserved for
|
||||
// the parameter slave_id and the running flag. The rest of
|
||||
// the buffer is available for additional data.
|
||||
if (inst && inst->lock && (data_len + 2 <= MB_FUNC_OTHER_REP_SLAVEID_BUF)) {
|
||||
uint8_t chunk_num = ((data_len + 2) / MB_SLAVE_ID_CHUNK_SIZE) + 1;
|
||||
if (!inst->pobj_id || inst->obj_id_chunks != chunk_num) {
|
||||
CRITICAL_SECTION(inst->lock) {
|
||||
inst->pobj_id = realloc(inst->pobj_id, (chunk_num * MB_SLAVE_ID_CHUNK_SIZE));
|
||||
}
|
||||
}
|
||||
if (!inst->pobj_id) {
|
||||
return MB_ENORES;
|
||||
}
|
||||
CRITICAL_SECTION(inst->lock) {
|
||||
inst->obj_id_len = 0;
|
||||
inst->pobj_id[inst->obj_id_len++] = slave_id;
|
||||
inst->pobj_id[inst->obj_id_len++] = (uint8_t)(is_running ? 0xFF : 0x00);
|
||||
if (data_len > 0) {
|
||||
memcpy(&inst->pobj_id[inst->obj_id_len], pdata, (size_t)data_len);
|
||||
inst->obj_id_len += data_len;
|
||||
inst->obj_id_chunks = chunk_num;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = MB_ENORES;
|
||||
@@ -58,11 +138,25 @@ mb_err_enum_t mb_set_slv_id(mb_base_t *inst, uint8_t slv_id, bool is_running, ui
|
||||
return status;
|
||||
}
|
||||
|
||||
mb_exception_t mb_fn_report_slv_id(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
mb_err_enum_t mbs_get_slave_id(mb_base_t *inst, uint8_t *pdata, uint8_t *pdata_len)
|
||||
{
|
||||
memcpy(&frame_ptr[MB_PDU_DATA_OFF], &inst->slave_id[0], (size_t)inst->slave_id_len);
|
||||
*len_buf = (uint16_t)(MB_PDU_DATA_OFF + inst->slave_id_len);
|
||||
return MB_EX_NONE;
|
||||
mb_err_enum_t status = MB_ENOERR;
|
||||
if (inst && inst->lock && pdata_len) {
|
||||
if (!inst->pobj_id) {
|
||||
return MB_ENOREG;
|
||||
}
|
||||
if (pdata && (*pdata_len >= inst->obj_id_len)) {
|
||||
CRITICAL_SECTION(inst->lock) {
|
||||
memcpy(pdata, &inst->pobj_id[0],(size_t)inst->obj_id_len);
|
||||
}
|
||||
} else {
|
||||
status = MB_ENORES;
|
||||
}
|
||||
*pdata_len = inst->obj_id_len;
|
||||
} else {
|
||||
status = MB_EINVAL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -126,3 +126,4 @@ mb_exception_t mb_error_to_exception(mb_err_enum_t error_code)
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,8 +133,11 @@ struct mb_base_t
|
||||
mb_trans_base_t *transp_obj;
|
||||
mb_port_base_t *port_obj;
|
||||
|
||||
uint8_t slave_id[MB_FUNC_OTHER_REP_SLAVEID_BUF];
|
||||
uint16_t slave_id_len;
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
uint8_t *pobj_id;
|
||||
uint16_t obj_id_len;
|
||||
uint8_t obj_id_chunks;
|
||||
#endif
|
||||
|
||||
mb_delete_fp delete;
|
||||
mb_enable_fp enable;
|
||||
@@ -166,7 +169,6 @@ mb_err_enum_t mbs_delete(mb_base_t *inst);
|
||||
mb_err_enum_t mbs_enable(mb_base_t *inst);
|
||||
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_RTU_EN || CONFIG_FMB_COMM_MODE_ASCII_EN)
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ extern "C" {
|
||||
* how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
* is set to <code>1</code>.
|
||||
*/
|
||||
#define MB_FUNC_OTHER_REP_SLAVEID_BUF (32)
|
||||
#define MB_FUNC_OTHER_REP_SLAVEID_BUF (CONFIG_FMB_CONTROLLER_SLAVE_ID_MAX_SIZE)
|
||||
|
||||
/*! \brief If the <em>Report Slave ID</em> function should be enabled. */
|
||||
#define MB_FUNC_OTHER_REP_SLAVEID_ENABLED (CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT)
|
||||
|
||||
@@ -14,9 +14,9 @@ extern "C" {
|
||||
|
||||
typedef struct mb_base_t mb_base_t;
|
||||
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_BUF
|
||||
mb_exception_t mb_fn_report_slv_id(mb_base_t *inst, uint8_t *frame_ptr,uint16_t *len_buf);
|
||||
mb_exception_t mbm_fn_report_slv_id(mb_base_t *inst, uint8_t *frame_ptr,uint16_t *len_buf);
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mb_exception_t mbs_fn_report_slave_id(mb_base_t *inst, uint8_t *frame_ptr,uint16_t *len_buf);
|
||||
mb_exception_t mbm_fn_report_slave_id(mb_base_t *inst, uint8_t *frame_ptr,uint16_t *len_buf);
|
||||
#endif
|
||||
|
||||
#if MB_FUNC_READ_INPUT_ENABLED
|
||||
|
||||
@@ -23,6 +23,27 @@ mb_err_enum_t mbm_rq_read_coils(mb_base_t *inst, uint8_t snd_addr, uint16_t coil
|
||||
mb_err_enum_t mbm_rq_write_coil(mb_base_t *inst, uint8_t snd_addr, uint16_t coil_addr, uint16_t coil_data, uint32_t tout);
|
||||
mb_err_enum_t mbm_rq_write_multi_coils(mb_base_t *inst, uint8_t snd_addr, uint16_t coil_addr, uint16_t coil_num, uint8_t *data_ptr, uint32_t tout);
|
||||
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mb_err_enum_t mbm_rq_report_slave_id(mb_base_t *inst, uint8_t slave_addr, uint32_t timeout);
|
||||
mb_exception_t mbm_fn_report_slave_id(mb_base_t *inst, uint8_t * pframe, uint16_t *usLen);
|
||||
|
||||
/*! \ingroup modbus_registers
|
||||
* \brief The common callback function used to transfer common data as bytes from command buffer in little endian format.
|
||||
*
|
||||
* \param pdata A pointer to data in command buffer to be transferred.
|
||||
* \param address Unused for this function == 0.
|
||||
* \param bytes Number of bytes the callback function must supply.
|
||||
*
|
||||
* \return The function must return one of the following error codes:
|
||||
* - mb_err_enum_t::MB_ENOERR If no error occurred. In this case a normal
|
||||
* Modbus response is sent.
|
||||
* - mb_err_enum_t::MB_ENOREG if can not map the data of the registers
|
||||
* - mb_err_enum_t::MB_EILLSTATE if can not procceed with data transfer due to critical error
|
||||
* - mb_err_enum_t::MB_EINVAL if value data can not be transferred
|
||||
*/
|
||||
mb_err_enum_t mbc_reg_common_cb(mb_base_t *inst, uint8_t *pdata, uint16_t address, uint16_t bytes);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -11,8 +11,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
mb_err_enum_t mb_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 MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mb_exception_t mbs_fn_report_slave_id(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *plen_buf);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -100,23 +100,39 @@ void mb_util_set_bits(uint8_t *byte_buf, uint16_t bit_offset, uint8_t but_num, u
|
||||
*/
|
||||
uint8_t mb_util_get_bits(uint8_t *byte_buf, uint16_t bit_offset, uint8_t but_num);
|
||||
|
||||
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
/*! \brief Standard function to set slave ID in the modbus object.
|
||||
*
|
||||
* This function is used to set the Slave ID array for modbus object.
|
||||
* This ID can then be read over Modbus.
|
||||
*
|
||||
* \param inst - instance pointer to base modbus object
|
||||
* \param slv_id - slave short address.
|
||||
* \param slave_id - slave short address.
|
||||
* \param is_running - true, if the slave is running, false otherwise
|
||||
* \param slv_idstr - the pointer to slave ID array to set in the modbus object
|
||||
* \param slv_idstr_len - slave ID array length
|
||||
* \param pdata - the pointer to slave ID array to set in the modbus object
|
||||
* \param len - slave ID array length
|
||||
*
|
||||
* returns the modbus error code = MB_ENOERR, if set correctly, MB_ENOREG, otherwise
|
||||
* \endcode
|
||||
*/
|
||||
mb_err_enum_t mb_set_slv_id(mb_base_t *inst, uint8_t slv_id, bool is_running, uint8_t const *slv_idstr, uint16_t slv_idstr_len);
|
||||
mb_err_enum_t mbs_set_slave_id(mb_base_t *inst, uint8_t sl_id, bool is_running, uint8_t const *pdata, uint16_t len);
|
||||
|
||||
/*! \brief Standard function to get slave ID from the modbus object.
|
||||
*
|
||||
* This function is used to get the Slave ID array for modbus object.
|
||||
* This ID can then be read over Modbus.
|
||||
*
|
||||
* \param inst - instance pointer to base modbus object
|
||||
* \param pdata - the pointer to store object ID array from the modbus object
|
||||
* \param[in/out] pdata_len - input length of the allocated pdata array,
|
||||
* returns the actual length of object id.
|
||||
* returns the modbus error code = MB_ENOERR, if set correctly,
|
||||
* MB_ENOREG - if the object ID is not set,
|
||||
* MB_ENORES - no space to store object ID in the pdata buffer,
|
||||
* MB_EINVAL - the arguments are not correct
|
||||
*/
|
||||
mb_err_enum_t mbs_get_slave_id(mb_base_t *inst, uint8_t *pdata, uint8_t *pdata_len);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ static const char *TAG = "mb_object.master";
|
||||
static const mb_fn_handler_t master_handlers[MB_FUNC_HANDLERS_MAX] =
|
||||
{
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
{MB_FUNC_OTHER_REPORT_SLAVEID, (void *)mb_fn_report_slv_id},
|
||||
{MB_FUNC_OTHER_REPORT_SLAVEID, (void *)mbm_fn_report_slave_id},
|
||||
#endif
|
||||
#if MB_FUNC_READ_INPUT_ENABLED
|
||||
{MB_FUNC_READ_INPUT_REGISTER, (void *)mbm_fn_read_inp_reg},
|
||||
@@ -109,6 +109,11 @@ mb_err_enum_t mbm_rtu_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
|
||||
mbm_obj->base.descr.is_master = true;
|
||||
mbm_obj->base.descr.obj_name = (char *)TAG;
|
||||
mbm_obj->base.descr.inst_index = mb_port_get_inst_counter_inc();
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mbm_obj->base.pobj_id = NULL;
|
||||
mbm_obj->base.obj_id_len = 0;
|
||||
mbm_obj->base.obj_id_chunks = 0;
|
||||
#endif
|
||||
int res = asprintf(&mbm_obj->base.descr.parent_name, "mbm_rtu@%p", mbm_obj->base.descr.parent);
|
||||
MB_GOTO_ON_FALSE((res), MB_EILLSTATE, error,
|
||||
TAG, "name alloc fail, err: %d", (int)res);
|
||||
@@ -166,6 +171,11 @@ mb_err_enum_t mbm_ascii_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
|
||||
mbm_obj->base.descr.is_master = true;
|
||||
mbm_obj->base.descr.obj_name = (char *)TAG;
|
||||
mbm_obj->base.descr.inst_index = mb_port_get_inst_counter_inc();
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mbm_obj->base.pobj_id = NULL;
|
||||
mbm_obj->base.obj_id_len = 0;
|
||||
mbm_obj->base.obj_id_chunks = 0;
|
||||
#endif
|
||||
int res = asprintf(&mbm_obj->base.descr.parent_name, "mbm_ascii@%p", mbm_obj->base.descr.parent);
|
||||
MB_GOTO_ON_FALSE((res), MB_EILLSTATE, error,
|
||||
TAG, "name alloc fail, err: %d", (int)res);
|
||||
@@ -223,6 +233,11 @@ mb_err_enum_t mbm_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj)
|
||||
mbm_obj->base.descr.is_master = true;
|
||||
mbm_obj->base.descr.obj_name = (char *)TAG;
|
||||
mbm_obj->base.descr.inst_index = mb_port_get_inst_counter_inc();
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mbm_obj->base.pobj_id = NULL;
|
||||
mbm_obj->base.obj_id_len = 0;
|
||||
mbm_obj->base.obj_id_chunks = 0;
|
||||
#endif
|
||||
int res = asprintf(&mbm_obj->base.descr.parent_name, "mbm_tcp#%p", mbm_obj->base.descr.parent);
|
||||
MB_GOTO_ON_FALSE((res), MB_EILLSTATE, error,
|
||||
TAG, "name alloc fail, err: %d", (int)res);
|
||||
@@ -263,6 +278,16 @@ mb_err_enum_t mbm_delete(mb_base_t *inst)
|
||||
// call destructor of the transport object
|
||||
mbm_obj->base.transp_obj->frm_delete(inst->transp_obj);
|
||||
}
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
// check object ID
|
||||
if (mbm_obj->base.pobj_id) {
|
||||
free(mbm_obj->base.pobj_id);
|
||||
mbm_obj->base.pobj_id = NULL;
|
||||
mbm_obj->base.obj_id_len = 0;
|
||||
mbm_obj->base.obj_id_chunks = 0;
|
||||
ESP_LOGW(TAG, "%p, Master object ID is not supported!", mbm_obj);
|
||||
}
|
||||
#endif
|
||||
// delete the modbus instance
|
||||
free(mbm_obj->base.descr.parent_name);
|
||||
CRITICAL_SECTION_CLOSE(inst->lock);
|
||||
|
||||
@@ -18,10 +18,32 @@ static const char *TAG = "mb_object.slave";
|
||||
|
||||
#if (MB_SLAVE_ASCII_ENABLED || MB_SLAVE_RTU_ENABLED || MB_TCP_ENABLED)
|
||||
|
||||
#if (MB_SLAVE_ASCII_ENABLED || MB_SLAVE_RTU_ENABLED)
|
||||
|
||||
typedef struct _port_serial_opts mb_serial_opts_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mb_base_t base;
|
||||
// here are slave object properties and methods
|
||||
uint8_t mb_address;
|
||||
mb_comm_mode_t cur_mode;
|
||||
const mb_fn_handler_t *func_handlers;
|
||||
mb_state_enum_t cur_state;
|
||||
uint8_t *frame;
|
||||
uint16_t length;
|
||||
uint8_t func_code;
|
||||
uint8_t rcv_addr;
|
||||
uint64_t curr_trans_id;
|
||||
volatile uint16_t *pdu_snd_len;
|
||||
} mbs_object_t;
|
||||
|
||||
static mb_fn_handler_t slave_handlers[MB_FUNC_HANDLERS_MAX] =
|
||||
{
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
{MB_FUNC_OTHER_REPORT_SLAVEID, (void *)mb_fn_report_slv_id},
|
||||
{MB_FUNC_OTHER_REPORT_SLAVEID, (void *)mbs_fn_report_slave_id},
|
||||
#endif
|
||||
#if MB_FUNC_READ_INPUT_ENABLED
|
||||
{MB_FUNC_READ_INPUT_REGISTER, (void *)mbs_fn_read_input_reg},
|
||||
@@ -52,31 +74,10 @@ static mb_fn_handler_t slave_handlers[MB_FUNC_HANDLERS_MAX] =
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mb_base_t base;
|
||||
// here are slave object properties and methods
|
||||
uint8_t mb_address;
|
||||
mb_comm_mode_t cur_mode;
|
||||
mb_state_enum_t cur_state;
|
||||
mb_fn_handler_t *func_handlers;
|
||||
uint8_t *frame;
|
||||
uint16_t length;
|
||||
uint8_t func_code;
|
||||
uint8_t rcv_addr;
|
||||
uint64_t curr_trans_id;
|
||||
volatile uint16_t *pdu_snd_len;
|
||||
} mbs_object_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);
|
||||
mb_err_enum_t mbs_enable(mb_base_t *inst);
|
||||
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);
|
||||
|
||||
typedef struct _port_serial_opts mb_serial_opts_t;
|
||||
|
||||
#if (MB_SLAVE_RTU_ENABLED)
|
||||
|
||||
@@ -98,6 +99,11 @@ mb_err_enum_t mbs_rtu_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
|
||||
mbs_obj->base.descr.is_master = false;
|
||||
mbs_obj->base.descr.obj_name = (char *)TAG;
|
||||
mbs_obj->base.descr.inst_index = mb_port_get_inst_counter_inc();
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mbs_obj->base.pobj_id = NULL;
|
||||
mbs_obj->base.obj_id_len = 0;
|
||||
mbs_obj->base.obj_id_chunks = 0;
|
||||
#endif
|
||||
int res = asprintf(&mbs_obj->base.descr.parent_name, "mbs_rtu@%p", *in_out_obj);
|
||||
MB_GOTO_ON_FALSE((res), MB_EILLSTATE, error,
|
||||
TAG, "name alloc fail, err: %d", (int)res);
|
||||
@@ -148,6 +154,11 @@ mb_err_enum_t mbs_ascii_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
|
||||
mbs_obj->base.descr.is_master = false;
|
||||
mbs_obj->base.descr.obj_name = (char *)TAG;
|
||||
mbs_obj->base.descr.inst_index = mb_port_get_inst_counter_inc();
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mbs_obj->base.pobj_id = NULL;
|
||||
mbs_obj->base.obj_id_len = 0;
|
||||
mbs_obj->base.obj_id_chunks = 0;
|
||||
#endif
|
||||
int res = asprintf(&mbs_obj->base.descr.parent_name, "mbs_ascii@%p", *in_out_obj);
|
||||
MB_GOTO_ON_FALSE((res), MB_EILLSTATE, error,
|
||||
TAG, "name alloc fail, err: %d", (int)res);
|
||||
@@ -199,6 +210,11 @@ mb_err_enum_t mbs_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj)
|
||||
mbs_obj->base.descr.is_master = false;
|
||||
mbs_obj->base.descr.obj_name = (char *)TAG;
|
||||
mbs_obj->base.descr.inst_index = mb_port_get_inst_counter_inc();
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
mbs_obj->base.pobj_id = NULL;
|
||||
mbs_obj->base.obj_id_len = 0;
|
||||
mbs_obj->base.obj_id_chunks = 0;
|
||||
#endif
|
||||
int res = asprintf(&mbs_obj->base.descr.parent_name, "mbs_tcp@%p", *in_out_obj);
|
||||
MB_GOTO_ON_FALSE((res), MB_EILLSTATE, error,
|
||||
TAG, "name alloc fail, err: %d", (int)res);
|
||||
@@ -239,6 +255,15 @@ mb_err_enum_t mbs_delete(mb_base_t *inst)
|
||||
// call destructor of the transport object
|
||||
MB_OBJ(mbs_obj->base.transp_obj)->frm_delete(inst->transp_obj);
|
||||
}
|
||||
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
|
||||
// delete allocated slave ID
|
||||
if (mbs_obj->base.pobj_id) {
|
||||
free(mbs_obj->base.pobj_id);
|
||||
mbs_obj->base.pobj_id = NULL;
|
||||
mbs_obj->base.obj_id_len = 0;
|
||||
mbs_obj->base.obj_id_chunks = 0;
|
||||
}
|
||||
#endif
|
||||
// delete the modbus instance
|
||||
free(mbs_obj->base.descr.parent_name);
|
||||
CRITICAL_SECTION_CLOSE(inst->lock);
|
||||
|
||||
Reference in new issue
Block a user