mb master, slave add custom fc handlers

This commit is contained in:
aleks committed 2025-03-10 16:09:03 +01:00
1 parent a54f11355c
commit fc8fc06fc5
23 files changed
+438 -84

No files matched your search

@@ -5,8 +5,8 @@
*/
#pragma once
#include "mb_config.h"
#include "mb_types.h"
#include "sdkconfig.h"
#if __has_include("esp_idf_version.h")
#include "esp_idf_version.h"
@@ -85,6 +85,26 @@ typedef enum _mb_event_enum {
EV_MASTER_PROCESS_SUCCESS = 0x0400 /*!< Master error process. */
} mb_event_enum_t;
/*! \ingroup modbus
* \brief Modbus exception types used in the stack.
*/
typedef enum _mb_exception_enum
{
MB_EX_NONE = 0x00,
MB_EX_ILLEGAL_FUNCTION = 0x01,
MB_EX_ILLEGAL_DATA_ADDRESS = 0x02,
MB_EX_ILLEGAL_DATA_VALUE = 0x03,
MB_EX_SLAVE_DEVICE_FAILURE = 0x04,
MB_EX_ACKNOWLEDGE = 0x05,
MB_EX_SLAVE_BUSY = 0x06,
MB_EX_MEMORY_PARITY_ERROR = 0x08,
MB_EX_GATEWAY_PATH_FAILED = 0x0A,
MB_EX_GATEWAY_TGT_FAILED = 0x0B,
MB_EX_CRITICAL = 0xFF
} mb_exception_t;
typedef mb_exception_t (*mb_fn_handler_fp)(void *, uint8_t *frame_ptr, uint16_t *len_buf);
/*! \ingroup modbus
* \brief Error event type
*/
+33
View File
@@ -44,6 +44,39 @@
/* ----------------------- Start implementation -----------------------------*/
mb_exception_t mb_error_to_exception(mb_err_enum_t error_code);
/**
* This function will request read coil.
*
* @param uid slave address
* @param fc custom function code
* @param buf additional data to send
* @param buf_size size of data to send
* @param timeout timeout (-1 will waiting forever)
*
* @return error code (mb_err_enum_t)
*/
mb_err_enum_t mbm_rq_custom(mb_base_t *inst, uint8_t uid, uint8_t fc, uint8_t *buf, uint16_t buf_size, uint32_t tout)
{
uint8_t *mb_frame_ptr;
if (!buf || (uid > MB_ADDRESS_MAX) || (buf_size >= (MB_BUFFER_SIZE - 2))) {
return MB_EINVAL;
}
if (!mb_port_event_res_take(inst->port_obj, tout)) {
return MB_EBUSY;
}
inst->get_send_buf(inst, &mb_frame_ptr);
inst->set_dest_addr(inst, uid);
mb_frame_ptr[MB_PDU_FUNC_OFF] = fc;
memcpy(&mb_frame_ptr[MB_PDU_DATA_OFF], buf, buf_size);
inst->set_send_len(inst, MB_PDU_SIZE_MIN + buf_size);
(void)mb_port_event_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START));
return mb_port_event_wait_req_finish(inst->port_obj);
}
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;
+48
View File
@@ -126,4 +126,52 @@ mb_exception_t mb_error_to_exception(mb_err_enum_t error_code)
return status;
}
mb_err_enum_t mb_set_handler(mb_fn_handler_t *pfh_table, uint8_t func_code, mb_fn_handler_fp phandler)
{
int index;
mb_err_enum_t status = MB_EILLSTATE;
if ((0 < func_code) && (func_code <= MB_FUNC_CODE_MAX)) {
if (phandler != NULL) {
for(index = 0; index < MB_FUNC_HANDLERS_MAX; index++) {
if ((pfh_table[index].handler == NULL) ||
(pfh_table[index].handler == phandler)) {
pfh_table[index].func_code = func_code;
pfh_table[index].handler = phandler;
break;
}
}
status = (index != MB_FUNC_HANDLERS_MAX) ? MB_ENOERR : MB_ENORES;
} else {
for (index = 0; index < MB_FUNC_HANDLERS_MAX; index++) {
if (pfh_table[index].func_code == func_code) {
pfh_table[index].func_code = 0;
pfh_table[index].handler = NULL;
break;
}
}
status = (index < MB_FUNC_HANDLERS_MAX) ? MB_ENOERR : MB_ENORES;
}
} else {
status = MB_EINVAL;
}
return status;
}
mb_err_enum_t mb_get_handler(mb_fn_handler_t *pfh_table, uint8_t func_code, mb_fn_handler_fp *phandler)
{
int index;
mb_err_enum_t status = MB_EILLSTATE;
if (pfh_table && phandler && (0 < func_code) && (func_code <= MB_FUNC_CODE_MAX)) {
for(index = 0; index < MB_FUNC_HANDLERS_MAX; index++) {
if (func_code == pfh_table[index].func_code) {
*phandler = pfh_table[index].handler;
break;
}
}
status = (index < MB_FUNC_HANDLERS_MAX) ? MB_ENOERR : MB_ENORES;
} else {
status = MB_EINVAL;
}
return status;
}
+7 -1
View File
@@ -152,7 +152,8 @@ struct mb_base_t
mb_rw_callbacks_t rw_cbs;
};
typedef struct _port_tcp_opts mb_tcp_opts_t;
mb_err_enum_t mb_set_handler(mb_fn_handler_t *pfh_table, uint8_t func_code, mb_fn_handler_fp phandler);
mb_err_enum_t mb_get_handler(mb_fn_handler_t *pfh_table, uint8_t func_code, mb_fn_handler_fp *phandler);
#if (CONFIG_FMB_COMM_MODE_ASCII_EN || CONFIG_FMB_COMM_MODE_RTU_EN)
@@ -163,8 +164,13 @@ mb_err_enum_t mbs_ascii_create(mb_serial_opts_t *ser_opts, void **in_out_obj);
#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);
#endif
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);
+1 -1
View File
@@ -115,7 +115,7 @@ extern "C" {
* the sum of all enabled functions in this file and custom function
* handlers. If set to small adding more functions will fail.
*/
#define MB_FUNC_HANDLERS_MAX (16)
#define MB_FUNC_HANDLERS_MAX (CONFIG_FMB_FUNC_HANDLERS_MAX)
/*! \brief Number of bytes which should be allocated for the <em>Report Slave ID
* </em>command.
+2
View File
@@ -12,6 +12,8 @@
extern "C" {
#endif
#define MB_FUNC_CODE_MAX 127
typedef struct mb_base_t mb_base_t;
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
+8 -1
View File
@@ -10,7 +10,7 @@
extern "C" {
#endif
typedef struct mb_base_t mb_base_t; /*!< Type of moddus object */
typedef struct mb_base_t mb_base_t; /*!< Type of modbus object */
mb_err_enum_t mbm_rq_read_inp_reg(mb_base_t *inst, uint8_t snd_addr, uint16_t reg_addr, uint16_t reg_num, uint32_t tout);
mb_err_enum_t mbm_rq_write_holding_reg(mb_base_t *inst, uint8_t snd_addr, uint16_t reg_addr, uint16_t reg_data, uint32_t tout);
@@ -26,6 +26,7 @@ mb_err_enum_t mbm_rq_write_multi_coils(mb_base_t *inst, uint8_t snd_addr, uint16
#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);
mb_err_enum_t mbm_rq_custom(mb_base_t *inst, uint8_t uid, uint8_t fc, uint8_t *buf, uint16_t buf_size, uint32_t tout);
/*! \ingroup modbus_registers
* \brief The common callback function used to transfer common data as bytes from command buffer in little endian format.
@@ -44,6 +45,12 @@ mb_exception_t mbm_fn_report_slave_id(mb_base_t *inst, uint8_t * pframe, uint16_
mb_err_enum_t mbc_reg_common_cb(mb_base_t *inst, uint8_t *pdata, uint16_t address, uint16_t bytes);
#endif
// The function to register custom function handler for master
mb_err_enum_t mbm_set_handler(uint8_t func_code, mb_fn_handler_fp phandler);
// The helper function to get custom function handler for master
mb_err_enum_t mbm_get_handler(uint8_t fc, mb_fn_handler_fp *phandler);
#ifdef __cplusplus
}
#endif
-16
View File
@@ -38,22 +38,6 @@ typedef enum _mb_commands_enum
/* ----------------------- Type definitions ---------------------------------*/
typedef enum
{
MB_EX_NONE = 0x00,
MB_EX_ILLEGAL_FUNCTION = 0x01,
MB_EX_ILLEGAL_DATA_ADDRESS = 0x02,
MB_EX_ILLEGAL_DATA_VALUE = 0x03,
MB_EX_SLAVE_DEVICE_FAILURE = 0x04,
MB_EX_ACKNOWLEDGE = 0x05,
MB_EX_SLAVE_BUSY = 0x06,
MB_EX_MEMORY_PARITY_ERROR = 0x08,
MB_EX_GATEWAY_PATH_FAILED = 0x0A,
MB_EX_GATEWAY_TGT_FAILED = 0x0B
} mb_exception_t;
typedef mb_exception_t (*mb_fn_handler_fp)(void *, uint8_t *frame_ptr, uint16_t *len_buf);
typedef struct
{
uint8_t func_code;
+4
View File
@@ -15,6 +15,10 @@ extern "C" {
mb_exception_t mbs_fn_report_slave_id(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *plen_buf);
#endif
// The helper function to register custom function handler for slave
mb_err_enum_t mbs_set_handler(uint8_t func_code, mb_fn_handler_fp phandler);
mb_err_enum_t mbs_get_handler(uint8_t func_code, mb_fn_handler_fp *phandler);
#ifdef __cplusplus
}
#endif
+75 -38
View File
@@ -16,9 +16,15 @@
static const char *TAG = "mb_object.master";
#if (MB_MASTER_ASCII_ENABLED || MB_MASTER_RTU_ENABLED)
typedef struct _port_serial_opts mb_serial_opts_t;
#endif
#if (MB_MASTER_ASCII_ENABLED || MB_MASTER_RTU_ENABLED || MB_MASTER_TCP_ENABLED)
static const mb_fn_handler_t master_handlers[MB_FUNC_HANDLERS_MAX] =
static mb_fn_handler_t master_handlers[MB_FUNC_HANDLERS_MAX] =
{
#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
{MB_FUNC_OTHER_REPORT_SLAVEID, (void *)mbm_fn_report_slave_id},
@@ -57,7 +63,6 @@ typedef struct
mb_base_t base;
mb_comm_mode_t cur_mode;
mb_state_enum_t cur_state;
const mb_fn_handler_t *func_handlers;
uint8_t *rcv_frame;
uint8_t *snd_frame;
uint16_t pdu_snd_len;
@@ -82,7 +87,55 @@ static void mbm_set_dest_addr(mb_base_t *inst, uint8_t dest_addr);
static uint8_t mbm_get_dest_addr(mb_base_t *inst);
static void mbm_get_pdu_send_buf(mb_base_t *inst, uint8_t **pbuf);
typedef struct _port_serial_opts mb_serial_opts_t;
static _lock_t s_mbm_lock; // lock section for command handlers
mb_err_enum_t mbm_set_handler(uint8_t func_code, mb_fn_handler_fp phandler)
{
mb_err_enum_t status = MB_EILLSTATE;
CRITICAL_SECTION(s_mbm_lock) {
status = mb_set_handler(&master_handlers[0], func_code, phandler);
}
return status;
}
// The helper function to register custom function handler for master
mb_err_enum_t mbm_get_handler(uint8_t fc, mb_fn_handler_fp *phandler)
{
mb_err_enum_t status = MB_EINVAL;
if (phandler) {
CRITICAL_SECTION(s_mbm_lock) {
status = mb_get_handler(&master_handlers[0], fc, phandler);
}
}
return status;
}
static mb_err_enum_t mbm_check_invoke_handler(mb_base_t *inst, uint8_t fc, uint8_t *pbuf, uint16_t *plen)
{
mb_exception_t exception = MB_EX_ILLEGAL_FUNCTION;
if (!fc) {
return MB_EX_ILLEGAL_FUNCTION;
}
if (fc & MB_FUNC_ERROR) {
exception = (mb_exception_t)pbuf[MB_PDU_DATA_OFF];
return exception;
}
CRITICAL_SECTION(s_mbm_lock) {
for (int i = 0; i < MB_FUNC_HANDLERS_MAX; i++) {
/* No more function handlers registered. Abort. */
if (master_handlers[i].func_code == 0) {
ESP_LOGE(TAG, MB_OBJ_FMT": function (0x%x), handler is missing.", MB_OBJ_PARENT(inst), (int)fc);
break;
}
if (master_handlers[i].func_code == fc) {
exception = master_handlers[i].handler(inst, pbuf, plen);
ESP_LOGD(__func__, MB_OBJ_FMT": function (0x%x), invoke handler.", MB_OBJ_PARENT(inst), (int)fc);
break;
}
}
}
return exception;
}
#if (MB_MASTER_RTU_ENABLED)
@@ -121,7 +174,6 @@ mb_err_enum_t mbm_rtu_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
ret = mbm_rtu_transp_create(ser_opts, (void **)&transp_obj);
MB_GOTO_ON_FALSE((transp_obj && (ret == MB_ENOERR)), MB_EILLSTATE, error,
TAG, "transport creation, err: %d", (int)ret);
mbm_obj->func_handlers = master_handlers;
mbm_obj->cur_mode = ser_opts->mode;
mbm_obj->cur_state = STATE_DISABLED;
transp_obj->get_tx_frm(transp_obj, (uint8_t **)&mbm_obj->snd_frame);
@@ -183,7 +235,6 @@ mb_err_enum_t mbm_ascii_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
ret = mbm_ascii_transp_create(ser_opts, (void **)&transp_obj);
MB_GOTO_ON_FALSE((transp_obj && (ret == MB_ENOERR)), MB_EILLSTATE, error,
TAG, "transport creation, err: %d", (int)ret);
mbm_obj->func_handlers = master_handlers;
mbm_obj->cur_mode = ser_opts->mode;
mbm_obj->cur_state = STATE_DISABLED;
transp_obj->get_tx_frm(transp_obj, (uint8_t **)&mbm_obj->snd_frame);
@@ -245,7 +296,6 @@ mb_err_enum_t mbm_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj)
ret = mbm_tcp_transp_create(tcp_opts, (void **)&transp_obj);
MB_GOTO_ON_FALSE((transp_obj && (ret == MB_ENOERR)), MB_EILLSTATE, error,
TAG, "transport creation, err: %d", (int)ret);
mbm_obj->func_handlers = master_handlers;
mbm_obj->cur_mode = tcp_opts->mode;
mbm_obj->cur_state = STATE_DISABLED;
transp_obj->get_tx_frm(transp_obj, (uint8_t **)&mbm_obj->snd_frame);
@@ -271,7 +321,7 @@ error:
mb_err_enum_t mbm_delete(mb_base_t *inst)
{
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);
mb_err_enum_t status = MB_ENOERR;
if (mbm_obj->cur_state == STATE_DISABLED) {
if (MB_OBJ(mbm_obj->base.transp_obj)->frm_delete) {
@@ -303,7 +353,7 @@ mb_err_enum_t mbm_delete(mb_base_t *inst)
mb_err_enum_t mbm_enable(mb_base_t *inst)
{
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);
mb_err_enum_t status = MB_ENOERR;
CRITICAL_SECTION(inst->lock)
{
@@ -322,7 +372,7 @@ mb_err_enum_t mbm_enable(mb_base_t *inst)
mb_err_enum_t mbm_disable(mb_base_t *inst)
{
mb_err_enum_t status = MB_ENOERR;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);
CRITICAL_SECTION(inst->lock)
{
if (mbm_obj->cur_state == STATE_ENABLED) {
@@ -340,7 +390,7 @@ mb_err_enum_t mbm_disable(mb_base_t *inst)
static void mbm_get_pdu_send_buf(mb_base_t *inst, uint8_t **pbuf)
{
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);
MB_OBJ(mbm_obj->base.transp_obj)->get_tx_frm(mbm_obj->base.transp_obj, pbuf);
}
@@ -353,7 +403,7 @@ static void mbm_get_pdu_recv_buf(mb_base_t *inst, uint8_t **pbuf)
static void mbm_set_pdu_send_length(mb_base_t *inst, uint16_t length)
{
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);
CRITICAL_SECTION(inst->lock)
{
mbm_obj->pdu_snd_len = length;
@@ -362,13 +412,13 @@ static void mbm_set_pdu_send_length(mb_base_t *inst, uint16_t length)
static uint16_t mbm_get_pdu_send_length(mb_base_t *inst)
{
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);
return mbm_obj->pdu_snd_len;
}
static void mbm_set_dest_addr(mb_base_t *inst, uint8_t dest_addr)
{
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);
CRITICAL_SECTION(inst->lock)
{
mbm_obj->master_dst_addr = dest_addr;
@@ -377,7 +427,7 @@ static void mbm_set_dest_addr(mb_base_t *inst, uint8_t dest_addr)
static uint8_t mbm_get_dest_addr(mb_base_t *inst)
{
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);
return mbm_obj->master_dst_addr;
}
@@ -496,31 +546,18 @@ mb_err_enum_t mbm_poll(mb_base_t *inst)
ESP_LOGD(TAG, MB_OBJ_FMT":EV_EXECUTE", MB_OBJ_PARENT(inst));
mbm_obj->func_code = mbm_obj->rcv_frame[MB_PDU_FUNC_OFF];
exception = MB_EX_ILLEGAL_FUNCTION;
/* If receive frame has exception. The receive function code highest bit is 1.*/
if (mbm_obj->func_code & MB_FUNC_ERROR) {
exception = (mb_exception_t)mbm_obj->rcv_frame[MB_PDU_DATA_OFF];
} else {
for (int i = 0; i < MB_FUNC_HANDLERS_MAX; i++) {
/* No more function handlers registered. Abort. */
if (mbm_obj->func_handlers[i].func_code == 0) {
break;
}
if (mbm_obj->func_handlers[i].func_code == mbm_obj->func_code) {
/* If master request is broadcast,
* the master need execute function for all slave.
*/
if (MB_OBJ(inst->transp_obj)->frm_is_bcast(inst->transp_obj)) {
length = mbm_obj->pdu_snd_len;
for (int j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++) {
mbm_set_dest_addr(inst, j);
exception = mbm_obj->func_handlers[i].handler(inst, mbm_obj->rcv_frame, &length);
}
} else {
exception = mbm_obj->func_handlers[i].handler(inst, mbm_obj->rcv_frame, &mbm_obj->pdu_rcv_len);
}
break;
}
/* If master request is broadcast,
* the master need to execute function for all slaves.
*/
if (MB_OBJ(inst->transp_obj)->frm_is_bcast(inst->transp_obj)) {
length = mbm_obj->pdu_snd_len;
for (int j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++) {
mbm_set_dest_addr(inst, j);
exception = mbm_check_invoke_handler(inst, mbm_obj->func_code, mbm_obj->rcv_frame, &length);
}
} else {
ESP_LOGD(__func__, MB_OBJ_FMT": function (0x%x), invoke handler.", MB_OBJ_PARENT(inst), (int)mbm_obj->func_code);
exception = mbm_check_invoke_handler(inst, mbm_obj->func_code, mbm_obj->rcv_frame, &mbm_obj->pdu_rcv_len);
}
/* If master has exception, will send error process event. Otherwise the master is idle.*/
if (exception != MB_EX_NONE) {
+48 -18
View File
@@ -30,7 +30,6 @@ typedef struct
// 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;
@@ -74,11 +73,58 @@ static mb_fn_handler_t slave_handlers[MB_FUNC_HANDLERS_MAX] =
#endif
};
static _lock_t s_mbs_lock;
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);
// The helper function to register custom function handler for slave
mb_err_enum_t mbs_set_handler(uint8_t fc, mb_fn_handler_fp phandler)
{
mb_err_enum_t status = MB_EINVAL;
CRITICAL_SECTION(s_mbs_lock) {
status = mb_set_handler(&slave_handlers[0], fc, phandler);
}
return status;
}
// The helper function to register custom function handler for slave
mb_err_enum_t mbs_get_handler(uint8_t fc, mb_fn_handler_fp *phandler)
{
mb_err_enum_t status = MB_EINVAL;
if (phandler) {
CRITICAL_SECTION(s_mbs_lock) {
status = mb_get_handler(&slave_handlers[0], fc, phandler);
}
}
return status;
}
static mb_err_enum_t mbs_check_invoke_handler(mb_base_t *inst, uint8_t fc, uint8_t *pbuf, uint16_t *plen)
{
mb_exception_t exception = MB_EX_ILLEGAL_FUNCTION;
if (!fc || (fc & MB_FUNC_ERROR)) {
return MB_EX_ILLEGAL_FUNCTION;
}
CRITICAL_SECTION(s_mbs_lock) {
for (int i = 0; i < MB_FUNC_HANDLERS_MAX; i++) {
/* No more function handlers registered. Abort. */
if (slave_handlers[i].func_code == 0) {
ESP_LOGD(TAG, MB_OBJ_FMT": function (0x%x), handler is missing.", MB_OBJ_PARENT(inst), (int)fc);
break;
}
if (slave_handlers[i].func_code == fc) {
exception = slave_handlers[i].handler(inst, pbuf, plen);
ESP_LOGD(TAG, MB_OBJ_FMT": function (0x%x), invoke handler.", MB_OBJ_PARENT(inst), (int)fc);
break;
}
}
}
return exception;
}
#if (MB_SLAVE_RTU_ENABLED)
mb_err_enum_t mbs_rtu_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
@@ -111,7 +157,6 @@ mb_err_enum_t mbs_rtu_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
ret = mbs_rtu_transp_create(ser_opts, (void **)&transp_obj);
MB_GOTO_ON_FALSE((transp_obj && (ret == MB_ENOERR)), MB_EILLSTATE, error,
TAG, "transport creation, err: %d", (int)ret);
mbs_obj->func_handlers = slave_handlers;
mbs_obj->cur_mode = ser_opts->mode;
mbs_obj->mb_address = ser_opts->uid;
mbs_obj->cur_state = STATE_DISABLED;
@@ -166,7 +211,6 @@ mb_err_enum_t mbs_ascii_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
ret = mbs_ascii_transp_create(ser_opts, (void **)&transp_obj);
MB_GOTO_ON_FALSE((transp_obj && (ret == MB_ENOERR)), MB_EILLSTATE, error,
TAG, "transport creation, err: %d", (int)ret);
mbs_obj->func_handlers = slave_handlers;
mbs_obj->cur_mode = ser_opts->mode;
mbs_obj->mb_address = ser_opts->uid;
mbs_obj->cur_state = STATE_DISABLED;
@@ -222,7 +266,6 @@ mb_err_enum_t mbs_tcp_create(mb_tcp_opts_t *tcp_opts, void **in_out_obj)
ret = mbs_tcp_transp_create(tcp_opts, (void **)&transp_obj);
MB_GOTO_ON_FALSE((transp_obj && (ret == MB_ENOERR)), MB_EILLSTATE, error,
TAG, "transport creation, err: %d", (int)ret);
mbs_obj->func_handlers = slave_handlers;
mbs_obj->cur_mode = tcp_opts->mode;
mbs_obj->mb_address = tcp_opts->uid;
mbs_obj->cur_state = STATE_DISABLED;
@@ -358,20 +401,7 @@ mb_err_enum_t mbs_poll(mb_base_t *inst)
MB_RETURN_ON_FALSE(mbs_obj->frame, MB_EILLSTATE, TAG, "receive buffer fail.");
ESP_LOGD(TAG, MB_OBJ_FMT":EV_EXECUTE", MB_OBJ_PARENT(inst));
mbs_obj->func_code = mbs_obj->frame[MB_PDU_FUNC_OFF];
exception = MB_EX_ILLEGAL_FUNCTION;
// If receive frame has exception. The receive function code highest bit is 1.
for (int i = 0; (i < MB_FUNC_HANDLERS_MAX); i++) {
// No more function handlers registered. Abort.
if (mbs_obj->func_handlers[i].func_code == 0) {
ESP_LOGD(TAG, MB_OBJ_FMT": function (0x%x), handler is not found.", MB_OBJ_PARENT(inst), (int)mbs_obj->func_code);
break;
}
if ((mbs_obj->func_handlers[i].func_code) == mbs_obj->func_code) {
ESP_LOGD(TAG, MB_OBJ_FMT": function (0x%x), start handler.", MB_OBJ_PARENT(inst), (int)mbs_obj->func_code);
exception = mbs_obj->func_handlers[i].handler(inst, mbs_obj->frame, &mbs_obj->length);
break;
}
}
exception = mbs_check_invoke_handler(inst, mbs_obj->func_code, mbs_obj->frame, &mbs_obj->length);
// If the request was not sent to the broadcast address, return a reply.
if ((mbs_obj->rcv_addr != MB_ADDRESS_BROADCAST) || (mbs_obj->cur_mode == MB_TCP)) {
if (exception != MB_EX_NONE) {