forked from espressif/esp-modbus
add the function to expose the transaction info
This commit is contained in:
@@ -237,6 +237,24 @@ eMBErrorCode eMBMasterRegInputCB(UCHAR * pucRegBuffer, USHORT usAddress,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to get current transaction info
|
||||||
|
*/
|
||||||
|
esp_err_t mbc_master_get_transaction_info(mb_trans_info_t *ptinfo)
|
||||||
|
{
|
||||||
|
mb_trans_info_t tinfo = {0};
|
||||||
|
MB_MASTER_CHECK((ptinfo),
|
||||||
|
ESP_ERR_INVALID_ARG,
|
||||||
|
"Wrong argument.");
|
||||||
|
MB_MASTER_CHECK(xMBMasterGetLastTransactionInfo(&tinfo.trans_id, &tinfo.dest_addr,
|
||||||
|
&tinfo.func_code, &tinfo.exception,
|
||||||
|
&tinfo.err_type),
|
||||||
|
ESP_ERR_INVALID_STATE,
|
||||||
|
"Master can not get transaction info.");
|
||||||
|
*ptinfo = tinfo;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to set parameter buffer according to its type
|
// Helper function to set parameter buffer according to its type
|
||||||
esp_err_t mbc_master_set_param_data(void* dest, void* src, mb_descr_type_t param_type, size_t param_size)
|
esp_err_t mbc_master_set_param_data(void* dest, void* src, mb_descr_type_t param_type, size_t param_size)
|
||||||
{
|
{
|
||||||
|
@@ -150,6 +150,17 @@ typedef struct {
|
|||||||
uint16_t reg_size; /*!< Modbus number of registers */
|
uint16_t reg_size; /*!< Modbus number of registers */
|
||||||
} mb_param_request_t;
|
} mb_param_request_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Modbus transacion info structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint64_t trans_id; /*!< Modbus unique transaction identificator */
|
||||||
|
uint8_t dest_addr; /*!< Modbus destination short address (or UID) */
|
||||||
|
uint8_t func_code; /*!< Modbus last transaction function code */
|
||||||
|
uint8_t exception; /*!< Modbus last transaction exception code returned by slave */
|
||||||
|
uint16_t err_type; /*!< Modbus last transaction error type */
|
||||||
|
} mb_trans_info_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize Modbus controller and stack for TCP port
|
* @brief Initialize Modbus controller and stack for TCP port
|
||||||
*
|
*
|
||||||
@@ -321,6 +332,18 @@ esp_err_t mbc_master_set_parameter(uint16_t cid, char* name, uint8_t* value, uin
|
|||||||
*/
|
*/
|
||||||
esp_err_t mbc_master_set_param_data(void* dest, void* src, mb_descr_type_t param_type, size_t param_size);
|
esp_err_t mbc_master_set_param_data(void* dest, void* src, mb_descr_type_t param_type, size_t param_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The helper function to expose transaction info from modbus layer
|
||||||
|
*
|
||||||
|
* @param[in] ptinfo the pointer to transaction info structure
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - esp_err_t ESP_OK - the transaction info is saved in the appropriate parameter structure
|
||||||
|
* - esp_err_t ESP_ERR_INVALID_ARG - invalid argument of function or parameter descriptor
|
||||||
|
* - esp_err_t ESP_ERR_INVALID_STATE - invalid state during data processing or allocation failure
|
||||||
|
*/
|
||||||
|
esp_err_t mbc_master_get_transaction_info(mb_trans_info_t *ptinfo);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "esp_modbus_common.h" // for common types
|
#include "esp_modbus_common.h" // for common types
|
||||||
#include "esp_modbus_master.h" // for public master types
|
#include "esp_modbus_master.h" // for public master types
|
||||||
#include "esp_modbus_callbacks.h"
|
#include "esp_modbus_callbacks.h"
|
||||||
|
#include "mb_m.h" // this is required to expose current transaction info
|
||||||
|
|
||||||
/* ----------------------- Defines ------------------------------------------*/
|
/* ----------------------- Defines ------------------------------------------*/
|
||||||
|
|
||||||
|
@@ -100,9 +100,9 @@ typedef enum
|
|||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
MB_TMODE_T35, /*!< Master receive frame T3.5 timeout. */
|
MB_TMODE_T35, /*!< Master receive frame T3.5 timeout. */
|
||||||
MB_TMODE_RESPOND_TIMEOUT, /*!< Master wait respond for slave. */
|
MB_TMODE_RESPOND_TIMEOUT, /*!< Master wait respond for slave. */
|
||||||
MB_TMODE_CONVERT_DELAY /*!< Master sent broadcast ,then delay sometime.*/
|
MB_TMODE_CONVERT_DELAY /*!< Master sent broadcast ,then delay sometime.*/
|
||||||
} eMBMasterTimerMode;
|
} eMBMasterTimerMode;
|
||||||
|
|
||||||
/* ----------------------- Function prototypes ------------------------------*/
|
/* ----------------------- Function prototypes ------------------------------*/
|
||||||
@@ -128,7 +128,7 @@ typedef enum
|
|||||||
* - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
|
* - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBMasterSerialInit( eMBMode eMode, UCHAR ucPort,
|
eMBErrorCode eMBMasterSerialInit( eMBMode eMode, UCHAR ucPort,
|
||||||
ULONG ulBaudRate, eMBParity eParity );
|
ULONG ulBaudRate, eMBParity eParity );
|
||||||
|
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
* \brief Initialize the Modbus Master protocol stack for Modbus TCP.
|
* \brief Initialize the Modbus Master protocol stack for Modbus TCP.
|
||||||
@@ -220,7 +220,7 @@ eMBErrorCode eMBMasterPoll( void );
|
|||||||
* valid it returns eMBErrorCode::MB_EINVAL.
|
* valid it returns eMBErrorCode::MB_EINVAL.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBMasterRegisterCB( UCHAR ucFunctionCode,
|
eMBErrorCode eMBMasterRegisterCB( UCHAR ucFunctionCode,
|
||||||
pxMBFunctionHandler pxHandler );
|
pxMBFunctionHandler pxHandler );
|
||||||
|
|
||||||
/* ----------------------- Callback -----------------------------------------*/
|
/* ----------------------- Callback -----------------------------------------*/
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ eMBErrorCode eMBMasterRegisterCB( UCHAR ucFunctionCode,
|
|||||||
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
|
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
||||||
USHORT usNRegs );
|
USHORT usNRegs );
|
||||||
|
|
||||||
/*! \ingroup modbus_registers
|
/*! \ingroup modbus_registers
|
||||||
* \brief Callback function used if a <em>Holding Register</em> value is
|
* \brief Callback function used if a <em>Holding Register</em> value is
|
||||||
@@ -290,7 +290,7 @@ eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
|||||||
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
|
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBMasterRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
eMBErrorCode eMBMasterRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
||||||
USHORT usNRegs, eMBRegisterMode eMode );
|
USHORT usNRegs, eMBRegisterMode eMode );
|
||||||
|
|
||||||
/*! \ingroup modbus_registers
|
/*! \ingroup modbus_registers
|
||||||
* \brief Callback function used if a <em>Coil Register</em> value is
|
* \brief Callback function used if a <em>Coil Register</em> value is
|
||||||
@@ -319,7 +319,7 @@ eMBErrorCode eMBMasterRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
|||||||
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
|
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBMasterRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
eMBErrorCode eMBMasterRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
||||||
USHORT usNCoils, eMBRegisterMode eMode );
|
USHORT usNCoils, eMBRegisterMode eMode );
|
||||||
|
|
||||||
/*! \ingroup modbus_registers
|
/*! \ingroup modbus_registers
|
||||||
* \brief Callback function used if a <em>Input Discrete Register</em> value is
|
* \brief Callback function used if a <em>Input Discrete Register</em> value is
|
||||||
@@ -342,7 +342,7 @@ eMBErrorCode eMBMasterRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
|||||||
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
|
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress,
|
||||||
USHORT usNDiscrete );
|
USHORT usNDiscrete );
|
||||||
|
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
*\brief These Modbus functions are called for user when Modbus run in Master Mode.
|
*\brief These Modbus functions are called for user when Modbus run in Master Mode.
|
||||||
@@ -353,20 +353,20 @@ eMBMasterReqErrCode
|
|||||||
eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut );
|
eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr,
|
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr,
|
||||||
USHORT usNRegs, USHORT * pusDataBuffer, LONG lTimeOut );
|
USHORT usNRegs, USHORT * pusDataBuffer, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut );
|
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
||||||
USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
|
USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
|
||||||
USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut );
|
USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils, LONG lTimeOut );
|
eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LONG lTimeOut );
|
eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
||||||
USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer, LONG lTimeOut );
|
USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut );
|
eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut );
|
||||||
|
|
||||||
@@ -409,6 +409,9 @@ eMBMasterErrorEventType eMBMasterGetErrorType( void );
|
|||||||
void vMBMasterSetErrorType( eMBMasterErrorEventType errorType );
|
void vMBMasterSetErrorType( eMBMasterErrorEventType errorType );
|
||||||
eMBMasterReqErrCode eMBMasterWaitRequestFinish( void );
|
eMBMasterReqErrCode eMBMasterWaitRequestFinish( void );
|
||||||
eMBMode ucMBMasterGetCommMode( void );
|
eMBMode ucMBMasterGetCommMode( void );
|
||||||
|
BOOL xMBMasterGetLastTransactionInfo( uint64_t *pxTransId, UCHAR *pucDestAddress,
|
||||||
|
UCHAR *pucFunctionCode, UCHAR *pucException,
|
||||||
|
USHORT *pusErrorType );
|
||||||
|
|
||||||
/* ----------------------- Callback -----------------------------------------*/
|
/* ----------------------- Callback -----------------------------------------*/
|
||||||
|
|
||||||
|
@@ -95,7 +95,7 @@ typedef struct _MbEventType {
|
|||||||
eMBMasterEventEnum eEvent; /*!< event itself. */
|
eMBMasterEventEnum eEvent; /*!< event itself. */
|
||||||
uint64_t xTransactionId; /*!< ID of the transaction */
|
uint64_t xTransactionId; /*!< ID of the transaction */
|
||||||
uint64_t xPostTimestamp; /*!< timestamp of event posted */
|
uint64_t xPostTimestamp; /*!< timestamp of event posted */
|
||||||
uint64_t xGetTimestamp; /*!< timestamp of event get */
|
uint64_t xGetTimestamp; /*!< timestamp of event get */
|
||||||
} xMBMasterEventType;
|
} xMBMasterEventType;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -71,12 +71,21 @@
|
|||||||
|
|
||||||
/* ----------------------- Static variables ---------------------------------*/
|
/* ----------------------- Static variables ---------------------------------*/
|
||||||
|
|
||||||
static UCHAR ucMBMasterDestAddress;
|
static UCHAR ucMBMasterDestAddress = 0;
|
||||||
static BOOL xMBRunInMasterMode = FALSE;
|
static BOOL xMBRunInMasterMode = FALSE;
|
||||||
static volatile eMBMasterErrorEventType eMBMasterCurErrorType;
|
static volatile eMBMasterErrorEventType eMBMasterCurErrorType = EV_ERROR_INIT;
|
||||||
static volatile USHORT usMasterSendPDULength;
|
static volatile USHORT usMasterSendPDULength;
|
||||||
static volatile eMBMode eMBMasterCurrentMode;
|
static volatile eMBMode eMBMasterCurrentMode;
|
||||||
|
|
||||||
|
static UCHAR *pucMBSendFrame = NULL;
|
||||||
|
static UCHAR *pucMBRecvFrame = NULL;
|
||||||
|
static UCHAR ucRecvAddress = 0;
|
||||||
|
static UCHAR ucLastFunctionCode = 0;
|
||||||
|
static UCHAR usLastFrameError = 0;
|
||||||
|
static eMBException eLastException = MB_EX_NONE;
|
||||||
|
static uint64_t xLastTransactionId = 0;
|
||||||
|
static uint64_t xCurTransactionId = 0;
|
||||||
|
|
||||||
/*------------------------ Shared variables ---------------------------------*/
|
/*------------------------ Shared variables ---------------------------------*/
|
||||||
|
|
||||||
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
|
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
|
||||||
@@ -182,7 +191,13 @@ eMBMasterTCPInit( USHORT ucTCPPort )
|
|||||||
{
|
{
|
||||||
eStatus = MB_EPORTERR;
|
eStatus = MB_EPORTERR;
|
||||||
}
|
}
|
||||||
|
/* initialize the state values. */
|
||||||
|
ucRecvAddress = 0;
|
||||||
|
ucLastFunctionCode = 0;
|
||||||
|
usLastFrameError = 0;
|
||||||
|
eLastException = MB_EX_NONE;
|
||||||
|
xCurTransactionId = 0;
|
||||||
|
eMBMasterCurErrorType = EV_ERROR_INIT;
|
||||||
}
|
}
|
||||||
return eStatus;
|
return eStatus;
|
||||||
}
|
}
|
||||||
@@ -240,6 +255,13 @@ eMBMasterSerialInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eP
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
eMBState = STATE_DISABLED;
|
eMBState = STATE_DISABLED;
|
||||||
|
/* initialize the state values. */
|
||||||
|
ucRecvAddress = 0;
|
||||||
|
ucLastFunctionCode = 0;
|
||||||
|
usLastFrameError = 0;
|
||||||
|
eLastException = MB_EX_NONE;
|
||||||
|
xCurTransactionId = 0;
|
||||||
|
eMBMasterCurErrorType = EV_ERROR_INIT;
|
||||||
}
|
}
|
||||||
/* initialize the OS resource for modbus master. */
|
/* initialize the OS resource for modbus master. */
|
||||||
vMBMasterOsResInit();
|
vMBMasterOsResInit();
|
||||||
@@ -311,18 +333,14 @@ eMBMasterDisable( void )
|
|||||||
eMBErrorCode
|
eMBErrorCode
|
||||||
eMBMasterPoll( void )
|
eMBMasterPoll( void )
|
||||||
{
|
{
|
||||||
static UCHAR *pucMBSendFrame = NULL;
|
int i;
|
||||||
static UCHAR *pucMBRecvFrame = NULL;
|
int j;
|
||||||
static UCHAR ucRcvAddress;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
static UCHAR ucFunctionCode;
|
|
||||||
static USHORT usLength;
|
|
||||||
static eMBException eException;
|
|
||||||
static uint64_t xCurTransactionId = 0;
|
|
||||||
int i;
|
|
||||||
int j;
|
|
||||||
eMBErrorCode eStatus = MB_ENOERR;
|
|
||||||
xMBMasterEventType xEvent;
|
xMBMasterEventType xEvent;
|
||||||
eMBMasterErrorEventType errorType;
|
eMBMasterErrorEventType errorType;
|
||||||
|
eMBException eException = MB_EX_NONE;
|
||||||
|
UCHAR ucFunctionCode = 0;
|
||||||
|
static USHORT usRecvLength = 0;
|
||||||
|
|
||||||
/* Check if the protocol stack is ready. */
|
/* Check if the protocol stack is ready. */
|
||||||
if( eMBState != STATE_ENABLED ) {
|
if( eMBState != STATE_ENABLED ) {
|
||||||
@@ -352,6 +370,7 @@ eMBMasterPoll( void )
|
|||||||
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":Frame send error = %d", xEvent.xTransactionId, (unsigned)eStatus );
|
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":Frame send error = %d", xEvent.xTransactionId, (unsigned)eStatus );
|
||||||
}
|
}
|
||||||
xCurTransactionId = xEvent.xTransactionId;
|
xCurTransactionId = xEvent.xTransactionId;
|
||||||
|
atomic_store(&(xLastTransactionId), xCurTransactionId);
|
||||||
break;
|
break;
|
||||||
case EV_MASTER_FRAME_SENT:
|
case EV_MASTER_FRAME_SENT:
|
||||||
if (xCurTransactionId == xEvent.xTransactionId) {
|
if (xCurTransactionId == xEvent.xTransactionId) {
|
||||||
@@ -361,15 +380,15 @@ eMBMasterPoll( void )
|
|||||||
break;
|
break;
|
||||||
case EV_MASTER_FRAME_RECEIVED:
|
case EV_MASTER_FRAME_RECEIVED:
|
||||||
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_FRAME_RECEIVED", xEvent.xTransactionId );
|
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_FRAME_RECEIVED", xEvent.xTransactionId );
|
||||||
eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &pucMBRecvFrame, &usLength);
|
eStatus = peMBMasterFrameReceiveCur( &ucRecvAddress, &pucMBRecvFrame, &usRecvLength);
|
||||||
if (xCurTransactionId == xEvent.xTransactionId) {
|
if (xCurTransactionId == xEvent.xTransactionId) {
|
||||||
MB_PORT_CHECK(pucMBSendFrame, MB_EILLSTATE, "Send buffer initialization fail.");
|
MB_PORT_CHECK(pucMBSendFrame, MB_EILLSTATE, "Send buffer initialization fail.");
|
||||||
// Check if the frame is for us. If not ,send an error process event.
|
// Check if the frame is for us. If not ,send an error process event.
|
||||||
if ( ( eStatus == MB_ENOERR ) && ( ( ucRcvAddress == ucMBMasterGetDestAddress() )
|
if ( ( eStatus == MB_ENOERR ) && ( ( ucRecvAddress == ucMBMasterGetDestAddress() )
|
||||||
|| ( ucRcvAddress == MB_TCP_PSEUDO_ADDRESS) ) ) {
|
|| ( ucRecvAddress == MB_TCP_PSEUDO_ADDRESS) ) ) {
|
||||||
if ( ( pucMBRecvFrame[MB_PDU_FUNC_OFF] & ~MB_FUNC_ERROR ) == ( pucMBSendFrame[MB_PDU_FUNC_OFF] ) ) {
|
if ( ( pucMBRecvFrame[MB_PDU_FUNC_OFF] & ~MB_FUNC_ERROR ) == ( pucMBSendFrame[MB_PDU_FUNC_OFF] ) ) {
|
||||||
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ": Packet data received successfully (%u).", xEvent.xTransactionId, (unsigned)eStatus);
|
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ": Packet data received successfully (%u).", xEvent.xTransactionId, (unsigned)eStatus);
|
||||||
ESP_LOG_BUFFER_HEX_LEVEL("POLL receive buffer", (void*)pucMBRecvFrame, (uint16_t)usLength, ESP_LOG_DEBUG);
|
ESP_LOG_BUFFER_HEX_LEVEL("POLL receive buffer", (void*)pucMBRecvFrame, (uint16_t)usRecvLength, ESP_LOG_DEBUG);
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
|
( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE( MB_PORT_TAG, "Drop incorrect frame, receive_func(%u) != send_func(%u)",
|
ESP_LOGE( MB_PORT_TAG, "Drop incorrect frame, receive_func(%u) != send_func(%u)",
|
||||||
@@ -381,7 +400,7 @@ eMBMasterPoll( void )
|
|||||||
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||||
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ": Packet data receive failed (addr=%u)(%u).",
|
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ": Packet data receive failed (addr=%u)(%u).",
|
||||||
xEvent.xTransactionId, (unsigned)ucRcvAddress, (unsigned)eStatus);
|
xEvent.xTransactionId, (unsigned)ucRecvAddress, (unsigned)eStatus);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Ignore the `EV_MASTER_FRAME_RECEIVED` event because the respond timeout occurred
|
// Ignore the `EV_MASTER_FRAME_RECEIVED` event because the respond timeout occurred
|
||||||
@@ -398,6 +417,7 @@ eMBMasterPoll( void )
|
|||||||
MB_PORT_CHECK(pucMBRecvFrame, MB_EILLSTATE, "receive buffer initialization fail.");
|
MB_PORT_CHECK(pucMBRecvFrame, MB_EILLSTATE, "receive buffer initialization fail.");
|
||||||
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_EXECUTE", xEvent.xTransactionId);
|
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_EXECUTE", xEvent.xTransactionId);
|
||||||
ucFunctionCode = pucMBRecvFrame[MB_PDU_FUNC_OFF];
|
ucFunctionCode = pucMBRecvFrame[MB_PDU_FUNC_OFF];
|
||||||
|
atomic_store(&(ucLastFunctionCode), ucFunctionCode);
|
||||||
eException = MB_EX_ILLEGAL_FUNCTION;
|
eException = MB_EX_ILLEGAL_FUNCTION;
|
||||||
/* If receive frame has exception. The receive function code highest bit is 1.*/
|
/* If receive frame has exception. The receive function code highest bit is 1.*/
|
||||||
if (ucFunctionCode & MB_FUNC_ERROR) {
|
if (ucFunctionCode & MB_FUNC_ERROR) {
|
||||||
@@ -415,20 +435,21 @@ eMBMasterPoll( void )
|
|||||||
* the master need execute function for all slave.
|
* the master need execute function for all slave.
|
||||||
*/
|
*/
|
||||||
if ( xMBMasterRequestIsBroadcast() ) {
|
if ( xMBMasterRequestIsBroadcast() ) {
|
||||||
usLength = usMBMasterGetPDUSndLength();
|
USHORT usLength = usMBMasterGetPDUSndLength();
|
||||||
for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
|
for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
|
||||||
{
|
{
|
||||||
vMBMasterSetDestAddress(j);
|
vMBMasterSetDestAddress(j);
|
||||||
eException = xMasterFuncHandlers[i].pxHandler(pucMBRecvFrame, &usLength);
|
eException = xMasterFuncHandlers[i].pxHandler(pucMBRecvFrame, &usLength);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eException = xMasterFuncHandlers[i].pxHandler( pucMBRecvFrame, &usLength );
|
eException = xMasterFuncHandlers[i].pxHandler(pucMBRecvFrame, &usRecvLength);
|
||||||
}
|
}
|
||||||
vMBMasterSetCBRunInMasterMode( FALSE );
|
vMBMasterSetCBRunInMasterMode( FALSE );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
atomic_store(&(eLastException), eException);
|
||||||
/* If master has exception, will send error process event. Otherwise the master is idle.*/
|
/* If master has exception, will send error process event. Otherwise the master is idle.*/
|
||||||
if ( eException != MB_EX_NONE ) {
|
if ( eException != MB_EX_NONE ) {
|
||||||
vMBMasterSetErrorType( EV_ERROR_EXECUTE_FUNCTION );
|
vMBMasterSetErrorType( EV_ERROR_EXECUTE_FUNCTION );
|
||||||
@@ -456,24 +477,28 @@ eMBMasterPoll( void )
|
|||||||
vMBMasterErrorCBRespondTimeout( xEvent.xTransactionId,
|
vMBMasterErrorCBRespondTimeout( xEvent.xTransactionId,
|
||||||
ucMBMasterGetDestAddress( ),
|
ucMBMasterGetDestAddress( ),
|
||||||
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
|
atomic_store(&(usLastFrameError), ( UCHAR )errorType);
|
||||||
break;
|
break;
|
||||||
case EV_ERROR_RECEIVE_DATA:
|
case EV_ERROR_RECEIVE_DATA:
|
||||||
vMBMasterErrorCBReceiveData( xEvent.xTransactionId,
|
vMBMasterErrorCBReceiveData( xEvent.xTransactionId,
|
||||||
ucMBMasterGetDestAddress( ),
|
ucMBMasterGetDestAddress( ),
|
||||||
pucMBRecvFrame, usLength,
|
pucMBRecvFrame, usRecvLength,
|
||||||
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
|
atomic_store(&(usLastFrameError), ( UCHAR )errorType);
|
||||||
break;
|
break;
|
||||||
case EV_ERROR_EXECUTE_FUNCTION:
|
case EV_ERROR_EXECUTE_FUNCTION:
|
||||||
vMBMasterErrorCBExecuteFunction( xEvent.xTransactionId,
|
vMBMasterErrorCBExecuteFunction( xEvent.xTransactionId,
|
||||||
ucMBMasterGetDestAddress( ),
|
ucMBMasterGetDestAddress( ),
|
||||||
pucMBRecvFrame, usLength,
|
pucMBRecvFrame, usRecvLength,
|
||||||
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
|
atomic_store(&(usLastFrameError), ( UCHAR )errorType);
|
||||||
break;
|
break;
|
||||||
case EV_ERROR_OK:
|
case EV_ERROR_OK:
|
||||||
vMBMasterCBRequestSuccess( xEvent.xTransactionId,
|
vMBMasterCBRequestSuccess( xEvent.xTransactionId,
|
||||||
ucMBMasterGetDestAddress( ),
|
ucMBMasterGetDestAddress( ),
|
||||||
pucMBRecvFrame, usLength,
|
pucMBRecvFrame, usRecvLength,
|
||||||
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
|
atomic_store(&(usLastFrameError), ( UCHAR )errorType);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":incorrect error type = %d.", xEvent.xTransactionId, (int)errorType);
|
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":incorrect error type = %d.", xEvent.xTransactionId, (int)errorType);
|
||||||
@@ -583,4 +608,21 @@ eMBMode ucMBMasterGetCommMode(void)
|
|||||||
return eMBMasterCurrentMode;
|
return eMBMasterCurrentMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get current transaction information */
|
||||||
|
BOOL xMBMasterGetLastTransactionInfo( uint64_t *pxTransId, UCHAR *pucDestAddress,
|
||||||
|
UCHAR *pucFunctionCode, UCHAR *pucException,
|
||||||
|
USHORT *pusErrorType )
|
||||||
|
{
|
||||||
|
BOOL xState = (eMBState == STATE_ENABLED);
|
||||||
|
if (xState && pxTransId && pucDestAddress && pucFunctionCode
|
||||||
|
&& pucException && pusErrorType) {
|
||||||
|
*pxTransId = atomic_load(&xLastTransactionId);
|
||||||
|
*pucDestAddress = ucMBMasterGetDestAddress();
|
||||||
|
*pucFunctionCode = atomic_load(&ucLastFunctionCode);
|
||||||
|
*pucException = (UCHAR) atomic_load(&eLastException);
|
||||||
|
*pusErrorType = atomic_load(&usLastFrameError);
|
||||||
|
}
|
||||||
|
return xState;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
|
#endif // MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
|
||||||
|
@@ -215,7 +215,7 @@ BOOL xMBPortSerialWaitEvent(QueueHandle_t xMbUartQueue, uart_event_t* pxEvent, U
|
|||||||
*/
|
*/
|
||||||
MB_ATTR_WEAK
|
MB_ATTR_WEAK
|
||||||
void vMBMasterErrorCBUserHandler( uint64_t xTransId, USHORT usError, UCHAR ucDestAddress, const UCHAR* pucRecvData, USHORT ucRecvLength,
|
void vMBMasterErrorCBUserHandler( uint64_t xTransId, USHORT usError, UCHAR ucDestAddress, const UCHAR* pucRecvData, USHORT ucRecvLength,
|
||||||
const UCHAR* pucSendData, USHORT ucSendLength );
|
const UCHAR* pucSendData, USHORT ucSendLength );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
PR_END_EXTERN_C
|
PR_END_EXTERN_C
|
||||||
|
@@ -392,6 +392,13 @@ static void master_operation_func(void *arg)
|
|||||||
alarm_state = true;
|
alarm_state = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
mb_trans_info_t tinfo = {0};
|
||||||
|
if (mbc_master_get_transaction_info(&tinfo) == ESP_OK) {
|
||||||
|
ESP_LOGI("TRANS_INFO", "Id: %" PRIu64 ", Addr: %x, FC: %x, Exp: %u, Err: %x",
|
||||||
|
(uint64_t)tinfo.trans_id, (int)tinfo.dest_addr,
|
||||||
|
(unsigned)tinfo.func_code, (unsigned)tinfo.exception,
|
||||||
|
(int)tinfo.err_type);
|
||||||
|
}
|
||||||
} else if ((cid >= CID_RELAY_P1) && (cid <= CID_DISCR_P1)) {
|
} else if ((cid >= CID_RELAY_P1) && (cid <= CID_DISCR_P1)) {
|
||||||
if (TEST_VERIFY_VALUES(param_descriptor, (uint8_t *)temp_data_ptr) == ESP_OK) {
|
if (TEST_VERIFY_VALUES(param_descriptor, (uint8_t *)temp_data_ptr) == ESP_OK) {
|
||||||
uint8_t state = *(uint8_t *)temp_data_ptr;
|
uint8_t state = *(uint8_t *)temp_data_ptr;
|
||||||
@@ -483,26 +490,22 @@ static esp_err_t master_init(void)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef UCHAR
|
|
||||||
#define UCHAR uint8_t
|
|
||||||
#define USHORT uint16_t
|
|
||||||
#define MB_PDU_DATA_OFF 1
|
#define MB_PDU_DATA_OFF 1
|
||||||
#endif
|
|
||||||
|
|
||||||
#define EV_ERROR_EXECUTE_FUNCTION 3
|
#define EV_ERROR_EXECUTE_FUNCTION 3
|
||||||
|
|
||||||
void vMBMasterErrorCBUserHandler( uint64_t xTransId, USHORT usError, UCHAR ucDestAddress, const UCHAR* pucRecvData, USHORT ucRecvLength,
|
void vMBMasterErrorCBUserHandler( uint64_t xTransId, uint16_t usError, uint8_t ucDestAddress, const uint8_t *pucRecvData, uint16_t ucRecvLength,
|
||||||
const UCHAR* pucSendData, USHORT ucSendLength )
|
const uint8_t *pucSendData, uint16_t ucSendLength )
|
||||||
{
|
{
|
||||||
ESP_LOGW("USER_ERR_CB", "The transaction error type: %u", usError);
|
ESP_LOGW("USER_ERR_CB", "The transaction %" PRIu64 ", error type: %u", xTransId, usError);
|
||||||
if ((usError == EV_ERROR_EXECUTE_FUNCTION) && pucRecvData && ucRecvLength) {
|
if ((usError == EV_ERROR_EXECUTE_FUNCTION) && pucRecvData && ucRecvLength) {
|
||||||
ESP_LOGW("USER_ERR_CB", "The command is unsupported or an exception on slave happened: %x", (int)pucRecvData[1]);
|
ESP_LOGW("USER_ERR_CB", "The command is unsupported or an exception on slave happened: %x", (int)pucRecvData[MB_PDU_DATA_OFF]);
|
||||||
}
|
}
|
||||||
if (pucRecvData && ucRecvLength) {
|
if (pucRecvData && ucRecvLength) {
|
||||||
ESP_LOG_BUFFER_HEX_LEVEL("Received buffer", (void *)pucRecvData, (USHORT)ucRecvLength, ESP_LOG_WARN);
|
ESP_LOG_BUFFER_HEX_LEVEL("Received buffer", (void *)pucRecvData, (uint16_t)ucRecvLength, ESP_LOG_WARN);
|
||||||
}
|
}
|
||||||
if (pucSendData && ucSendLength) {
|
if (pucSendData && ucSendLength) {
|
||||||
ESP_LOG_BUFFER_HEX_LEVEL("Sent buffer", (void *)pucSendData, (USHORT)ucSendLength, ESP_LOG_WARN);
|
ESP_LOG_BUFFER_HEX_LEVEL("Sent buffer", (void *)pucSendData, (uint16_t)ucSendLength, ESP_LOG_WARN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user