forked from espressif/esp-modbus
298 lines
10 KiB
C
298 lines
10 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
// Public interface header for slave
|
|
#include <stdint.h> // for standard int types definition
|
|
#include <stddef.h> // for NULL and std defines
|
|
#include "soc/soc.h" // for BITN definitions
|
|
#include "freertos/FreeRTOS.h" // for task creation and queues access
|
|
#include "freertos/event_groups.h" // for event groups
|
|
#include "esp_modbus_common.h" // for common types
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define REG_SIZE(type, nregs) ((type == MB_PARAM_INPUT) || (type == MB_PARAM_HOLDING)) ? (nregs >> 1) : (nregs << 3)
|
|
|
|
#define MB_SLAVE_ASSERT(con) do { \
|
|
if (!(con)) { ESP_LOGE(TAG, "assert errno:%d, errno_str: !(%s)", errno, strerror(errno)); assert(0 && #con); } \
|
|
} while (0)
|
|
|
|
#define MB_SLAVE_GET_IFACE(pctx) (__extension__( \
|
|
{ \
|
|
MB_SLAVE_ASSERT((pctx)); \
|
|
((mbs_controller_iface_t*)pctx); \
|
|
} \
|
|
))
|
|
|
|
#define MB_SLAVE_GET_OPTS(pctx) (&MB_SLAVE_GET_IFACE(pctx)->opts)
|
|
|
|
#define MB_SLAVE_IS_ACTIVE(pctx) ((bool)(MB_SLAVE_GET_IFACE(pctx)->is_active))
|
|
|
|
#define MB_SLAVE_GET_IFACE_FROM_BASE(pinst) (__extension__( \
|
|
{ \
|
|
MB_SLAVE_ASSERT(pinst); \
|
|
mb_base_t *pbase = (mb_base_t*)pinst; \
|
|
MB_RETURN_ON_FALSE(pbase->descr.parent, MB_EILLSTATE, TAG, "Slave interface is not correctly initialized."); \
|
|
((mbs_controller_iface_t*)pbase->descr.parent); \
|
|
} \
|
|
))
|
|
|
|
/**
|
|
* @brief Parameter access event information type
|
|
*/
|
|
typedef struct {
|
|
uint32_t time_stamp; /*!< Timestamp of Modbus Event (uS)*/
|
|
uint16_t mb_offset; /*!< Modbus register offset */
|
|
mb_event_group_t type; /*!< Modbus event type */
|
|
uint8_t *address; /*!< Modbus data storage address */
|
|
size_t size; /*!< Modbus event register size (number of registers)*/
|
|
} mb_param_info_t;
|
|
|
|
/**
|
|
* @brief Area access type modificator
|
|
*/
|
|
typedef enum {
|
|
MB_ACCESS_RW = 0x0000,
|
|
MB_ACCESS_RO = 0x0001,
|
|
MB_ACCESS_WO = 0x0002
|
|
} mb_param_access_t;
|
|
|
|
/**
|
|
* @brief Parameter storage area descriptor
|
|
*/
|
|
typedef struct {
|
|
uint16_t start_offset; /*!< Modbus start address for area descriptor */
|
|
mb_param_type_t type; /*!< Type of storage area descriptor */
|
|
mb_param_access_t access; /*!< Area access type */
|
|
void *address; /*!< Instance address for storage area descriptor */
|
|
size_t size; /*!< Instance size for area descriptor (bytes) */
|
|
} mb_register_area_descriptor_t;
|
|
|
|
/**
|
|
* @brief Initialize Modbus Slave controller and stack for TCP port
|
|
*
|
|
* @param[out] ctx context pointer of the initialized modbus interface
|
|
* @param[in] config - pointer to configuration structure for the slave
|
|
*
|
|
* @return
|
|
* - ESP_OK Success
|
|
* - ESP_ERR_NO_MEM Parameter error
|
|
* - ESP_ERR_NOT_SUPPORTED Port type not supported
|
|
* - ESP_ERR_INVALID_STATE Initialization failure
|
|
*/
|
|
esp_err_t mbc_slave_create_tcp(mb_communication_info_t *config, void **ctx);
|
|
|
|
/**
|
|
* @brief Initialize Modbus Slave controller and stack for Serial port
|
|
*
|
|
* @param[out] ctx context pointer of the initialized modbus interface
|
|
* @param[in] config - pointer to configuration structure for the slave
|
|
*
|
|
* @return
|
|
* - ESP_OK Success
|
|
* - ESP_ERR_NO_MEM Parameter error
|
|
* - ESP_ERR_NOT_SUPPORTED Port type not supported
|
|
* - ESP_ERR_INVALID_STATE Initialization failure
|
|
*/
|
|
esp_err_t mbc_slave_create_serial(mb_communication_info_t *config, void **ctx);
|
|
|
|
/**
|
|
* @brief Initialize Modbus Slave controller interface handle
|
|
*
|
|
* @param[in] ctx - pointer to slave interface data structure
|
|
*/
|
|
void mbc_slave_init_iface(void *ctx);
|
|
|
|
/**
|
|
* @brief Deletes Modbus controller and stack engine
|
|
*
|
|
* @param[in] ctx context pointer of the initialized modbus interface
|
|
*
|
|
* @return
|
|
* - ESP_OK Success
|
|
* - ESP_ERR_INVALID_STATE Parameter error
|
|
*/
|
|
esp_err_t mbc_slave_delete(void *ctx);
|
|
|
|
/**
|
|
* @brief Critical section lock function for parameter access
|
|
*
|
|
* @param[in] ctx pointer to slave handle (modbus interface)
|
|
* @return
|
|
* - ESP_OK Success
|
|
* - ESP_ERR_INVALID_STATE Initialization failure
|
|
*/
|
|
esp_err_t mbc_slave_lock(void *ctx);
|
|
|
|
/**
|
|
* @brief Critical section unlock for parameter access
|
|
*
|
|
* @param[in] ctx pointer to slave handle (modbus interface)
|
|
* @return
|
|
* - ESP_OK Success
|
|
* - ESP_ERR_INVALID_STATE Initialization failure
|
|
*/
|
|
esp_err_t mbc_slave_unlock(void *ctx);
|
|
|
|
/**
|
|
* @brief Start of Modbus communication stack
|
|
*
|
|
* @param[in] ctx context pointer of the initialized modbus interface
|
|
*
|
|
* @return
|
|
* - ESP_OK Success
|
|
* - ESP_ERR_INVALID_ARG Modbus stack start error
|
|
*/
|
|
esp_err_t mbc_slave_start(void *ctx);
|
|
|
|
/**
|
|
* @brief Stop of Modbus communication stack
|
|
*
|
|
* @param[in] ctx context pointer of the initialized modbus interface
|
|
*
|
|
* @return
|
|
* - ESP_OK Success
|
|
* - ESP_ERR_INVALID_ARG Modbus stack stop error
|
|
*/
|
|
esp_err_t mbc_slave_stop(void *ctx);
|
|
|
|
/**
|
|
* @brief Wait for specific event on parameter change.
|
|
*
|
|
* @param[in] ctx context pointer of the initialized modbus interface
|
|
* @param group Group event bit mask to wait for change
|
|
*
|
|
* @return
|
|
* - mb_event_group_t event bits triggered
|
|
*/
|
|
mb_event_group_t mbc_slave_check_event(void *ctx, mb_event_group_t group);
|
|
|
|
/**
|
|
* @brief Get parameter information
|
|
*
|
|
* @param[in] ctx context pointer of the initialized modbus interface *
|
|
* @param[out] reg_info parameter info structure
|
|
* @param[in] timeout Timeout in milliseconds to read information from
|
|
* parameter queue
|
|
*
|
|
* @return
|
|
* - ESP_OK Success
|
|
* - ESP_ERR_TIMEOUT Can not get data from parameter queue
|
|
* or queue overflow
|
|
*/
|
|
esp_err_t mbc_slave_get_param_info(void *ctx, mb_param_info_t *reg_info, uint32_t timeout);
|
|
|
|
/**
|
|
* @brief Set Modbus area descriptor
|
|
*
|
|
* @param[in] ctx context pointer of the initialized modbus interface *
|
|
* @param descr_data Modbus registers area descriptor structure
|
|
*
|
|
* @return
|
|
* - ESP_OK: The appropriate descriptor is set
|
|
* - ESP_ERR_INVALID_ARG: The argument is incorrect
|
|
*/
|
|
esp_err_t mbc_slave_set_descriptor(void *ctx, mb_register_area_descriptor_t descr_data);
|
|
|
|
// The support of <0x11 - Report Slave ID> command is intentionally included for TCP slave as well!
|
|
#if CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT
|
|
/**
|
|
* @brief Set Modbus slave identificator
|
|
*
|
|
* @param[in] ctx context pointer of the initialized modbus interface
|
|
* @param[in] uid - unit identifier (short slave address) for Modbus slave
|
|
* @param[in] is_running - Modbus slave running status
|
|
* @param[in] pdata - pointer to data buffer for extended context (vendor specific)
|
|
* @param[in] data_len - length of data buffer (the length of the extended context)
|
|
*
|
|
* @return
|
|
* - ESP_OK: The appropriate identificator is set
|
|
* - ESP_ERR_INVALID_ARG: The argument is incorrect
|
|
*/
|
|
esp_err_t mbc_set_slave_id(void *ctx, uint8_t uid, bool is_running, uint8_t const *pdata, uint8_t data_len);
|
|
|
|
/*! \brief Get slave identificator from the modbus object.
|
|
*
|
|
* This function is used to get the Slave ID array for modbus object.
|
|
*
|
|
* \param ctx - context pointer of the initialized modbus interface
|
|
* \param pdata - the pointer to store object ID array from the modbus object
|
|
* \param[in/out] pdata_len - in: length of the allocated pdata array,
|
|
* out: returns the actual length of object id.
|
|
* returns the modbus error code = ESP_OK, if set correctly,
|
|
* ESP_ERR_INVALID_RESPONSE - if the object ID is not set,
|
|
* ESP_ERR_INVALID_STATE - no space to store object ID in the pdata buffer,
|
|
* or incorrect arguments are provided
|
|
*/
|
|
esp_err_t mbc_get_slave_id(void *ctx, uint8_t const *pdata, uint8_t *pdata_len);
|
|
#endif
|
|
|
|
/**
|
|
* @brief Holding register read/write callback function
|
|
*
|
|
* @param[in] inst the pointer of the initialized modbus base
|
|
* @param[in] reg_buffer input buffer of registers
|
|
* @param[in] address - start address of register
|
|
* @param[in] n_regs - number of registers
|
|
* @param[in] mode - parameter access mode (MB_REG_READ, MB_REG_WRITE)
|
|
*
|
|
* @return
|
|
* - MB_ENOERR: Read write is successful
|
|
* - MB_ENOREG: The argument is incorrect
|
|
*/
|
|
mb_err_enum_t mbc_reg_holding_slave_cb(mb_base_t *inst, uint8_t *reg_buffer, uint16_t address, uint16_t n_regs, mb_reg_mode_enum_t mode) __attribute__ ((weak));
|
|
|
|
/**
|
|
* @brief Input register read/write callback function
|
|
*
|
|
* @param[in] inst the pointer of the initialized modbus base
|
|
* @param[in] reg_buffer input buffer of registers
|
|
* @param[in] address - start address of register
|
|
* @param[in] n_regs - number of registers
|
|
*
|
|
* @return
|
|
* - MB_ENOERR: Read write is successful
|
|
* - MB_ENOREG: The argument is incorrect
|
|
*/
|
|
mb_err_enum_t mbc_reg_input_slave_cb(mb_base_t *inst, uint8_t *reg_buffer, uint16_t address, uint16_t n_regs) __attribute__ ((weak));
|
|
|
|
/**
|
|
* @brief Discrete register read/write callback function
|
|
*
|
|
* @param[in] inst the pointer of the initialized modbus base
|
|
* @param[in] reg_buffer input buffer of registers
|
|
* @param[in] address - start address of register
|
|
* @param[in] n_discrete - number of discrete registers
|
|
*
|
|
* @return
|
|
* - MB_ENOERR: Read write is successful
|
|
* - MB_ENOREG: The argument is incorrect
|
|
*/
|
|
mb_err_enum_t mbc_reg_discrete_slave_cb(mb_base_t *inst, uint8_t *reg_buffer, uint16_t address, uint16_t n_discrete) __attribute__ ((weak));
|
|
|
|
/**
|
|
* @brief Coil register read/write callback function
|
|
*
|
|
* @param[in] inst the pointer of the initialized modbus base
|
|
* @param[in] reg_buffer input buffer of registers
|
|
* @param[in] address - start address of register
|
|
* @param[in] n_coils - number of discrete registers
|
|
* @param[in] mode - parameter access mode (MB_REG_READ, MB_REG_WRITE)
|
|
*
|
|
* @return
|
|
* - MB_ENOERR: Read write is successful
|
|
* - MB_ENOREG: The argument is incorrect
|
|
*/
|
|
mb_err_enum_t mbc_reg_coils_slave_cb(mb_base_t *inst, uint8_t *reg_buffer, uint16_t address, uint16_t n_coils, mb_reg_mode_enum_t mode) __attribute__ ((weak));
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|