forked from espressif/esp-modbus
fix atomic access to state variables
This commit is contained in:
@ -83,7 +83,6 @@ typedef enum
|
|||||||
/* These Modbus values are shared in ASCII mode*/
|
/* These Modbus values are shared in ASCII mode*/
|
||||||
extern volatile UCHAR ucMasterRcvBuf[];
|
extern volatile UCHAR ucMasterRcvBuf[];
|
||||||
extern volatile UCHAR ucMasterSndBuf[];
|
extern volatile UCHAR ucMasterSndBuf[];
|
||||||
extern volatile eMBMasterTimerMode eMasterCurTimerMode;
|
|
||||||
|
|
||||||
/* ----------------------- Static functions ---------------------------------*/
|
/* ----------------------- Static functions ---------------------------------*/
|
||||||
static UCHAR prvucMBCHAR2BIN( UCHAR ucCharacter );
|
static UCHAR prvucMBCHAR2BIN( UCHAR ucCharacter );
|
||||||
|
@ -95,6 +95,19 @@ typedef enum
|
|||||||
MB_MRE_EXE_FUN /*!< execute function error. */
|
MB_MRE_EXE_FUN /*!< execute function error. */
|
||||||
} eMBMasterReqErrCode;
|
} eMBMasterReqErrCode;
|
||||||
|
|
||||||
|
|
||||||
|
/*! \ingroup modbus
|
||||||
|
* \brief Transaction information structure.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint64_t xTransId;
|
||||||
|
UCHAR ucDestAddr;
|
||||||
|
UCHAR ucFuncCode;
|
||||||
|
eMBException eException;
|
||||||
|
UCHAR ucFrameError;
|
||||||
|
} TransactionInfo_t;
|
||||||
|
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
* \brief TimerMode is Master 3 kind of Timer modes.
|
* \brief TimerMode is Master 3 kind of Timer modes.
|
||||||
*/
|
*/
|
||||||
@ -107,9 +120,7 @@ typedef enum
|
|||||||
|
|
||||||
extern _lock_t xMBMLock; // Modbus lock object
|
extern _lock_t xMBMLock; // Modbus lock object
|
||||||
|
|
||||||
#define MB_ATOMIC_SECTION() CRITICAL_SECTION(xMBMLock)
|
#define MB_ATOMIC_SECTION CRITICAL_SECTION(xMBMLock)
|
||||||
#define MB_ATOMIC_STORE(PTR, DES) CRITICAL_STORE(xMBMLock, PTR, DES)
|
|
||||||
#define MB_ATOMIC_LOAD(PTR) CRITICAL_LOAD(xMBMLock, PTR)
|
|
||||||
|
|
||||||
/* ----------------------- Function prototypes ------------------------------*/
|
/* ----------------------- Function prototypes ------------------------------*/
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
/* ----------------------- System includes ----------------------------------*/
|
/* ----------------------- System includes ----------------------------------*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
/* ----------------------- Platform includes --------------------------------*/
|
/* ----------------------- Platform includes --------------------------------*/
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
@ -67,32 +68,29 @@
|
|||||||
#define MB_PORT_HAS_CLOSE 1
|
#define MB_PORT_HAS_CLOSE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ----------------------- Static variables ---------------------------------*/
|
/*------------------------ Shared variables ---------------------------------*/
|
||||||
|
|
||||||
static volatile eMBMasterErrorEventType eMBMasterCurErrorType = EV_ERROR_INIT;
|
|
||||||
static volatile USHORT usMasterSendPDULength;
|
|
||||||
static volatile eMBMode eMBMasterCurrentMode;
|
|
||||||
static uint64_t xCurTransactionId = 0;
|
|
||||||
|
|
||||||
_lock_t xMBMLock; // base modbus object lock
|
_lock_t xMBMLock; // base modbus object lock
|
||||||
|
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
|
||||||
|
volatile UCHAR ucMasterRcvBuf[MB_SERIAL_BUF_SIZE];
|
||||||
|
|
||||||
|
static _Atomic USHORT usMasterSendPDULength = 0;
|
||||||
|
static _Atomic eMBMasterErrorEventType eMBMasterCurErrorType = EV_ERROR_INIT;
|
||||||
|
static _Atomic BOOL xMBRunInMasterMode = FALSE;
|
||||||
|
static _Atomic UCHAR ucMBMasterDestAddress = 0;
|
||||||
|
static _Atomic BOOL xFrameIsBroadcast = FALSE;
|
||||||
|
|
||||||
|
static _Atomic eMBMasterTimerMode eMasterCurTimerMode;
|
||||||
|
|
||||||
|
/* ----------------------- Static variables ---------------------------------*/
|
||||||
|
static uint64_t xCurTransactionId = 0;
|
||||||
static UCHAR *pucMBSendFrame = NULL;
|
static UCHAR *pucMBSendFrame = NULL;
|
||||||
static UCHAR *pucMBRecvFrame = NULL;
|
static UCHAR *pucMBRecvFrame = NULL;
|
||||||
static UCHAR ucRecvAddress = 0;
|
static UCHAR ucRecvAddress = 0;
|
||||||
|
static eMBMode eMBMasterCurrentMode;
|
||||||
|
|
||||||
static BOOL xMBRunInMasterMode =FALSE;
|
/* The transaction information structure which keep last processing state */
|
||||||
static UCHAR ucMBMasterDestAddress = 0;
|
static TransactionInfo_t xTransactionInfo = {0};
|
||||||
static UCHAR ucLastFunctionCode = 0;
|
|
||||||
static UCHAR usLastFrameError = 0;
|
|
||||||
static eMBException eLastException = MB_EX_NONE;
|
|
||||||
static uint64_t xLastTransactionId = 0;
|
|
||||||
|
|
||||||
/*------------------------ Shared variables ---------------------------------*/
|
|
||||||
|
|
||||||
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
|
|
||||||
volatile UCHAR ucMasterRcvBuf[MB_SERIAL_BUF_SIZE];
|
|
||||||
volatile eMBMasterTimerMode eMasterCurTimerMode;
|
|
||||||
volatile BOOL xFrameIsBroadcast = FALSE;
|
|
||||||
|
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
@ -182,9 +180,21 @@ eMBMasterTCPInit( USHORT ucTCPPort )
|
|||||||
peMBMasterFrameSendCur = eMBMasterTCPSend;
|
peMBMasterFrameSendCur = eMBMasterTCPSend;
|
||||||
pxMBMasterPortCBTimerExpired = xMBMasterTCPTimerExpired;
|
pxMBMasterPortCBTimerExpired = xMBMasterTCPTimerExpired;
|
||||||
pvMBMasterFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBMasterTCPPortClose : NULL;
|
pvMBMasterFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBMasterTCPPortClose : NULL;
|
||||||
ucMBMasterDestAddress = MB_TCP_PSEUDO_ADDRESS;
|
|
||||||
eMBMasterCurrentMode = MB_TCP;
|
eMBMasterCurrentMode = MB_TCP;
|
||||||
eMBState = STATE_DISABLED;
|
eMBState = STATE_DISABLED;
|
||||||
|
ucRecvAddress = MB_TCP_PSEUDO_ADDRESS;
|
||||||
|
xCurTransactionId = 0;
|
||||||
|
xTransactionInfo.xTransId = 0;
|
||||||
|
xTransactionInfo.ucDestAddr = 0;
|
||||||
|
xTransactionInfo.ucFuncCode = 0;
|
||||||
|
xTransactionInfo.eException = MB_EX_NONE;
|
||||||
|
xTransactionInfo.ucFrameError = 0;
|
||||||
|
|
||||||
|
/* initialize the state values. */
|
||||||
|
atomic_init(&usMasterSendPDULength, 0);
|
||||||
|
atomic_init(&eMBMasterCurErrorType, EV_ERROR_INIT);
|
||||||
|
atomic_init(&xMBRunInMasterMode, FALSE);
|
||||||
|
atomic_init(&ucMBMasterDestAddress, MB_TCP_PSEUDO_ADDRESS);
|
||||||
|
|
||||||
// initialize the OS resource for modbus master.
|
// initialize the OS resource for modbus master.
|
||||||
vMBMasterOsResInit();
|
vMBMasterOsResInit();
|
||||||
@ -192,13 +202,7 @@ eMBMasterTCPInit( USHORT ucTCPPort )
|
|||||||
{
|
{
|
||||||
eStatus = MB_EPORTERR;
|
eStatus = MB_EPORTERR;
|
||||||
}
|
}
|
||||||
/* initialize the state values. */
|
|
||||||
ucRecvAddress = MB_TCP_PSEUDO_ADDRESS;
|
|
||||||
ucLastFunctionCode = 0;
|
|
||||||
usLastFrameError = 0;
|
|
||||||
eLastException = MB_EX_NONE;
|
|
||||||
xCurTransactionId = 0;
|
|
||||||
eMBMasterCurErrorType = EV_ERROR_INIT;
|
|
||||||
}
|
}
|
||||||
return eStatus;
|
return eStatus;
|
||||||
}
|
}
|
||||||
@ -256,13 +260,19 @@ eMBMasterSerialInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eP
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
eMBState = STATE_DISABLED;
|
eMBState = STATE_DISABLED;
|
||||||
/* initialize the state values. */
|
ucRecvAddress = 0;
|
||||||
ucRecvAddress = MB_TCP_PSEUDO_ADDRESS;
|
|
||||||
ucLastFunctionCode = 0;
|
|
||||||
usLastFrameError = 0;
|
|
||||||
eLastException = MB_EX_NONE;
|
|
||||||
xCurTransactionId = 0;
|
xCurTransactionId = 0;
|
||||||
eMBMasterCurErrorType = EV_ERROR_INIT;
|
xTransactionInfo.xTransId = 0;
|
||||||
|
xTransactionInfo.ucDestAddr = 0;
|
||||||
|
xTransactionInfo.ucFuncCode = 0;
|
||||||
|
xTransactionInfo.eException = MB_EX_NONE;
|
||||||
|
xTransactionInfo.ucFrameError = 0;
|
||||||
|
|
||||||
|
/* initialize the state values. */
|
||||||
|
atomic_init(&usMasterSendPDULength, 0);
|
||||||
|
atomic_init(&eMBMasterCurErrorType, EV_ERROR_INIT);
|
||||||
|
atomic_init(&xMBRunInMasterMode, FALSE);
|
||||||
|
atomic_init(&ucMBMasterDestAddress, MB_TCP_PSEUDO_ADDRESS);
|
||||||
}
|
}
|
||||||
/* initialize the OS resource for modbus master. */
|
/* initialize the OS resource for modbus master. */
|
||||||
vMBMasterOsResInit();
|
vMBMasterOsResInit();
|
||||||
@ -338,9 +348,9 @@ eMBMasterPoll( void )
|
|||||||
int j;
|
int j;
|
||||||
eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
xMBMasterEventType xEvent;
|
xMBMasterEventType xEvent;
|
||||||
eMBMasterErrorEventType errorType;
|
eMBMasterErrorEventType errorType = EV_ERROR_INIT;
|
||||||
eMBException eException = MB_EX_NONE;
|
static eMBException eException = MB_EX_NONE;
|
||||||
UCHAR ucFunctionCode = 0;
|
static UCHAR ucFunctionCode = 0;
|
||||||
static USHORT usRecvLength = 0;
|
static USHORT usRecvLength = 0;
|
||||||
|
|
||||||
/* Check if the protocol stack is ready. */
|
/* Check if the protocol stack is ready. */
|
||||||
@ -371,7 +381,6 @@ 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;
|
||||||
MB_ATOMIC_STORE(&(xLastTransactionId), xCurTransactionId);
|
|
||||||
break;
|
break;
|
||||||
case EV_MASTER_FRAME_SENT:
|
case EV_MASTER_FRAME_SENT:
|
||||||
if (xCurTransactionId == xEvent.xTransactionId) {
|
if (xCurTransactionId == xEvent.xTransactionId) {
|
||||||
@ -418,7 +427,6 @@ 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];
|
||||||
MB_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) {
|
||||||
@ -450,7 +458,6 @@ eMBMasterPoll( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MB_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 );
|
||||||
@ -478,28 +485,24 @@ eMBMasterPoll( void )
|
|||||||
vMBMasterErrorCBRespondTimeout( xEvent.xTransactionId,
|
vMBMasterErrorCBRespondTimeout( xEvent.xTransactionId,
|
||||||
ucMBMasterGetDestAddress( ),
|
ucMBMasterGetDestAddress( ),
|
||||||
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
MB_ATOMIC_STORE(&(usLastFrameError), errorType);
|
|
||||||
break;
|
break;
|
||||||
case EV_ERROR_RECEIVE_DATA:
|
case EV_ERROR_RECEIVE_DATA:
|
||||||
vMBMasterErrorCBReceiveData( xEvent.xTransactionId,
|
vMBMasterErrorCBReceiveData( xEvent.xTransactionId,
|
||||||
ucMBMasterGetDestAddress( ),
|
ucMBMasterGetDestAddress( ),
|
||||||
pucMBRecvFrame, usRecvLength,
|
pucMBRecvFrame, usRecvLength,
|
||||||
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
MB_ATOMIC_STORE(&(usLastFrameError), errorType);
|
|
||||||
break;
|
break;
|
||||||
case EV_ERROR_EXECUTE_FUNCTION:
|
case EV_ERROR_EXECUTE_FUNCTION:
|
||||||
vMBMasterErrorCBExecuteFunction( xEvent.xTransactionId,
|
vMBMasterErrorCBExecuteFunction( xEvent.xTransactionId,
|
||||||
ucMBMasterGetDestAddress( ),
|
ucMBMasterGetDestAddress( ),
|
||||||
pucMBRecvFrame, usRecvLength,
|
pucMBRecvFrame, usRecvLength,
|
||||||
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
MB_ATOMIC_STORE(&(usLastFrameError), errorType);
|
|
||||||
break;
|
break;
|
||||||
case EV_ERROR_OK:
|
case EV_ERROR_OK:
|
||||||
vMBMasterCBRequestSuccess( xEvent.xTransactionId,
|
vMBMasterCBRequestSuccess( xEvent.xTransactionId,
|
||||||
ucMBMasterGetDestAddress( ),
|
ucMBMasterGetDestAddress( ),
|
||||||
pucMBRecvFrame, usRecvLength,
|
pucMBRecvFrame, usRecvLength,
|
||||||
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
pucMBSendFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
MB_ATOMIC_STORE(&(usLastFrameError), 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);
|
||||||
@ -509,6 +512,13 @@ eMBMasterPoll( void )
|
|||||||
vMBMasterPortTimersDisable( );
|
vMBMasterPortTimersDisable( );
|
||||||
uint64_t xProcTime = xCurTransactionId ? ( xEvent.xPostTimestamp - xCurTransactionId ) : 0;
|
uint64_t xProcTime = xCurTransactionId ? ( xEvent.xPostTimestamp - xCurTransactionId ) : 0;
|
||||||
ESP_LOGD( MB_PORT_TAG, "Transaction (%" PRIu64 "), processing time(us) = %" PRId64, xCurTransactionId, xProcTime );
|
ESP_LOGD( MB_PORT_TAG, "Transaction (%" PRIu64 "), processing time(us) = %" PRId64, xCurTransactionId, xProcTime );
|
||||||
|
MB_ATOMIC_SECTION {
|
||||||
|
xTransactionInfo.xTransId = xCurTransactionId;
|
||||||
|
xTransactionInfo.ucDestAddr = atomic_load(&ucMBMasterDestAddress);
|
||||||
|
xTransactionInfo.ucFuncCode = ucFunctionCode;
|
||||||
|
xTransactionInfo.eException = eException;
|
||||||
|
xTransactionInfo.ucFrameError = errorType;
|
||||||
|
}
|
||||||
xCurTransactionId = 0;
|
xCurTransactionId = 0;
|
||||||
vMBMasterSetErrorType( EV_ERROR_INIT );
|
vMBMasterSetErrorType( EV_ERROR_INIT );
|
||||||
vMBMasterRunResRelease( );
|
vMBMasterRunResRelease( );
|
||||||
@ -528,37 +538,37 @@ eMBMasterPoll( void )
|
|||||||
// Get whether the Modbus Master is run in master mode.
|
// Get whether the Modbus Master is run in master mode.
|
||||||
BOOL xMBMasterGetCBRunInMasterMode( void )
|
BOOL xMBMasterGetCBRunInMasterMode( void )
|
||||||
{
|
{
|
||||||
return MB_ATOMIC_LOAD( &xMBRunInMasterMode);
|
return atomic_load(&xMBRunInMasterMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set whether the Modbus Master is run in master mode.
|
// Set whether the Modbus Master is run in master mode.
|
||||||
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
|
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
|
||||||
{
|
{
|
||||||
MB_ATOMIC_STORE(&(xMBRunInMasterMode), IsMasterMode);
|
atomic_store(&xMBRunInMasterMode, IsMasterMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Modbus Master send destination address.
|
// Get Modbus Master send destination address.
|
||||||
UCHAR ucMBMasterGetDestAddress( void )
|
UCHAR ucMBMasterGetDestAddress( void )
|
||||||
{
|
{
|
||||||
return MB_ATOMIC_LOAD( &ucMBMasterDestAddress);
|
return atomic_load(&ucMBMasterDestAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Modbus Master send destination address.
|
// Set Modbus Master send destination address.
|
||||||
void vMBMasterSetDestAddress( UCHAR Address )
|
void vMBMasterSetDestAddress( UCHAR Address )
|
||||||
{
|
{
|
||||||
MB_ATOMIC_STORE(&(ucMBMasterDestAddress), Address);
|
atomic_store(&ucMBMasterDestAddress, Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Modbus Master current error event type.
|
// Get Modbus Master current error event type.
|
||||||
eMBMasterErrorEventType inline eMBMasterGetErrorType( void )
|
eMBMasterErrorEventType inline eMBMasterGetErrorType( void )
|
||||||
{
|
{
|
||||||
return MB_ATOMIC_LOAD(&eMBMasterCurErrorType);
|
return atomic_load(&eMBMasterCurErrorType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Modbus Master current error event type.
|
// Set Modbus Master current error event type.
|
||||||
void IRAM_ATTR vMBMasterSetErrorType( eMBMasterErrorEventType errorType )
|
void IRAM_ATTR vMBMasterSetErrorType( eMBMasterErrorEventType errorType )
|
||||||
{
|
{
|
||||||
MB_ATOMIC_STORE(&(eMBMasterCurErrorType), errorType);
|
atomic_store(&eMBMasterCurErrorType, errorType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get Modbus Master send PDU's buffer address pointer.*/
|
/* Get Modbus Master send PDU's buffer address pointer.*/
|
||||||
@ -570,37 +580,37 @@ void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
|
|||||||
/* Set Modbus Master send PDU's buffer length.*/
|
/* Set Modbus Master send PDU's buffer length.*/
|
||||||
void vMBMasterSetPDUSndLength( USHORT SendPDULength )
|
void vMBMasterSetPDUSndLength( USHORT SendPDULength )
|
||||||
{
|
{
|
||||||
MB_ATOMIC_STORE(&(usMasterSendPDULength), SendPDULength);
|
atomic_store(&usMasterSendPDULength, SendPDULength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get Modbus Master send PDU's buffer length.*/
|
/* Get Modbus Master send PDU's buffer length.*/
|
||||||
USHORT usMBMasterGetPDUSndLength( void )
|
USHORT usMBMasterGetPDUSndLength( void )
|
||||||
{
|
{
|
||||||
return MB_ATOMIC_LOAD(&usMasterSendPDULength);
|
return atomic_load(&usMasterSendPDULength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Modbus Master current timer mode.*/
|
/* Set Modbus Master current timer mode.*/
|
||||||
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
|
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
|
||||||
{
|
{
|
||||||
MB_ATOMIC_STORE(&(eMasterCurTimerMode), eMBTimerMode);
|
atomic_store(&eMasterCurTimerMode, eMBTimerMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get Modbus Master current timer mode.*/
|
/* Get Modbus Master current timer mode.*/
|
||||||
eMBMasterTimerMode MB_PORT_ISR_ATTR xMBMasterGetCurTimerMode( void )
|
eMBMasterTimerMode MB_PORT_ISR_ATTR xMBMasterGetCurTimerMode( void )
|
||||||
{
|
{
|
||||||
return MB_ATOMIC_LOAD(&eMasterCurTimerMode);
|
return atomic_load(&eMasterCurTimerMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The master request is broadcast? */
|
/* The master request is broadcast? */
|
||||||
BOOL MB_PORT_ISR_ATTR xMBMasterRequestIsBroadcast( void )
|
BOOL MB_PORT_ISR_ATTR xMBMasterRequestIsBroadcast( void )
|
||||||
{
|
{
|
||||||
return MB_ATOMIC_LOAD( &xFrameIsBroadcast);
|
return atomic_load(&xFrameIsBroadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The master request is broadcast? */
|
/* The master request is broadcast? */
|
||||||
void vMBMasterRequestSetType( BOOL xIsBroadcast )
|
void vMBMasterRequestSetType( BOOL xIsBroadcast )
|
||||||
{
|
{
|
||||||
MB_ATOMIC_STORE(&(xFrameIsBroadcast), xIsBroadcast);
|
atomic_store(&xFrameIsBroadcast, xIsBroadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Modbus Master communication mode.
|
// Get Modbus Master communication mode.
|
||||||
@ -616,13 +626,13 @@ BOOL xMBMasterGetLastTransactionInfo( uint64_t *pxTransId, UCHAR *pucDestAddress
|
|||||||
{
|
{
|
||||||
BOOL xState = (eMBState == STATE_ENABLED);
|
BOOL xState = (eMBState == STATE_ENABLED);
|
||||||
if (xState && pxTransId && pucDestAddress && pucFunctionCode
|
if (xState && pxTransId && pucDestAddress && pucFunctionCode
|
||||||
&& pucException && pusErrorType) {
|
&& pucException && pusErrorType) {
|
||||||
MB_ATOMIC_SECTION() {
|
MB_ATOMIC_SECTION {
|
||||||
*pxTransId = xLastTransactionId;
|
*pxTransId = xTransactionInfo.xTransId;
|
||||||
*pucDestAddress = ucMBMasterDestAddress;
|
*pucDestAddress = xTransactionInfo.ucDestAddr;
|
||||||
*pucFunctionCode = ucLastFunctionCode;
|
*pucFunctionCode = xTransactionInfo.ucFuncCode;
|
||||||
*pucException = eLastException;
|
*pucException = xTransactionInfo.eException;
|
||||||
*pusErrorType = usLastFrameError;
|
*pusErrorType = xTransactionInfo.ucFrameError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return xState;
|
return xState;
|
||||||
|
@ -154,28 +154,6 @@ void unlock_obj(_lock_t *plock);
|
|||||||
|
|
||||||
#define CRITICAL_SECTION(lock) for (int st = lock_obj((_lock_t *)&lock); (st > 0); unlock_obj((_lock_t *)&lock), st = -1)
|
#define CRITICAL_SECTION(lock) for (int st = lock_obj((_lock_t *)&lock); (st > 0); unlock_obj((_lock_t *)&lock), st = -1)
|
||||||
|
|
||||||
#define CRITICAL_STORE(LOCK, PTR, DES) \
|
|
||||||
__extension__ \
|
|
||||||
({ \
|
|
||||||
__auto_type __atomic_ptr = (PTR); \
|
|
||||||
__typeof__ ((void)0, *__atomic_ptr) __atomic_tmp = (DES); \
|
|
||||||
lock_obj((_lock_t *)&LOCK); \
|
|
||||||
*__atomic_ptr = __atomic_tmp; \
|
|
||||||
unlock_obj((_lock_t *)&LOCK); \
|
|
||||||
(__atomic_tmp); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define CRITICAL_LOAD(LOCK, PTR) \
|
|
||||||
__extension__ \
|
|
||||||
({ \
|
|
||||||
__auto_type __atomic_ptr = (PTR); \
|
|
||||||
__typeof__ ((void)0, *__atomic_ptr) __atomic_tmp; \
|
|
||||||
lock_obj((_lock_t *)&LOCK); \
|
|
||||||
__atomic_tmp = (*__atomic_ptr); \
|
|
||||||
unlock_obj((_lock_t *)&LOCK); \
|
|
||||||
(__atomic_tmp); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
PR_BEGIN_EXTERN_C
|
PR_BEGIN_EXTERN_C
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------- Modbus includes ----------------------------------*/
|
/* ----------------------- Modbus includes ----------------------------------*/
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
@ -64,7 +65,7 @@ static EventGroupHandle_t xEventGroupMasterHdl;
|
|||||||
static EventGroupHandle_t xEventGroupMasterConfirmHdl;
|
static EventGroupHandle_t xEventGroupMasterConfirmHdl;
|
||||||
static QueueHandle_t xQueueMasterHdl;
|
static QueueHandle_t xQueueMasterHdl;
|
||||||
|
|
||||||
static uint64_t xTransactionID = 0;
|
static _Atomic uint64_t xTransactionID = 0;
|
||||||
|
|
||||||
/* ----------------------- Start implementation -----------------------------*/
|
/* ----------------------- Start implementation -----------------------------*/
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ xMBMasterPortEventInit( void )
|
|||||||
xQueueMasterHdl = xQueueCreate(MB_EVENT_QUEUE_SIZE, sizeof(xMBMasterEventType));
|
xQueueMasterHdl = xQueueCreate(MB_EVENT_QUEUE_SIZE, sizeof(xMBMasterEventType));
|
||||||
MB_PORT_CHECK(xQueueMasterHdl, FALSE, "mb stack event group creation error.");
|
MB_PORT_CHECK(xQueueMasterHdl, FALSE, "mb stack event group creation error.");
|
||||||
vQueueAddToRegistry(xQueueMasterHdl, "MbMasterPortEventQueue");
|
vQueueAddToRegistry(xQueueMasterHdl, "MbMasterPortEventQueue");
|
||||||
xTransactionID = 0;
|
atomic_init(&xTransactionID, 0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ xMBMasterPortEventPost( eMBMasterEventEnum eEvent)
|
|||||||
xEvent.xPostTimestamp = esp_timer_get_time();
|
xEvent.xPostTimestamp = esp_timer_get_time();
|
||||||
|
|
||||||
if (eEvent & EV_MASTER_TRANS_START) {
|
if (eEvent & EV_MASTER_TRANS_START) {
|
||||||
MB_ATOMIC_STORE(&(xTransactionID), xEvent.xPostTimestamp);
|
atomic_store(&(xTransactionID), xEvent.xPostTimestamp);
|
||||||
}
|
}
|
||||||
xEvent.eEvent = (eEvent & ~EV_MASTER_TRANS_START);
|
xEvent.eEvent = (eEvent & ~EV_MASTER_TRANS_START);
|
||||||
|
|
||||||
@ -118,7 +119,7 @@ xMBMasterPortEventGet(xMBMasterEventType *peEvent)
|
|||||||
BOOL xEventHappened = FALSE;
|
BOOL xEventHappened = FALSE;
|
||||||
|
|
||||||
if (xQueueReceive(xQueueMasterHdl, peEvent, portMAX_DELAY) == pdTRUE) {
|
if (xQueueReceive(xQueueMasterHdl, peEvent, portMAX_DELAY) == pdTRUE) {
|
||||||
peEvent->xTransactionId = MB_ATOMIC_LOAD(&xTransactionID);
|
peEvent->xTransactionId = atomic_load(&xTransactionID);
|
||||||
// Set event bits in confirmation group (for synchronization with port task)
|
// Set event bits in confirmation group (for synchronization with port task)
|
||||||
xEventGroupSetBits(xEventGroupMasterConfirmHdl, peEvent->eEvent);
|
xEventGroupSetBits(xEventGroupMasterConfirmHdl, peEvent->eEvent);
|
||||||
peEvent->xGetTimestamp = esp_timer_get_time();
|
peEvent->xGetTimestamp = esp_timer_get_time();
|
||||||
@ -145,7 +146,7 @@ xMBMasterPortFsmWaitConfirmation( eMBMasterEventEnum eEventMask, ULONG ulTimeout
|
|||||||
|
|
||||||
uint64_t xMBMasterPortGetTransactionId( )
|
uint64_t xMBMasterPortGetTransactionId( )
|
||||||
{
|
{
|
||||||
return MB_ATOMIC_LOAD(&xTransactionID);
|
return atomic_load(&xTransactionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is initialize the OS resource for modbus master.
|
// This function is initialize the OS resource for modbus master.
|
||||||
|
Reference in New Issue
Block a user