forked from espressif/esp-modbus
mb master, slave add custom fc handlers
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "mb_config.h"
|
||||
#include "mb_types.h"
|
||||
|
||||
#if __has_include("esp_idf_version.h")
|
||||
#include "esp_idf_version.h"
|
||||
#endif
|
||||
|
||||
// Workaround for atomics incompatibility issue under CPP.
|
||||
#if defined(__cplusplus) && (IDF_VERSION <= ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
#include <atomic>
|
||||
#define _Atomic(T) std::atomic<T>
|
||||
#define atomic_int int
|
||||
#else
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#else
|
||||
// This is to verify the atomic int types for C compilation unit have the same layout as int type.
|
||||
static_assert(
|
||||
(sizeof(_Atomic(int)) == sizeof(int) && sizeof(_Atomic int) == sizeof(int)),
|
||||
"the _Atomic int types are not layout compatible with int type"
|
||||
);
|
||||
#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)
|
||||
|
||||
#include "driver/uart.h"
|
||||
|
||||
struct _port_serial_opts {
|
||||
mb_mode_type_t mode; /*!< Modbus communication mode */
|
||||
uart_port_t port; /*!< Modbus communication port (UART) number */
|
||||
uint8_t uid; /*!< Modbus slave address field (dummy for master) */
|
||||
uint32_t response_tout_ms; /*!< Modbus slave response timeout */
|
||||
uint64_t test_tout_us; /*!< Modbus test timeout (reserved) */
|
||||
uint32_t baudrate; /*!< Modbus baudrate */
|
||||
uart_word_length_t data_bits; /*!< Modbus number of data bits */
|
||||
uart_stop_bits_t stop_bits; /*!< Modbus number of stop bits */
|
||||
uart_parity_t parity; /*!< Modbus UART parity settings */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
typedef struct _port_serial_opts mb_serial_opts_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef enum _addr_type_enum {
|
||||
MB_NOIP = 0,
|
||||
MB_IPV4 = 1, /*!< TCP IPV4 addressing */
|
||||
MB_IPV6 = 2 /*!< TCP IPV6 addressing */
|
||||
} mb_addr_type_t;
|
||||
|
||||
|
||||
struct _port_common_opts {
|
||||
mb_mode_type_t mode; /*!< Modbus communication mode */
|
||||
uint16_t port; /*!< Modbus communication port (UART) number */
|
||||
uint8_t uid; /*!< Modbus slave address field (dummy for master) */
|
||||
uint32_t response_tout_ms; /*!< Modbus slave response timeout */
|
||||
uint64_t test_tout_us; /*!< Modbus test timeout (reserved) */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
struct _port_tcp_opts {
|
||||
mb_mode_type_t mode; /*!< Modbus communication mode */
|
||||
uint16_t port; /*!< Modbus communication port (UART) number */
|
||||
uint8_t uid; /*!< Modbus slave address field (dummy for master) */
|
||||
uint32_t response_tout_ms; /*!< Modbus slave response timeout */
|
||||
uint64_t test_tout_us; /*!< Modbus test timeout (reserved) */
|
||||
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 */
|
||||
char *dns_name; /*!< Modbus node DNS name */
|
||||
bool start_disconnected; /*!< (Master only option) do not wait for connection to all nodes before polling */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
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; /*!< 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, /*!< 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; /*!< 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; /*!< node unit ID (UID) field for MBAP frame */
|
||||
uint16_t port; /*!< node port number */
|
||||
mb_comm_mode_t proto; /*!< protocol type */
|
||||
_Atomic(int) state; /*!< node state */
|
||||
void *inst; /*!< pointer to linked instance */
|
||||
} mb_uid_info_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "stdbool.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ----------------------- Type definitions ---------------------------------*/
|
||||
|
||||
/*! \ingroup modbus
|
||||
* \brief Modbus serial transmission modes (RTU/ASCII/TCP/UDP).
|
||||
*
|
||||
* Modbus serial supports two transmission modes. Either ASCII or RTU. RTU
|
||||
* is faster but has more hardware requirements and requires a network with
|
||||
* a low jitter. ASCII is slower and more reliable on slower links (E.g. modems)
|
||||
* The TCP or UDP mode is used for communication over ethernet.
|
||||
*/
|
||||
typedef enum _mb_comm_mode
|
||||
{
|
||||
MB_RTU, /*!< RTU transmission mode. */
|
||||
MB_ASCII, /*!< ASCII transmission mode. */
|
||||
MB_TCP, /*!< TCP mode. */
|
||||
MB_UDP /*!< UDP mode. */
|
||||
} mb_comm_mode_t;
|
||||
|
||||
/*! \ingroup modbus
|
||||
* \brief If register should be written or read.
|
||||
*
|
||||
* This value is passed to the callback functions which support either
|
||||
* reading or writing register values. Writing means that the application
|
||||
* registers should be updated and reading means that the modbus protocol
|
||||
* stack needs to know the current register values.
|
||||
*
|
||||
* \see mbs_reg_holding_cb(), mbs_reg_coils_cb(), mbs_reg_holding_cb() and
|
||||
* mbs_reg_input_cb().
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MB_REG_READ = 0x0001, /*!< Read register values and pass to protocol stack. */
|
||||
MB_REG_WRITE = 0x0002, /*!< Update register values. */
|
||||
} mb_reg_mode_enum_t;
|
||||
|
||||
/*! \ingroup modbus
|
||||
* \brief Event types used by all function in the protocol stack.
|
||||
*/
|
||||
typedef enum _mb_event_enum {
|
||||
EV_TRANS_START = 0x0001, /*!< Start of transaction. */
|
||||
EV_READY = 0x0002, /*!< Startup finished. */
|
||||
EV_FRAME_RECEIVED = 0x0004, /*!< Frame received. */
|
||||
EV_EXECUTE = 0x0008, /*!< Execute function. */
|
||||
EV_FRAME_TRANSMIT = 0x0010, /*!< Transmission started . */
|
||||
EV_FRAME_SENT = 0x0020, /*!< Frame sent. */
|
||||
EV_ERROR_PROCESS = 0x0040, /*!< Error process state. */
|
||||
EV_MASTER_ERROR_RESPOND_TIMEOUT = 0x0080, /*!< Request respond timeout. */
|
||||
EV_MASTER_ERROR_RECEIVE_DATA = 0x0100, /*!< Request receive data error. */
|
||||
EV_MASTER_ERROR_EXECUTE_FUNCTION = 0x0200, /*!< Request execute function error. */
|
||||
EV_MASTER_PROCESS_SUCCESS = 0x0400 /*!< Master error process. */
|
||||
} mb_event_enum_t;
|
||||
|
||||
/*! \ingroup modbus
|
||||
* \brief Error event type
|
||||
*/
|
||||
typedef enum _mb_err_event_enum {
|
||||
EV_ERROR_INIT, /*!< No error, initial state. */
|
||||
EV_ERROR_RESPOND_TIMEOUT, /*!< Slave respond timeout. */
|
||||
EV_ERROR_RECEIVE_DATA, /*!< Receive frame data error. */
|
||||
EV_ERROR_EXECUTE_FUNCTION, /*!< Execute function error. */
|
||||
EV_ERROR_OK /*!< No error, processing completed. */
|
||||
} mb_err_event_t;
|
||||
|
||||
typedef struct _mb_event_t {
|
||||
mb_event_enum_t event; /*!< event itself. */
|
||||
uint64_t trans_id; /*!< unique transaction id */
|
||||
uint16_t length; /*!< length of data accociated with the event */
|
||||
void *pdata; /*!< data accociated with the event */
|
||||
mb_err_event_t type; /*!< error type accociated with the event */
|
||||
uint64_t post_ts; /*!< timestamp of event posted */
|
||||
uint64_t get_ts; /*!< timestamp of event receved */
|
||||
} mb_event_t;
|
||||
|
||||
/*! \ingroup modbus
|
||||
* \brief Errorcodes used by all function in the protocol stack.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MB_ENOERR, /*!< no error. */
|
||||
MB_ENOREG, /*!< illegal register address. */
|
||||
MB_EINVAL, /*!< illegal argument. */
|
||||
MB_EPORTERR, /*!< porting layer error. */
|
||||
MB_ENORES, /*!< insufficient resources. */
|
||||
MB_EIO, /*!< I/O error. */
|
||||
MB_EILLSTATE, /*!< protocol stack in illegal state. */
|
||||
MB_ERECVDATA, /*!< receive data error. */
|
||||
MB_ETIMEDOUT, /*!< timeout error occurred. */
|
||||
MB_EILLFUNC, /*!< illegal MB function. */
|
||||
MB_EBUSY, /*!< master is busy now. */
|
||||
MB_ENOCONN /*!< peer is not connected. */
|
||||
} mb_err_enum_t;
|
||||
|
||||
/*! \ingroup modbus
|
||||
* \brief TimerMode is Master 3 kind of Timer modes.
|
||||
*/
|
||||
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_timer_mode_enum_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user