forked from espressif/esp-modbus
feature modbus tcp master slave v2
This commit is contained in:
1 parent
d4345f8cd7
commit
2e2be467f6
109 files changed
+4454
-2319
No files matched your search
@@ -82,7 +82,7 @@ mb_err_enum_t mbm_rq_read_coils(mb_base_t *inst, uint8_t snd_addr, uint16_t coil
|
||||
if (snd_addr > MB_ADDRESS_MAX) {
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout)) {
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout)) {
|
||||
return MB_EBUSY;
|
||||
}
|
||||
inst->get_send_buf(inst, &mb_frame_ptr);
|
||||
@@ -98,8 +98,8 @@ mb_err_enum_t mbm_rq_read_coils(mb_base_t *inst, uint8_t snd_addr, uint16_t coil
|
||||
|
||||
inst->set_send_len(inst, MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE);
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START) );
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_read_coils(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
@@ -182,7 +182,7 @@ mb_err_enum_t mbm_rq_write_coil(mb_base_t *inst, uint8_t snd_addr, uint16_t coil
|
||||
if ((coil_data != 0xFF00) && (coil_data != 0x0000)) {
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout)) {
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout)) {
|
||||
return MB_EBUSY;
|
||||
}
|
||||
inst->get_send_buf(inst, &mb_frame_ptr);
|
||||
@@ -199,8 +199,8 @@ mb_err_enum_t mbm_rq_write_coil(mb_base_t *inst, uint8_t snd_addr, uint16_t coil
|
||||
|
||||
inst->set_send_len(inst, (MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE));
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START) );
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_write_coil(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
@@ -249,7 +249,7 @@ mb_err_enum_t mbm_rq_write_multi_coils(mb_base_t *inst, uint8_t snd_addr, uint16
|
||||
if (coil_num > MB_PDU_REQ_WRITE_MUL_COILCNT_MAX) {
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout)) {
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout)) {
|
||||
return MB_EBUSY;
|
||||
}
|
||||
inst->get_send_buf(inst, &mb_frame_ptr);
|
||||
@@ -278,8 +278,8 @@ mb_err_enum_t mbm_rq_write_multi_coils(mb_base_t *inst, uint8_t snd_addr, uint16
|
||||
|
||||
inst->set_send_len(inst, (MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + byte_cnt));
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START) );
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_write_multi_coils(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
@@ -332,4 +332,4 @@ mb_exception_t mbm_fn_write_multi_coils(mb_base_t *inst, uint8_t *frame_ptr, uin
|
||||
}
|
||||
|
||||
#endif // #if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
|
||||
#endif // #if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
||||
#endif // #if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
|
||||
@@ -64,7 +64,7 @@ mb_err_enum_t mbm_rq_read_discrete_inputs(mb_base_t *inst, uint8_t snd_addr, uin
|
||||
if (!inst || (snd_addr > MB_ADDRESS_MAX)) {
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout)) {
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout)) {
|
||||
return MB_EBUSY;
|
||||
}
|
||||
inst->get_send_buf(inst, &mb_frame_ptr);
|
||||
@@ -80,8 +80,8 @@ mb_err_enum_t mbm_rq_read_discrete_inputs(mb_base_t *inst, uint8_t snd_addr, uin
|
||||
|
||||
inst->set_send_len(inst, MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE);
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START) );
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_read_discrete_inputs(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
|
||||
@@ -94,7 +94,7 @@ mb_err_enum_t mbm_rq_write_holding_reg(mb_base_t *inst, uint8_t snd_addr, uint16
|
||||
{
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout))
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout))
|
||||
{
|
||||
return MB_EBUSY;
|
||||
}
|
||||
@@ -111,8 +111,8 @@ mb_err_enum_t mbm_rq_write_holding_reg(mb_base_t *inst, uint8_t snd_addr, uint16
|
||||
|
||||
inst->set_send_len(inst, MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE);
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START));
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_write_holding_reg(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
@@ -170,7 +170,7 @@ mb_err_enum_t mbm_rq_write_multi_holding_reg(mb_base_t *inst, uint8_t snd_addr,
|
||||
{
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout))
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout))
|
||||
{
|
||||
return MB_EBUSY;
|
||||
}
|
||||
@@ -198,8 +198,8 @@ mb_err_enum_t mbm_rq_write_multi_holding_reg(mb_base_t *inst, uint8_t snd_addr,
|
||||
|
||||
inst->set_send_len(inst, (MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + 2 * reg_num));
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START));
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_write_multi_holding_reg(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
@@ -272,7 +272,7 @@ mb_err_enum_t mbm_rq_read_holding_reg(mb_base_t *inst, uint8_t snd_addr, uint16_
|
||||
{
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout))
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout))
|
||||
{
|
||||
return MB_EBUSY;
|
||||
}
|
||||
@@ -289,8 +289,8 @@ mb_err_enum_t mbm_rq_read_holding_reg(mb_base_t *inst, uint8_t snd_addr, uint16_
|
||||
|
||||
inst->set_send_len(inst, (MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE));
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START));
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_read_holding_reg(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
@@ -376,7 +376,7 @@ mb_err_enum_t mbm_rq_rw_multi_holding_reg(mb_base_t *inst, uint8_t snd_addr, uin
|
||||
{
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout))
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout))
|
||||
{
|
||||
return MB_EBUSY;
|
||||
}
|
||||
@@ -408,8 +408,8 @@ mb_err_enum_t mbm_rq_rw_multi_holding_reg(mb_base_t *inst, uint8_t snd_addr, uin
|
||||
|
||||
inst->set_send_len(inst, (MB_PDU_SIZE_MIN + MB_PDU_REQ_READWRITE_SIZE_MIN + 2 * wr_reg_num));
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START));
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_rw_multi_holding_regs(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
|
||||
@@ -67,7 +67,7 @@ mb_err_enum_t mbm_rq_read_inp_reg(mb_base_t *inst, uint8_t snd_addr, uint16_t re
|
||||
if (!inst || (snd_addr > MB_ADDRESS_MAX)) {
|
||||
return MB_EINVAL;
|
||||
}
|
||||
if (!mb_port_evt_res_take(inst->port_obj, tout)) {
|
||||
if (!mb_port_event_res_take(inst->port_obj, tout)) {
|
||||
return MB_EBUSY;
|
||||
}
|
||||
inst->get_send_buf(inst, &mb_frame_ptr);
|
||||
@@ -83,8 +83,8 @@ mb_err_enum_t mbm_rq_read_inp_reg(mb_base_t *inst, uint8_t snd_addr, uint16_t re
|
||||
|
||||
inst->set_send_len(inst, MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE);
|
||||
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_FRAME_TRANSMIT | EV_TRANS_START) );
|
||||
return mb_port_evt_wait_req_finish(inst->port_obj);
|
||||
(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_exception_t mbm_fn_read_inp_reg(mb_base_t *inst, uint8_t *frame_ptr, uint16_t *len_buf)
|
||||
|
||||
@@ -55,36 +55,53 @@ extern "C" {
|
||||
(void)log_tag; \
|
||||
if (!(a)) { \
|
||||
ESP_LOGE(log_tag, "%s(%d): " format, __FUNCTION__, __LINE__ __VA_OPT__(,) __VA_ARGS__); \
|
||||
ret = (err_code); \
|
||||
ret = (err_code); \
|
||||
goto goto_tag; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define MB_CAT_BUF_SIZE (100)
|
||||
|
||||
#define MB_STR_CAT(pref, message) (__extension__( \
|
||||
{ \
|
||||
char buf##__FUNCTION__##__LINE__[MB_CAT_BUF_SIZE]; \
|
||||
strncpy(&(buf##__FUNCTION__##__LINE__)[0], pref, (MB_CAT_BUF_SIZE - 1)); \
|
||||
strncat((buf##__FUNCTION__##__LINE__), message, (MB_CAT_BUF_SIZE - 1)); \
|
||||
(&((buf##__FUNCTION__##__LINE__)[0])); \
|
||||
} \
|
||||
))
|
||||
|
||||
#define MB_OBJ_FMT "%p"
|
||||
|
||||
#define MB_OBJ_PTR(inst) (__extension__( \
|
||||
{ \
|
||||
assert(inst); \
|
||||
(((obj_descr_t*)(inst))->parent); \
|
||||
} \
|
||||
#define MB_GET_OBJ_CTX(pinst, type, base) (__extension__( \
|
||||
{ \
|
||||
assert(pinst); \
|
||||
((type *)__containerof(pinst, type, base)); \
|
||||
} \
|
||||
))
|
||||
|
||||
#define MB_BASE2PORT(inst) (__extension__( \
|
||||
{ \
|
||||
assert(inst); \
|
||||
(((mb_base_t *)inst)->port_obj); \
|
||||
} \
|
||||
#define MB_OBJ(pinst) (__extension__( \
|
||||
{ \
|
||||
assert(pinst); \
|
||||
((typeof(pinst))(pinst)); \
|
||||
} \
|
||||
))
|
||||
|
||||
#define CAT_BUF_SIZE (100)
|
||||
#define MB_STR_CAT(pref, message) (__extension__( \
|
||||
{ \
|
||||
static char string_buf[CAT_BUF_SIZE]; \
|
||||
strncpy(string_buf, pref, (CAT_BUF_SIZE - 1)); \
|
||||
strncat(string_buf, message, (CAT_BUF_SIZE - 1)); \
|
||||
} \
|
||||
#define MB_OBJ_PARENT(pinst) (__extension__( \
|
||||
{ \
|
||||
assert(pinst); \
|
||||
(((obj_descr_t*)(pinst))->parent); \
|
||||
} \
|
||||
))
|
||||
|
||||
#define MB_BASE2PORT(pinst) (__extension__( \
|
||||
{ \
|
||||
assert(pinst); \
|
||||
assert(((mb_base_t *)pinst)->port_obj); \
|
||||
(((mb_base_t *)pinst)->port_obj); \
|
||||
} \
|
||||
))
|
||||
|
||||
typedef struct mb_base_t mb_base_t;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "stdatomic.h"
|
||||
#include "mb_config.h"
|
||||
#include "mb_types.h"
|
||||
|
||||
@@ -12,6 +13,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MB_ATTR_WEAK __attribute__ ((weak))
|
||||
|
||||
typedef enum _mb_comm_mode mb_mode_type_t;
|
||||
|
||||
#if (CONFIG_FMB_COMM_MODE_ASCII_EN || CONFIG_FMB_COMM_MODE_RTU_EN)
|
||||
@@ -60,42 +63,44 @@ struct _port_tcp_opts {
|
||||
mb_addr_type_t addr_type; /*!< Modbus address type */
|
||||
void *ip_addr_table; /*!< Modbus address or table for connection */
|
||||
void *ip_netif_ptr; /*!< Modbus network interface */
|
||||
bool start_disconnected; /*!< do not wait connection to all nodes before polling */
|
||||
char *dns_name; /*!< Modbus node DNS name */
|
||||
bool start_disconnected; /*!< (Master only option) do not wait for connection to all nodes before polling */
|
||||
};
|
||||
|
||||
typedef struct _port_tcp_opts mb_tcp_opts_t;
|
||||
|
||||
// The common object descriptor struture (common for mb, transport, port objects)
|
||||
struct _obj_descr {
|
||||
char *parent_name;
|
||||
char *obj_name;
|
||||
void *parent;
|
||||
uint32_t inst_index;
|
||||
bool is_master;
|
||||
char *parent_name; /*!< Name of the parent (base) object */
|
||||
char *obj_name; /*!< Name of the object */
|
||||
void *parent; /*!< Pointer to the parent (base) object */
|
||||
uint32_t inst_index; /*!< The consicutive index of the object instance */
|
||||
bool is_master; /*!< The current object is master or slave (false) */
|
||||
};
|
||||
|
||||
typedef struct _obj_descr obj_descr_t;
|
||||
|
||||
typedef enum _mb_sock_state {
|
||||
MB_SOCK_STATE_UNDEF = 0x0000,
|
||||
MB_SOCK_STATE_CLOSED,
|
||||
MB_SOCK_STATE_READY,
|
||||
MB_SOCK_STATE_OPENED,
|
||||
MB_SOCK_STATE_RESOLVED,
|
||||
MB_SOCK_STATE_CONNECTING,
|
||||
MB_SOCK_STATE_CONNECTED
|
||||
MB_SOCK_STATE_UNDEF = 0x0000, /*!< Default init state */
|
||||
MB_SOCK_STATE_CLOSED, /*!< Node is closed */
|
||||
MB_SOCK_STATE_READY, /*!< Node is ready for communication */
|
||||
MB_SOCK_STATE_OPENED, /*!< Node is opened */
|
||||
MB_SOCK_STATE_RESOLVED, /*!< Node address is resolved */
|
||||
MB_SOCK_STATE_CONNECTING, /*!< Node connection is in progress */
|
||||
MB_SOCK_STATE_CONNECTED, /*!< Node is connected */
|
||||
MB_SOCK_STATE_ACCEPTED /*!< Slave node accepted the connection */
|
||||
} mb_sock_state_t;
|
||||
|
||||
typedef struct _uid_info {
|
||||
uint16_t index; /*!< index of the address info */
|
||||
int fd; /*!< slave global FD for VFS (reserved) */
|
||||
char *node_name_str; /*!< node name string (host name of slave to resolve) */
|
||||
char *ip_addr_str; /*!< represents the IP address of the slave */
|
||||
int fd; /*!< node global FD for VFS (reserved) */
|
||||
char *node_name_str; /*!< node name string (host name of node to resolve) */
|
||||
char *ip_addr_str; /*!< represents the IP address of the node */
|
||||
mb_addr_type_t addr_type; /*!< type of IP address */
|
||||
uint16_t uid; /*!< slave unit ID (UID) field for MBAP frame */
|
||||
uint16_t port; /*!< slave port number */
|
||||
uint16_t uid; /*!< node unit ID (UID) field for MBAP frame */
|
||||
uint16_t port; /*!< node port number */
|
||||
mb_comm_mode_t proto; /*!< protocol type */
|
||||
mb_sock_state_t state; /*!< slave state */
|
||||
_Atomic mb_sock_state_t state; /*!< node state */
|
||||
void *inst; /*!< pointer to linked instance */
|
||||
} mb_uid_info_t;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ typedef enum _mb_commands_enum
|
||||
MB_FUNC_DIAG_GET_COM_EVENT_CNT = ( 11 ),
|
||||
MB_FUNC_DIAG_GET_COM_EVENT_LOG = ( 12 ),
|
||||
MB_FUNC_OTHER_REPORT_SLAVEID = ( 17 ),
|
||||
MB_FUNC_ERROR = ( 128u ),
|
||||
MB_FUNC_ERROR = ( 128U ),
|
||||
} mb_commands_t;
|
||||
|
||||
/* ----------------------- Type definitions ---------------------------------*/
|
||||
|
||||
@@ -133,7 +133,7 @@ typedef enum
|
||||
MB_TMODE_T35, /*!< Master receive frame T3.5 timeout. */
|
||||
MB_TMODE_RESPOND_TIMEOUT, /*!< Master wait respond for slave. */
|
||||
MB_TMODE_CONVERT_DELAY /*!< Master sent broadcast , then delay sometime.*/
|
||||
} mb_tmr_mode_enum_t;
|
||||
} mb_timer_mode_enum_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ mb_err_enum_t mbm_ascii_create(mb_serial_opts_t *ser_opts, void **in_out_obj)
|
||||
mbm_obj->cur_state = STATE_DISABLED;
|
||||
transp_obj->get_tx_frm(transp_obj, (uint8_t **)&mbm_obj->snd_frame);
|
||||
transp_obj->get_rx_frm(transp_obj, (uint8_t **)&mbm_obj->rcv_frame);
|
||||
mbm_obj->base.port_obj = transp_obj->port_obj; // binding of the modbus object with port objet
|
||||
mbm_obj->base.port_obj = transp_obj->port_obj; // binding of the modbus object with port object
|
||||
mbm_obj->base.transp_obj = transp_obj;
|
||||
*in_out_obj = (void *)&(mbm_obj->base);
|
||||
ESP_LOGD(TAG, "created object %s", mbm_obj->base.descr.parent_name);
|
||||
@@ -253,10 +253,10 @@ error:
|
||||
|
||||
mb_err_enum_t mbm_delete(mb_base_t *inst)
|
||||
{
|
||||
mbm_object_t *mbm_obj = __containerof(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 (mbm_obj->base.transp_obj->frm_delete) {
|
||||
if (MB_OBJ(mbm_obj->base.transp_obj)->frm_delete) {
|
||||
// call destructor of the transport object
|
||||
mbm_obj->base.transp_obj->frm_delete(inst->transp_obj);
|
||||
}
|
||||
@@ -275,13 +275,13 @@ 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 = __containerof(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)
|
||||
{
|
||||
if (mbm_obj->cur_state == STATE_DISABLED) {
|
||||
/* Activate the protocol stack. */
|
||||
mbm_obj->base.transp_obj->frm_start(mbm_obj->base.transp_obj);
|
||||
MB_OBJ(mbm_obj->base.transp_obj)->frm_start(mbm_obj->base.transp_obj);
|
||||
mbm_obj->cur_state = STATE_ENABLED;
|
||||
status = MB_ENOERR;
|
||||
} else {
|
||||
@@ -294,11 +294,11 @@ 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 = __containerof(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) {
|
||||
mbm_obj->base.transp_obj->frm_stop(mbm_obj->base.transp_obj);
|
||||
MB_OBJ(mbm_obj->base.transp_obj)->frm_stop(mbm_obj->base.transp_obj);
|
||||
mbm_obj->cur_state = STATE_DISABLED;
|
||||
status = MB_ENOERR;
|
||||
} else if (mbm_obj->cur_state == STATE_DISABLED) {
|
||||
@@ -312,20 +312,20 @@ 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 = __containerof(inst, mbm_object_t, base);
|
||||
mbm_obj->base.transp_obj->get_tx_frm(mbm_obj->base.transp_obj, pbuf);
|
||||
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);
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
static void mbm_get_pdu_recv_buf(mb_base_t *inst, uint8_t **pbuf)
|
||||
{
|
||||
mbm_object_t *mbm_obj = __containerof(inst, mbm_object_t, base);
|
||||
mbm_obj->base.transp_obj->get_rx_frm(mbm_obj->base.transp_obj, pbuf);
|
||||
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
|
||||
MB_OBJ(mbm_obj->base.transp_obj)->get_rx_frm(mbm_obj->base.transp_obj, pbuf);
|
||||
}
|
||||
|
||||
static void mbm_set_pdu_send_length(mb_base_t *inst, uint16_t length)
|
||||
{
|
||||
mbm_object_t *mbm_obj = __containerof(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;
|
||||
@@ -334,13 +334,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 = __containerof(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 = __containerof(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;
|
||||
@@ -349,37 +349,37 @@ 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 = __containerof(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;
|
||||
}
|
||||
|
||||
void mbm_error_cb_respond_timeout(mb_base_t *inst, uint8_t dest_addr, const uint8_t *pdu_data, uint16_t pdu_length)
|
||||
{
|
||||
mb_port_evt_set_resp_flag(MB_BASE2PORT(inst), EV_MASTER_ERROR_RESPOND_TIMEOUT);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(__func__, (void *)pdu_data, pdu_length, ESP_LOG_WARN);
|
||||
mb_port_event_set_resp_flag(MB_BASE2PORT(inst), EV_MASTER_ERROR_RESPOND_TIMEOUT);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(__func__, (void *)pdu_data, pdu_length, ESP_LOG_DEBUG);
|
||||
}
|
||||
|
||||
void mbm_error_cb_receive_data(mb_base_t *inst, uint8_t dest_addr, const uint8_t *pdu_data, uint16_t pdu_length)
|
||||
{
|
||||
mb_port_evt_set_resp_flag(MB_BASE2PORT(inst), EV_MASTER_ERROR_RECEIVE_DATA);
|
||||
mb_port_event_set_resp_flag(MB_BASE2PORT(inst), EV_MASTER_ERROR_RECEIVE_DATA);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(__func__, (void *)pdu_data, pdu_length, ESP_LOG_DEBUG);
|
||||
}
|
||||
|
||||
void mbm_error_cb_execute_function(mb_base_t *inst, uint8_t dest_address, const uint8_t *pdu_data, uint16_t pdu_length)
|
||||
{
|
||||
mb_port_evt_set_resp_flag(MB_BASE2PORT(inst), EV_MASTER_ERROR_EXECUTE_FUNCTION);
|
||||
mb_port_event_set_resp_flag(MB_BASE2PORT(inst), EV_MASTER_ERROR_EXECUTE_FUNCTION);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(__func__, (void *)pdu_data, pdu_length, ESP_LOG_DEBUG);
|
||||
}
|
||||
|
||||
void mbm_error_cb_request_success(mb_base_t *inst, uint8_t dest_address, const uint8_t *pdu_data, uint16_t pdu_length)
|
||||
{
|
||||
mb_port_evt_set_resp_flag(MB_BASE2PORT(inst), EV_MASTER_PROCESS_SUCCESS);
|
||||
mb_port_event_set_resp_flag(MB_BASE2PORT(inst), EV_MASTER_PROCESS_SUCCESS);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(__func__, (void *)pdu_data, pdu_length, ESP_LOG_DEBUG);
|
||||
}
|
||||
|
||||
mb_err_enum_t mbm_poll(mb_base_t *inst)
|
||||
{
|
||||
mbm_object_t *mbm_obj = __containerof(inst, mbm_object_t, base);
|
||||
mbm_object_t *mbm_obj = MB_GET_OBJ_CTX(inst, mbm_object_t, base);;
|
||||
|
||||
uint16_t length;
|
||||
mb_exception_t exception;
|
||||
@@ -394,69 +394,78 @@ mb_err_enum_t mbm_poll(mb_base_t *inst)
|
||||
|
||||
/* Check if there is a event available. If not return control to caller.
|
||||
* Otherwise we will handle the event. */
|
||||
if (mb_port_evt_get(mbm_obj->base.port_obj, &event)) {
|
||||
if (mb_port_event_get(MB_OBJ(mbm_obj->base.port_obj), &event)) {
|
||||
switch (event.event) {
|
||||
case EV_READY:
|
||||
ESP_LOGW(TAG, MB_OBJ_FMT":EV_READY", MB_OBJ_PTR(inst));
|
||||
mb_port_evt_res_release(inst->port_obj);
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_READY", MB_OBJ_PARENT(inst));
|
||||
mb_port_event_res_release(MB_OBJ(inst->port_obj));
|
||||
break;
|
||||
|
||||
case EV_FRAME_TRANSMIT:
|
||||
mbm_get_pdu_send_buf(inst, &mbm_obj->snd_frame);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(MB_STR_CAT(inst->descr.parent_name, ":MB_TRANSMIT"), (void *)mbm_obj->snd_frame, mbm_obj->pdu_snd_len, ESP_LOG_WARN);
|
||||
status = inst->transp_obj->frm_send(inst->transp_obj, mbm_obj->master_dst_addr, mbm_obj->snd_frame, mbm_obj->pdu_snd_len);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(MB_STR_CAT(inst->descr.parent_name, ":MB_TRANSMIT"),
|
||||
(void *)mbm_obj->snd_frame, mbm_obj->pdu_snd_len, ESP_LOG_DEBUG);
|
||||
status = MB_OBJ(inst->transp_obj)->frm_send(inst->transp_obj, mbm_obj->master_dst_addr,
|
||||
mbm_obj->snd_frame, mbm_obj->pdu_snd_len);
|
||||
if (status != MB_ENOERR) {
|
||||
mb_port_evt_set_err_type(inst->port_obj, EV_ERROR_RECEIVE_DATA);
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", frame send error. %d", MB_OBJ_PTR(inst), (int)status);
|
||||
mb_port_event_set_err_type(MB_OBJ(inst->port_obj), EV_ERROR_RECEIVE_DATA);
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_ERROR_PROCESS));
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", frame send error. %d", MB_OBJ_PARENT(inst), (int)status);
|
||||
}
|
||||
// Initialize modbus transaction
|
||||
mbm_obj->curr_trans_id = event.trans_id;
|
||||
break;
|
||||
|
||||
case EV_FRAME_SENT:
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_MASTER_FRAME_SENT", MB_OBJ_PTR(inst));
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_FRAME_SENT", MB_OBJ_PARENT(inst));
|
||||
break;
|
||||
|
||||
case EV_FRAME_RECEIVED:
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_FRAME_RECEIVED", MB_OBJ_PARENT(inst));
|
||||
mbm_obj->pdu_rcv_len = event.length;
|
||||
status = inst->transp_obj->frm_rcv(inst->transp_obj, &mbm_obj->rcv_addr, &mbm_obj->rcv_frame, &mbm_obj->pdu_rcv_len);
|
||||
status = MB_OBJ(inst->transp_obj)->frm_rcv(inst->transp_obj, &mbm_obj->rcv_addr,
|
||||
&mbm_obj->rcv_frame, &mbm_obj->pdu_rcv_len);
|
||||
MB_RETURN_ON_FALSE(mbm_obj->snd_frame, MB_EILLSTATE, TAG, "Send buffer initialization fail.");
|
||||
if (event.trans_id == mbm_obj->curr_trans_id) {
|
||||
// Check if the frame is for us. If not ,send an error process event.
|
||||
if ((status == MB_ENOERR) && ((mbm_obj->rcv_addr == mbm_obj->master_dst_addr)
|
||||
if ((status == MB_ENOERR) && ((mbm_obj->rcv_addr == mbm_obj->master_dst_addr)
|
||||
|| (mbm_obj->rcv_addr == MB_TCP_PSEUDO_ADDRESS))) {
|
||||
if ((mbm_obj->rcv_frame[MB_PDU_FUNC_OFF] & ~MB_FUNC_ERROR) == (mbm_obj->snd_frame[MB_PDU_FUNC_OFF])) {
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT", frame data received successfully, (%d).", MB_OBJ_PTR(inst), (int)status);
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT", frame data received successfully, (%d).", MB_OBJ_PARENT(inst), (int)status);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(MB_STR_CAT(inst->descr.parent_name, ":MB_RECV"), (void *)mbm_obj->rcv_frame,
|
||||
(uint16_t)mbm_obj->pdu_rcv_len, ESP_LOG_WARN);
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_EXECUTE));
|
||||
(uint16_t)mbm_obj->pdu_rcv_len, ESP_LOG_DEBUG);
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_EXECUTE));
|
||||
} else {
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", drop incorrect frame, receive_func(%u) != send_func(%u)",
|
||||
MB_OBJ_PTR(inst), (mbm_obj->rcv_frame[MB_PDU_FUNC_OFF] & ~MB_FUNC_ERROR),
|
||||
MB_OBJ_PARENT(inst), (mbm_obj->rcv_frame[MB_PDU_FUNC_OFF] & ~MB_FUNC_ERROR),
|
||||
mbm_obj->snd_frame[MB_PDU_FUNC_OFF]);
|
||||
mb_port_evt_set_err_type(inst->port_obj, EV_ERROR_RECEIVE_DATA);
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
mb_port_event_set_err_type(MB_OBJ(inst->port_obj), EV_ERROR_RECEIVE_DATA);
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_ERROR_PROCESS));
|
||||
}
|
||||
} else {
|
||||
mb_port_evt_set_err_type(inst->port_obj, EV_ERROR_RECEIVE_DATA);
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
mb_port_event_set_err_type(MB_OBJ(inst->port_obj), EV_ERROR_RECEIVE_DATA);
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_ERROR_PROCESS));
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT", packet data receive failed (addr=%u)(%u).",
|
||||
MB_OBJ_PTR(inst), (unsigned)mbm_obj->rcv_addr, (unsigned)status);
|
||||
MB_OBJ_PARENT(inst), (unsigned)mbm_obj->rcv_addr, (unsigned)status);
|
||||
}
|
||||
} else {
|
||||
// Ignore the `EV_FRAME_RECEIVED` event because the respond timeout occurred
|
||||
// and this is likely respond to previous transaction
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", drop data received outside of transaction.", MB_OBJ_PTR(inst));
|
||||
mb_port_evt_set_err_type(inst->port_obj, EV_ERROR_RESPOND_TIMEOUT);
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", drop data received outside of transaction.", MB_OBJ_PARENT(inst));
|
||||
mb_port_event_set_err_type(MB_OBJ(inst->port_obj), EV_ERROR_RESPOND_TIMEOUT);
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_ERROR_PROCESS));
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_EXECUTE:
|
||||
if (event.trans_id == mbm_obj->curr_trans_id) {
|
||||
MB_RETURN_ON_FALSE(mbm_obj->rcv_frame, MB_EILLSTATE, TAG, MB_OBJ_FMT", receive buffer initialization fail.", MB_OBJ_PTR(inst));
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_EXECUTE", MB_OBJ_PTR(inst));
|
||||
if (MB_OBJ(inst->transp_obj)->frm_is_bcast(inst->transp_obj)
|
||||
&& ((mbm_obj->cur_mode == MB_RTU) || (mbm_obj->cur_mode == MB_ASCII))) {
|
||||
mbm_obj->rcv_frame = mbm_obj->snd_frame;
|
||||
}
|
||||
MB_RETURN_ON_FALSE(mbm_obj->rcv_frame, MB_EILLSTATE, TAG,
|
||||
MB_OBJ_FMT", receive buffer initialization fail.", MB_OBJ_PARENT(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.*/
|
||||
@@ -472,7 +481,7 @@ mb_err_enum_t mbm_poll(mb_base_t *inst)
|
||||
/* If master request is broadcast,
|
||||
* the master need execute function for all slave.
|
||||
*/
|
||||
if (inst->transp_obj->frm_is_bcast(inst->transp_obj)) {
|
||||
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);
|
||||
@@ -487,28 +496,28 @@ mb_err_enum_t mbm_poll(mb_base_t *inst)
|
||||
}
|
||||
/* If master has exception, will send error process event. Otherwise the master is idle.*/
|
||||
if (exception != MB_EX_NONE) {
|
||||
mb_port_evt_set_err_type(inst->port_obj, EV_ERROR_EXECUTE_FUNCTION);
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
mb_port_event_set_err_type(MB_OBJ(inst->port_obj), EV_ERROR_EXECUTE_FUNCTION);
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_ERROR_PROCESS));
|
||||
} else {
|
||||
error_type = mb_port_evt_get_err_type(inst->port_obj);
|
||||
error_type = mb_port_event_get_err_type(MB_OBJ(inst->port_obj));
|
||||
if (error_type == EV_ERROR_INIT) {
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT", set event EV_ERROR_OK", MB_OBJ_PTR(inst));
|
||||
mb_port_evt_set_err_type(inst->port_obj, EV_ERROR_OK);
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT", set event EV_ERROR_OK", MB_OBJ_PARENT(inst));
|
||||
mb_port_event_set_err_type(MB_OBJ(inst->port_obj), EV_ERROR_OK);
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_ERROR_PROCESS));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mb_port_evt_set_err_type(inst->port_obj, EV_ERROR_EXECUTE_FUNCTION);
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_ERROR_PROCESS));
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", execution is expired.", MB_OBJ_PTR(inst));
|
||||
mb_port_event_set_err_type(MB_OBJ(inst->port_obj), EV_ERROR_EXECUTE_FUNCTION);
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_ERROR_PROCESS));
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", execution is expired.", MB_OBJ_PARENT(inst));
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_ERROR_PROCESS:
|
||||
ESP_LOGW(TAG, MB_OBJ_FMT":EV_ERROR_PROCESS", MB_OBJ_PTR(inst));
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_ERROR_PROCESS", MB_OBJ_PARENT(inst));
|
||||
// stop timer and execute specified error process callback function.
|
||||
mb_port_tmr_disable(inst->port_obj);
|
||||
error_type = mb_port_evt_get_err_type(inst->port_obj);
|
||||
mb_port_timer_disable(MB_OBJ(inst->port_obj));
|
||||
error_type = mb_port_event_get_err_type(MB_OBJ(inst->port_obj));
|
||||
mbm_get_pdu_send_buf(inst, &mbm_obj->snd_frame);
|
||||
switch (error_type)
|
||||
{
|
||||
@@ -529,23 +538,23 @@ mb_err_enum_t mbm_poll(mb_base_t *inst)
|
||||
mbm_obj->snd_frame, mbm_obj->pdu_snd_len);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", incorrect error type = %d.", MB_OBJ_PTR(inst), (int)error_type);
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", incorrect error type = %d.", MB_OBJ_PARENT(inst), (int)error_type);
|
||||
break;
|
||||
}
|
||||
mb_port_evt_set_err_type(inst->port_obj, EV_ERROR_INIT);
|
||||
mb_port_event_set_err_type(MB_OBJ(inst->port_obj), EV_ERROR_INIT);
|
||||
uint64_t time_div_us = mbm_obj->curr_trans_id ? (event.get_ts - mbm_obj->curr_trans_id) : 0;
|
||||
mbm_obj->curr_trans_id = 0;
|
||||
ESP_LOGW(TAG, MB_OBJ_FMT", transaction processing time(us) = %" PRId64, MB_OBJ_PTR(inst), time_div_us);
|
||||
mb_port_evt_res_release(inst->port_obj);
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT", transaction processing time(us) = %" PRId64, MB_OBJ_PARENT(inst), time_div_us);
|
||||
mb_port_event_res_release(MB_OBJ(inst->port_obj));
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", unexpected event triggered 0x%02x.", MB_OBJ_PTR(inst), (int)event.event);
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", unexpected event triggered 0x%02x.", MB_OBJ_PARENT(inst), (int)event.event);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Something went wrong and task unblocked but there are no any correct events set
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", unexpected event triggered 0x%02x.", MB_OBJ_PTR(inst), (int)event.event);
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT", unexpected event triggered 0x%02x.", MB_OBJ_PARENT(inst), (int)event.event);
|
||||
status = MB_EILLSTATE;
|
||||
}
|
||||
return status;
|
||||
|
||||
@@ -225,12 +225,12 @@ error:
|
||||
|
||||
mb_err_enum_t mbs_delete(mb_base_t *inst)
|
||||
{
|
||||
mbs_object_t *mbs_obj = __containerof(inst, mbs_object_t, base);
|
||||
mbs_object_t *mbs_obj = MB_GET_OBJ_CTX(inst, mbs_object_t, base);
|
||||
mb_err_enum_t status = MB_ENOERR;
|
||||
if (mbs_obj->cur_state == STATE_DISABLED) {
|
||||
if (mbs_obj->base.transp_obj->frm_delete) {
|
||||
if (MB_OBJ(mbs_obj->base.transp_obj)->frm_delete) {
|
||||
// call destructor of the transport object
|
||||
mbs_obj->base.transp_obj->frm_delete(inst->transp_obj);
|
||||
MB_OBJ(mbs_obj->base.transp_obj)->frm_delete(inst->transp_obj);
|
||||
}
|
||||
// delete the modbus instance
|
||||
free(mbs_obj->base.descr.parent_name);
|
||||
@@ -247,12 +247,12 @@ mb_err_enum_t mbs_delete(mb_base_t *inst)
|
||||
|
||||
mb_err_enum_t mbs_enable(mb_base_t *inst)
|
||||
{
|
||||
mbs_object_t *mbs_obj = __containerof(inst, mbs_object_t, base);
|
||||
mbs_object_t *mbs_obj = MB_GET_OBJ_CTX(inst, mbs_object_t, base);
|
||||
mb_err_enum_t status = MB_ENOERR;
|
||||
CRITICAL_SECTION(inst->lock) {
|
||||
if (mbs_obj->cur_state == STATE_DISABLED) {
|
||||
/* Activate the protocol stack. */
|
||||
mbs_obj->base.transp_obj->frm_start(mbs_obj->base.transp_obj);
|
||||
MB_OBJ(mbs_obj->base.transp_obj)->frm_start(mbs_obj->base.transp_obj);
|
||||
mbs_obj->cur_state = STATE_ENABLED;
|
||||
status = MB_ENOERR;
|
||||
} else {
|
||||
@@ -269,10 +269,10 @@ mb_err_enum_t mbs_enable(mb_base_t *inst)
|
||||
mb_err_enum_t mbs_disable(mb_base_t *inst)
|
||||
{
|
||||
mb_err_enum_t status = MB_ENOERR;
|
||||
mbs_object_t *mbs_obj = __containerof(inst, mbs_object_t, base);
|
||||
mbs_object_t *mbs_obj = MB_GET_OBJ_CTX(inst, mbs_object_t, base);;
|
||||
CRITICAL_SECTION(inst->lock) {
|
||||
if (mbs_obj->cur_state == STATE_ENABLED) {
|
||||
mbs_obj->base.transp_obj->frm_stop(mbs_obj->base.transp_obj);
|
||||
MB_OBJ(mbs_obj->base.transp_obj)->frm_stop(mbs_obj->base.transp_obj);
|
||||
mbs_obj->cur_state = STATE_DISABLED;
|
||||
status = MB_ENOERR;
|
||||
} else if (mbs_obj->cur_state == STATE_DISABLED) {
|
||||
@@ -286,7 +286,7 @@ mb_err_enum_t mbs_disable(mb_base_t *inst)
|
||||
|
||||
mb_err_enum_t mbs_poll(mb_base_t *inst)
|
||||
{
|
||||
mbs_object_t *mbs_obj = __containerof(inst, mbs_object_t, base);
|
||||
mbs_object_t *mbs_obj = MB_GET_OBJ_CTX(inst, mbs_object_t, base);;
|
||||
|
||||
mb_exception_t exception;
|
||||
mb_err_enum_t status = MB_ENOERR;
|
||||
@@ -298,45 +298,44 @@ mb_err_enum_t mbs_poll(mb_base_t *inst)
|
||||
}
|
||||
|
||||
/* Check if there is a event available. If not, return control to caller. Otherwise we will handle the event. */
|
||||
if (mb_port_evt_get(mbs_obj->base.port_obj, &event)) {
|
||||
if (mb_port_event_get(MB_OBJ(mbs_obj->base.port_obj), &event)) {
|
||||
switch(event.event) {
|
||||
case EV_READY:
|
||||
ESP_LOGW(TAG, MB_OBJ_FMT":EV_READY", MB_OBJ_PTR(inst));
|
||||
mb_port_evt_res_release(inst->port_obj);
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_READY", MB_OBJ_PARENT(inst));
|
||||
mb_port_event_res_release(MB_OBJ(inst->port_obj));
|
||||
break;
|
||||
|
||||
case EV_FRAME_RECEIVED:
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_FRAME_RECEIVED", MB_OBJ_PTR(inst));
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_FRAME_RECEIVED", MB_OBJ_PARENT(inst));
|
||||
mbs_obj->length = event.length;
|
||||
status = inst->transp_obj->frm_rcv(inst->transp_obj, &mbs_obj->rcv_addr, &mbs_obj->frame, &mbs_obj->length);
|
||||
status = MB_OBJ(inst->transp_obj)->frm_rcv(inst->transp_obj, &mbs_obj->rcv_addr, &mbs_obj->frame, &mbs_obj->length);
|
||||
// Check if the frame is for us. If not ,send an error process event.
|
||||
if (status == MB_ENOERR) {
|
||||
// Check if the frame is for us. If not ignore the frame.
|
||||
if((mbs_obj->rcv_addr == mbs_obj->mb_address) || (mbs_obj->rcv_addr == MB_ADDRESS_BROADCAST)
|
||||
|| (mbs_obj->rcv_addr == MB_TCP_PSEUDO_ADDRESS)) {
|
||||
mbs_obj->curr_trans_id = event.get_ts;
|
||||
(void)mb_port_evt_post(inst->port_obj, EVENT(EV_EXECUTE | EV_TRANS_START));
|
||||
(void)mb_port_event_post(MB_OBJ(inst->port_obj), EVENT(EV_EXECUTE | EV_TRANS_START));
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(MB_STR_CAT(inst->descr.parent_name, ":MB_RECV"), &mbs_obj->frame[MB_PDU_FUNC_OFF],
|
||||
(uint16_t)mbs_obj->length, ESP_LOG_WARN);
|
||||
(uint16_t)mbs_obj->length, ESP_LOG_DEBUG);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_EXECUTE:
|
||||
MB_RETURN_ON_FALSE(mbs_obj->frame, MB_EILLSTATE, TAG, "receive buffer fail.");
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_EXECUTE", MB_OBJ_PTR(inst));
|
||||
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) {
|
||||
if (mbs_obj->func_code == 0x04) {
|
||||
ESP_LOGW(TAG, "Read input registers");
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -350,34 +349,34 @@ mb_err_enum_t mbs_poll(mb_base_t *inst)
|
||||
mbs_obj->frame[mbs_obj->length++] = exception;
|
||||
}
|
||||
if ((mbs_obj->cur_mode == MB_ASCII) && MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS) {
|
||||
mb_port_tmr_delay(inst->port_obj, MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS);
|
||||
mb_port_timer_delay(MB_OBJ(inst->port_obj), MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS);
|
||||
}
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(MB_STR_CAT(inst->descr.parent_name, ":MB_SEND"), (void *)mbs_obj->frame, mbs_obj->length, ESP_LOG_WARN);
|
||||
status = inst->transp_obj->frm_send(inst->transp_obj, mbs_obj->rcv_addr, mbs_obj->frame, mbs_obj->length);
|
||||
ESP_LOG_BUFFER_HEX_LEVEL(MB_STR_CAT(inst->descr.parent_name, ":MB_SEND"), (void *)mbs_obj->frame, mbs_obj->length, ESP_LOG_DEBUG);
|
||||
status = MB_OBJ(inst->transp_obj)->frm_send(inst->transp_obj, mbs_obj->rcv_addr, mbs_obj->frame, mbs_obj->length);
|
||||
if (status != MB_ENOERR) {
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT":frame send error. %d", MB_OBJ_PTR(inst), (int)status);
|
||||
ESP_LOGE(TAG, MB_OBJ_FMT":frame send error. %d", MB_OBJ_PARENT(inst), (int)status);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_FRAME_TRANSMIT:
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_FRAME_TRANSMIT", MB_OBJ_PTR(inst));
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_FRAME_TRANSMIT", MB_OBJ_PARENT(inst));
|
||||
break;
|
||||
|
||||
case EV_FRAME_SENT:
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_MASTER_FRAME_SENT", MB_OBJ_PTR(inst));
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT":EV_MASTER_FRAME_SENT", MB_OBJ_PARENT(inst));
|
||||
uint64_t time_div_us = mbs_obj->curr_trans_id ? (event.get_ts - mbs_obj->curr_trans_id) : 0;
|
||||
mbs_obj->curr_trans_id = 0;
|
||||
ESP_LOGW(TAG, MB_OBJ_FMT", transaction processing time(us) = %" PRId64, MB_OBJ_PTR(inst), time_div_us);
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT", transaction processing time(us) = %" PRId64, MB_OBJ_PARENT(inst), time_div_us);
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT": Unexpected event triggered 0x%02x.", MB_OBJ_PTR(inst), (int)event.event);
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT": Unexpected event triggered 0x%02x.", MB_OBJ_PARENT(inst), (int)event.event);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Something went wrong and task unblocked but there are no any correct events set
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT": Unexpected event triggered 0x%02x, timeout?", MB_OBJ_PTR(inst), (int)event.event);
|
||||
ESP_LOGD(TAG, MB_OBJ_FMT": Unexpected event triggered 0x%02x, timeout?", MB_OBJ_PARENT(inst), (int)event.event);
|
||||
status = MB_EILLSTATE;
|
||||
}
|
||||
return status;
|
||||
|
||||
Reference in new issue
Block a user