modbus master fix event loop and kconfig

This commit is contained in:
Alex Lisitsyn
2023-06-20 02:38:53 +08:00
parent 2d79f8cc67
commit bf34b5bb8d
22 changed files with 337 additions and 301 deletions
+3 -3
View File
@@ -110,7 +110,7 @@ eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils, LONG
ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF ] = usNCoils >> 8;
ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF + 1] = usNCoils;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
@@ -217,7 +217,7 @@ eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LO
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF ] = usCoilData >> 8;
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usCoilData;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
@@ -327,7 +327,7 @@ eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
*ucMBFrame++ = pucDataBuffer[usRegIndex++];
}
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + ucByteCount );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
+1 -1
View File
@@ -92,7 +92,7 @@ eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT u
ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF ] = usNDiscreteIn >> 8;
ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF + 1] = usNDiscreteIn;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
@@ -122,7 +122,7 @@ eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRe
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF] = usRegData >> 8;
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usRegData ;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
@@ -200,7 +200,7 @@ eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
*ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
}
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + 2*usNRegs );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
@@ -286,7 +286,7 @@ eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRe
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] = usNRegs >> 8;
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
@@ -392,7 +392,7 @@ eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
*ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
}
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READWRITE_SIZE_MIN + 2*usNWriteRegs );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
+1 -1
View File
@@ -93,7 +93,7 @@ eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] = usNRegs >> 8;
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_TRANSMIT | EV_MASTER_TRANS_START );
eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
+1 -1
View File
@@ -103,7 +103,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.*/
}eMBMasterTimerMode;
} eMBMasterTimerMode;
/* ----------------------- Function prototypes ------------------------------*/
/*! \ingroup modbus
+3
View File
@@ -99,6 +99,9 @@ PR_BEGIN_EXTERN_C
#define MB_ASCII_BITS_PER_SYMB ( CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB )
#endif
#define MB_EVENT_QUEUE_SIZE ( CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE )
#define MB_EVENT_QUEUE_TIMEOUT ( pdMS_TO_TICKS( CONFIG_FMB_EVENT_QUEUE_TIMEOUT ) )
/*! \brief The character timeout value for Modbus ASCII.
*
* The character timeout value is not fixed for Modbus ASCII and is therefore
+27 -15
View File
@@ -70,17 +70,18 @@ typedef enum
#if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
typedef enum {
EV_MASTER_NO_EVENT = 0x0000,
EV_MASTER_READY = 0x0001, /*!< Startup finished. */
EV_MASTER_FRAME_RECEIVED = 0x0002, /*!< Frame received. */
EV_MASTER_EXECUTE = 0x0004, /*!< Execute function. */
EV_MASTER_FRAME_SENT = 0x0008, /*!< Frame sent. */
EV_MASTER_FRAME_TRANSMIT = 0x0010, /*!< Frame transmission. */
EV_MASTER_ERROR_PROCESS = 0x0020, /*!< Frame error process. */
EV_MASTER_PROCESS_SUCCESS = 0x0040, /*!< Request process success. */
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. */
} eMBMasterEventType;
EV_MASTER_TRANS_START = 0x0001, /*!< Transaction start flag */
EV_MASTER_READY = 0x0002, /*!< Startup finished. */
EV_MASTER_FRAME_RECEIVED = 0x0004, /*!< Frame received. */
EV_MASTER_EXECUTE = 0x0008, /*!< Execute function. */
EV_MASTER_FRAME_SENT = 0x0010, /*!< Frame sent. */
EV_MASTER_FRAME_TRANSMIT = 0x0020, /*!< Frame transmission. */
EV_MASTER_ERROR_PROCESS = 0x0040, /*!< Frame error process. */
EV_MASTER_PROCESS_SUCCESS = 0x0080, /*!< Request process success. */
EV_MASTER_ERROR_RESPOND_TIMEOUT = 0x0100, /*!< Request respond timeout. */
EV_MASTER_ERROR_RECEIVE_DATA = 0x0200, /*!< Request receive data error. */
EV_MASTER_ERROR_EXECUTE_FUNCTION = 0x0400 /*!< Request execute function error. */
} eMBMasterEventEnum;
typedef enum {
EV_ERROR_INIT, /*!< No error, initial state. */
@@ -89,6 +90,14 @@ typedef enum {
EV_ERROR_EXECUTE_FUNCTION, /*!< Execute function error. */
EV_ERROR_OK /*!< No error, processing completed. */
} eMBMasterErrorEventType;
typedef struct _MbEventType {
eMBMasterEventEnum eEvent; /*!< event itself. */
uint64_t xTransactionId; /*!< ID of the transaction */
uint64_t xPostTimestamp; /*!< timestamp of event posted */
uint64_t xGetTimestamp; /*!< timestamp of event get */
} xMBMasterEventType;
#endif
/*! \ingroup modbus
@@ -115,18 +124,21 @@ BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent );
#if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
BOOL xMBMasterPortEventInit( void );
BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
BOOL xMBMasterPortEventPost( eMBMasterEventEnum eEvent );
BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
BOOL xMBMasterPortEventGet( /*@out@ */ xMBMasterEventType * eEvent );
eMBMasterEventType
xMBMasterPortFsmWaitConfirmation( eMBMasterEventType eEventMask, ULONG ulTimeout);
eMBMasterEventEnum
xMBMasterPortFsmWaitConfirmation( eMBMasterEventEnum eEventMask, ULONG ulTimeout);
void vMBMasterOsResInit( void );
BOOL xMBMasterRunResTake( LONG time );
void vMBMasterRunResRelease( void );
uint64_t xMBMasterPortGetTransactionId( void );
#endif // MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
/* ----------------------- Serial port functions ----------------------------*/
+1 -1
View File
@@ -62,7 +62,7 @@ PR_BEGIN_EXTERN_C
#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 )
#define MB_FUNC_ERROR ( 128u )
/* ----------------------- Type definitions ---------------------------------*/
typedef enum
typedef enum
{
MB_EX_NONE = 0x00,
MB_EX_ILLEGAL_FUNCTION = 0x01,
+123 -122
View File
@@ -36,8 +36,9 @@
*/
/* ----------------------- System includes ----------------------------------*/
#include "stdlib.h"
#include "string.h"
#include <stdatomic.h>
#include <stdlib.h>
#include <string.h>
/* ----------------------- Platform includes --------------------------------*/
#include "port.h"
@@ -316,171 +317,171 @@ eMBMasterPoll( void )
static UCHAR ucFunctionCode;
static USHORT usLength;
static eMBException eException;
static BOOL xTransactionIsActive = FALSE;
static uint64_t xCurTransactionId = 0;
int i;
int j;
eMBErrorCode eStatus = MB_ENOERR;
eMBMasterEventType eEvent;
xMBMasterEventType xEvent;
eMBMasterErrorEventType errorType;
/* Check if the protocol stack is ready. */
if( eMBState != STATE_ENABLED )
{
if( eMBState != STATE_ENABLED ) {
return MB_EILLSTATE;
}
/* Check if there is a event available. If not return control to caller.
* Otherwise we will handle the event. */
if ( xMBMasterPortEventGet( &eEvent ) == TRUE )
{
while( eEvent ) {
if ( xMBMasterPortEventGet( &xEvent ) == TRUE ) {
switch( xEvent.eEvent ) {
// In some cases it is possible that more than one event set
// together (even from one subset mask) than process them consistently
if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_READY ) ) {
ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_READY", __func__);
case EV_MASTER_READY:
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_READY", xEvent.xTransactionId);
vMBMasterSetErrorType( EV_ERROR_INIT );
vMBMasterRunResRelease( );
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_READY );
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT ) ) {
ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_FRAME_TRANSMIT", __func__);
break;
case EV_MASTER_FRAME_TRANSMIT:
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_FRAME_TRANSMIT", xEvent.xTransactionId);
/* Master is busy now. */
vMBMasterGetPDUSndBuf( &ucMBSendFrame );
ESP_LOG_BUFFER_HEX_LEVEL("POLL transmit buffer", (void*)ucMBSendFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBSendFrame, usMBMasterGetPDUSndLength() );
if (eStatus != MB_ENOERR)
{
if (eStatus != MB_ENOERR) {
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
ESP_LOGE( MB_PORT_TAG, "%s:Frame send error. %u", __func__, (unsigned)eStatus );
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":Frame send error = %d", xEvent.xTransactionId, (unsigned)eStatus );
}
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT );
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_SENT ) ) {
ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_FRAME_SENT", __func__ );
ESP_LOG_BUFFER_HEX_LEVEL("POLL sent buffer", (void*)ucMBSendFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
xTransactionIsActive = TRUE;
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_SENT );
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED ) ) {
if (xTransactionIsActive) {
ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_FRAME_RECEIVED", __func__ );
eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBRcvFrame, &usLength);
xCurTransactionId = xEvent.xTransactionId;
break;
case EV_MASTER_FRAME_SENT:
if (xCurTransactionId == xEvent.xTransactionId) {
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_FRAME_SENT", xEvent.xTransactionId );
ESP_LOG_BUFFER_HEX_LEVEL("POLL sent buffer", (void*)ucMBSendFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
}
break;
case EV_MASTER_FRAME_RECEIVED:
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_FRAME_RECEIVED", xEvent.xTransactionId );
eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBRcvFrame, &usLength);
if (xCurTransactionId == xEvent.xTransactionId) {
MB_PORT_CHECK(ucMBSendFrame, MB_EILLSTATE, "Send buffer initialization fail.");
// Check if the frame is for us. If not ,send an error process event.
if ( ( eStatus == MB_ENOERR ) && ( ( ucRcvAddress == ucMBMasterGetDestAddress() )
|| ( ucRcvAddress == MB_TCP_PSEUDO_ADDRESS) ) ) {
if ( ( ucMBRcvFrame[MB_PDU_FUNC_OFF] & ~MB_FUNC_ERROR ) == ( ucMBSendFrame[MB_PDU_FUNC_OFF] ) ) {
ESP_LOGD(MB_PORT_TAG, "%s: Packet data received successfully (%u).", __func__, (unsigned)eStatus);
ESP_LOG_BUFFER_HEX_LEVEL("POLL receive buffer", (void*)ucMBRcvFrame, (unsigned)usLength, ESP_LOG_DEBUG);
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ": Packet data received successfully (%u).", xEvent.xTransactionId, (unsigned)eStatus);
ESP_LOG_BUFFER_HEX_LEVEL("POLL receive buffer", (void*)ucMBRcvFrame, (uint16_t)usLength, ESP_LOG_DEBUG);
( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
} else {
ESP_LOGE( MB_PORT_TAG, "Drop incorrect frame, receive_func(%u) != send_func(%u)",
(UCHAR)ucMBRcvFrame[MB_PDU_FUNC_OFF], (UCHAR)ucMBSendFrame[MB_PDU_FUNC_OFF]);
ucMBRcvFrame[MB_PDU_FUNC_OFF], ucMBSendFrame[MB_PDU_FUNC_OFF]);
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
}
} else {
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
ESP_LOGD( MB_PORT_TAG, "%s: Packet data receive failed (addr=%u)(%u).",
__func__, (unsigned)ucRcvAddress, (unsigned)eStatus);
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ": Packet data receive failed (addr=%u)(%u).",
xEvent.xTransactionId, (unsigned)ucRcvAddress, (unsigned)eStatus);
}
} else {
// Ignore the `EV_MASTER_FRAME_RECEIVED` event because the respond timeout occurred
// and this is likely respond to previous transaction
ESP_LOGE( MB_PORT_TAG, "Drop data received outside of transaction.");
ESP_LOGE( MB_PORT_TAG, "Drop data received outside of transaction (%" PRIu64 ")", xEvent.xTransactionId );
}
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED );
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_EXECUTE ) ) {
MB_PORT_CHECK(ucMBRcvFrame, MB_EILLSTATE, "receive buffer initialization fail.");
ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_EXECUTE", __func__);
ucFunctionCode = ucMBRcvFrame[MB_PDU_FUNC_OFF];
eException = MB_EX_ILLEGAL_FUNCTION;
/* If receive frame has exception. The receive function code highest bit is 1.*/
if (ucFunctionCode & MB_FUNC_ERROR)
{
eException = (eMBException)ucMBRcvFrame[MB_PDU_DATA_OFF];
} else {
for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
{
/* No more function handlers registered. Abort. */
if (xMasterFuncHandlers[i].ucFunctionCode == 0)
break;
case EV_MASTER_EXECUTE:
if (xCurTransactionId == xEvent.xTransactionId) {
MB_PORT_CHECK(ucMBRcvFrame, MB_EILLSTATE, "receive buffer initialization fail.");
ESP_LOGD(MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_EXECUTE", xEvent.xTransactionId);
ucFunctionCode = ucMBRcvFrame[MB_PDU_FUNC_OFF];
eException = MB_EX_ILLEGAL_FUNCTION;
/* If receive frame has exception. The receive function code highest bit is 1.*/
if (ucFunctionCode & MB_FUNC_ERROR) {
eException = (eMBException)ucMBRcvFrame[MB_PDU_DATA_OFF];
} else {
for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
{
break;
}
if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode)
{
vMBMasterSetCBRunInMasterMode(TRUE);
/* If master request is broadcast,
* the master need execute function for all slave.
*/
if ( xMBMasterRequestIsBroadcast() )
{
usLength = usMBMasterGetPDUSndLength();
for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
{
vMBMasterSetDestAddress(j);
eException = xMasterFuncHandlers[i].pxHandler(ucMBRcvFrame, &usLength);
/* No more function handlers registered. Abort. */
if (xMasterFuncHandlers[i].ucFunctionCode == 0) {
break;
}
if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode) {
vMBMasterSetCBRunInMasterMode(TRUE);
/* If master request is broadcast,
* the master need execute function for all slave.
*/
if ( xMBMasterRequestIsBroadcast() ) {
usLength = usMBMasterGetPDUSndLength();
for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
{
vMBMasterSetDestAddress(j);
eException = xMasterFuncHandlers[i].pxHandler(ucMBRcvFrame, &usLength);
}
} else {
eException = xMasterFuncHandlers[i].pxHandler( ucMBRcvFrame, &usLength );
}
vMBMasterSetCBRunInMasterMode( FALSE );
break;
}
else
{
eException = xMasterFuncHandlers[i].pxHandler( ucMBRcvFrame, &usLength );
}
vMBMasterSetCBRunInMasterMode( FALSE );
break;
}
}
}
/* If master has exception, will send error process event. Otherwise the master is idle.*/
if ( eException != MB_EX_NONE )
{
vMBMasterSetErrorType( EV_ERROR_EXECUTE_FUNCTION );
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
}
else
{
if ( eMBMasterGetErrorType( ) == EV_ERROR_INIT ) {
vMBMasterSetErrorType(EV_ERROR_OK);
ESP_LOGD( MB_PORT_TAG, "%s: set event EV_ERROR_OK", __func__ );
/* If master has exception, will send error process event. Otherwise the master is idle.*/
if ( eException != MB_EX_NONE ) {
vMBMasterSetErrorType( EV_ERROR_EXECUTE_FUNCTION );
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
} else {
if ( eMBMasterGetErrorType( ) == EV_ERROR_INIT ) {
vMBMasterSetErrorType(EV_ERROR_OK);
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":set event EV_ERROR_OK", xEvent.xTransactionId );
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
}
}
} else {
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_EXECUTE is expired", xEvent.xTransactionId );
}
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_EXECUTE );
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_ERROR_PROCESS ) ) {
ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_ERROR_PROCESS", __func__ );
/* Execute specified error process callback function. */
errorType = eMBMasterGetErrorType( );
vMBMasterGetPDUSndBuf( &ucMBSendFrame );
switch ( errorType )
{
case EV_ERROR_RESPOND_TIMEOUT:
vMBMasterErrorCBRespondTimeout( ucMBMasterGetDestAddress( ),
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
break;
case EV_ERROR_RECEIVE_DATA:
vMBMasterErrorCBReceiveData( ucMBMasterGetDestAddress( ),
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
break;
case EV_ERROR_EXECUTE_FUNCTION:
vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
break;
case EV_ERROR_OK:
vMBMasterCBRequestSuccess( );
break;
default:
ESP_LOGE( MB_PORT_TAG, "%s: incorrect error type = %u.", __func__, (unsigned)errorType);
break;
break;
case EV_MASTER_ERROR_PROCESS:
if (xCurTransactionId == xEvent.xTransactionId) {
ESP_LOGD( MB_PORT_TAG, "%" PRIu64 ":EV_MASTER_ERROR_PROCESS", xEvent.xTransactionId);
/* Execute specified error process callback function. */
errorType = eMBMasterGetErrorType( );
vMBMasterGetPDUSndBuf( &ucMBSendFrame );
switch ( errorType )
{
case EV_ERROR_RESPOND_TIMEOUT:
vMBMasterErrorCBRespondTimeout( ucMBMasterGetDestAddress( ),
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
break;
case EV_ERROR_RECEIVE_DATA:
vMBMasterErrorCBReceiveData( ucMBMasterGetDestAddress( ),
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
break;
case EV_ERROR_EXECUTE_FUNCTION:
vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
ucMBSendFrame, usMBMasterGetPDUSndLength( ) );
break;
case EV_ERROR_OK:
vMBMasterCBRequestSuccess( );
break;
default:
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":incorrect error type = %d.", xEvent.xTransactionId, (int)errorType);
break;
}
}
vMBMasterPortTimersDisable( );
uint64_t xProcTime = xCurTransactionId ? ( xEvent.xPostTimestamp - xCurTransactionId ) : 0;
ESP_LOGD( MB_PORT_TAG, "Transaction (%" PRIu64 "), processing time(us) = %" PRId64, xCurTransactionId, xProcTime );
xCurTransactionId = 0;
vMBMasterSetErrorType( EV_ERROR_INIT );
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_ERROR_PROCESS );
vMBMasterRunResRelease( );
}
break;
default:
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ":Unexpected event triggered 0x%02x.", xEvent.xTransactionId, (int)xEvent.eEvent );
break;
}
} else {
// Something went wrong and task unblocked but there are no any correct events set
ESP_LOGE( MB_PORT_TAG, "%s: Unexpected event triggered 0x%02x.", __func__, (int)eEvent );
ESP_LOGE( MB_PORT_TAG, "%" PRIu64 ": Unexpected event triggered 0x%02x.", xEvent.xTransactionId, (int)xEvent.eEvent );
eStatus = MB_EILLSTATE;
}
return eStatus;
@@ -489,37 +490,37 @@ eMBMasterPoll( void )
// Get whether the Modbus Master is run in master mode.
BOOL xMBMasterGetCBRunInMasterMode( void )
{
return xMBRunInMasterMode;
return atomic_load(&xMBRunInMasterMode);
}
// Set whether the Modbus Master is run in master mode.
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
{
xMBRunInMasterMode = IsMasterMode;
atomic_store(&(xMBRunInMasterMode), IsMasterMode);
}
// Get Modbus Master send destination address.
UCHAR ucMBMasterGetDestAddress( void )
{
return ucMBMasterDestAddress;
return atomic_load(&ucMBMasterDestAddress);
}
// Set Modbus Master send destination address.
void vMBMasterSetDestAddress( UCHAR Address )
{
ucMBMasterDestAddress = Address;
atomic_store(&(ucMBMasterDestAddress), Address);
}
// Get Modbus Master current error event type.
eMBMasterErrorEventType inline eMBMasterGetErrorType( void )
{
return eMBMasterCurErrorType;
return atomic_load(&eMBMasterCurErrorType);
}
// Set Modbus Master current error event type.
void IRAM_ATTR vMBMasterSetErrorType( eMBMasterErrorEventType errorType )
{
eMBMasterCurErrorType = errorType;
atomic_store(&(eMBMasterCurErrorType), errorType);
}
/* Get Modbus Master send PDU's buffer address pointer.*/
@@ -531,25 +532,25 @@ void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
/* Set Modbus Master send PDU's buffer length.*/
void vMBMasterSetPDUSndLength( USHORT SendPDULength )
{
usMasterSendPDULength = SendPDULength;
atomic_store(&(usMasterSendPDULength), SendPDULength);
}
/* Get Modbus Master send PDU's buffer length.*/
USHORT usMBMasterGetPDUSndLength( void )
{
return usMasterSendPDULength;
return atomic_load(&usMasterSendPDULength);
}
/* Set Modbus Master current timer mode.*/
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
{
eMasterCurTimerMode = eMBTimerMode;
atomic_store(&(eMasterCurTimerMode), eMBTimerMode);
}
/* Get Modbus Master current timer mode.*/
eMBMasterTimerMode MB_PORT_ISR_ATTR xMBMasterGetCurTimerMode( void )
{
return eMasterCurTimerMode;
return atomic_load(&eMasterCurTimerMode);
}
/* The master request is broadcast? */
@@ -561,7 +562,7 @@ BOOL MB_PORT_ISR_ATTR xMBMasterRequestIsBroadcast( void )
/* The master request is broadcast? */
void vMBMasterRequestSetType( BOOL xIsBroadcast )
{
xFrameIsBroadcast = xIsBroadcast;
atomic_store(&(xFrameIsBroadcast), xIsBroadcast);
}
// Get Modbus Master communication mode.
+6 -2
View File
@@ -252,7 +252,9 @@ xMBMasterRTUReceiveFSM( void )
BOOL xStatus = FALSE;
UCHAR ucByte;
assert(( eSndState == STATE_M_TX_IDLE ) || ( eSndState == STATE_M_TX_XFWR ));
if ( ( eSndState != STATE_M_TX_IDLE ) && ( eSndState != STATE_M_TX_XFWR ) ) {
return FALSE;
}
/* Always read the character. */
xStatus = xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
@@ -328,7 +330,9 @@ xMBMasterRTUTransmitFSM( void )
BOOL xNeedPoll = TRUE;
BOOL xFrameIsBroadcast = FALSE;
assert( eRcvState == STATE_M_RX_IDLE );
if ( eRcvState != STATE_M_RX_IDLE ) {
return FALSE;
}
switch ( eSndState )
{