mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-11-08 14:43:04 +08:00
[modbus]update modbus master and slave source code to lastest.
This commit is contained in:
1 parent
204298c1b2
commit
d8bbb5f126
9 files changed
+492
-124
No files matched your search
@@ -74,14 +74,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
|
||||
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
||||
#if MB_FUNC_READ_COILS_ENABLED > 0
|
||||
|
||||
/**
|
||||
* This function will request read coil.
|
||||
*
|
||||
* @param ucSndAddr salve address
|
||||
* @param usCoilAddr coil start address
|
||||
* @param usNCoils coil total number
|
||||
* @param lTimeOut timeout (-1 will waiting forever)
|
||||
*
|
||||
* @return error code
|
||||
*/
|
||||
eMBMasterReqErrCode
|
||||
eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils )
|
||||
eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils ,LONG lTimeOut )
|
||||
{
|
||||
UCHAR *ucMBFrame;
|
||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||
|
||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
@@ -93,6 +103,8 @@ eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils )
|
||||
ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF + 1] = usNCoils;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
|
||||
}
|
||||
return eErrStatus;
|
||||
}
|
||||
@@ -108,7 +120,12 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
|
||||
eMBException eStatus = MB_EX_NONE;
|
||||
eMBErrorCode eRegStatus;
|
||||
|
||||
if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
|
||||
/* If this request is broadcast, and it's read mode. This request don't need execute. */
|
||||
if ( xMBMasterRequestIsBroadcast() )
|
||||
{
|
||||
eStatus = MB_EX_NONE;
|
||||
}
|
||||
else if ( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
||||
@@ -136,7 +153,7 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
|
||||
( ucByteCount == pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] ) )
|
||||
{
|
||||
/* Make callback to fill the buffer. */
|
||||
eRegStatus = eMBRegCoilsCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usCoilCount, MB_REG_READ );
|
||||
eRegStatus = eMBMasterRegCoilsCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usCoilCount, MB_REG_READ );
|
||||
|
||||
/* If an error occured convert it into a Modbus exception. */
|
||||
if( eRegStatus != MB_ENOERR )
|
||||
@@ -161,15 +178,27 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
|
||||
|
||||
#if MB_FUNC_WRITE_COIL_ENABLED > 0
|
||||
|
||||
/**
|
||||
* This function will request write one coil.
|
||||
*
|
||||
* @param ucSndAddr salve address
|
||||
* @param usCoilAddr coil start address
|
||||
* @param usCoilData data to be written
|
||||
* @param lTimeOut timeout (-1 will waiting forever)
|
||||
*
|
||||
* @return error code
|
||||
*
|
||||
* @see eMBMasterReqWriteMultipleCoils
|
||||
*/
|
||||
eMBMasterReqErrCode
|
||||
eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData )
|
||||
eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LONG lTimeOut )
|
||||
{
|
||||
UCHAR *ucMBFrame;
|
||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||
|
||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else if ( usCoilAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
if ( usCoilAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
else if ( ( usCoilData != 0xFF00 ) && ( usCoilData != 0x0000 ) ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
@@ -181,6 +210,7 @@ eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData )
|
||||
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usCoilData;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
}
|
||||
@@ -214,7 +244,7 @@ eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
|
||||
ucBuf[0] = 0;
|
||||
}
|
||||
eRegStatus =
|
||||
eMBRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE );
|
||||
eMBMasterRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE );
|
||||
|
||||
/* If an error occured convert it into a Modbus exception. */
|
||||
if( eRegStatus != MB_ENOERR )
|
||||
@@ -240,18 +270,31 @@ eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
|
||||
|
||||
#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
|
||||
|
||||
/**
|
||||
* This function will request write multiple coils.
|
||||
*
|
||||
* @param ucSndAddr salve address
|
||||
* @param usCoilAddr coil start address
|
||||
* @param usNCoils coil total number
|
||||
* @param usCoilData data to be written
|
||||
* @param lTimeOut timeout (-1 will waiting forever)
|
||||
*
|
||||
* @return error code
|
||||
*
|
||||
* @see eMBMasterReqWriteCoil
|
||||
*/
|
||||
eMBMasterReqErrCode
|
||||
eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
||||
USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer )
|
||||
USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer, LONG lTimeOut)
|
||||
{
|
||||
UCHAR *ucMBFrame;
|
||||
USHORT usRegIndex = 0;
|
||||
UCHAR ucByteCount;
|
||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||
|
||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
else if ( usNCoils > MB_PDU_REQ_WRITE_MUL_COILCNT_MAX ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
@@ -277,6 +320,7 @@ eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
||||
}
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + ucByteCount );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
}
|
||||
@@ -293,7 +337,8 @@ eMBMasterFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
|
||||
eMBException eStatus = MB_EX_NONE;
|
||||
eMBErrorCode eRegStatus;
|
||||
|
||||
if( *usLen == MB_PDU_FUNC_WRITE_MUL_SIZE )
|
||||
/* If this request is broadcast, the *usLen is not need check. */
|
||||
if( ( *usLen == MB_PDU_FUNC_WRITE_MUL_SIZE ) || xMBMasterRequestIsBroadcast() )
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
|
||||
@@ -318,7 +363,7 @@ eMBMasterFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
|
||||
if( ( usCoilCnt >= 1 ) && ( ucByteCountVerify == ucByteCount ) )
|
||||
{
|
||||
eRegStatus =
|
||||
eMBRegCoilsCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
|
||||
eMBMasterRegCoilsCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
|
||||
usRegAddress, usCoilCnt, MB_REG_WRITE );
|
||||
|
||||
/* If an error occured convert it into a Modbus exception. */
|
||||
|
||||
@@ -57,16 +57,26 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
|
||||
|
||||
/* ----------------------- Start implementation -----------------------------*/
|
||||
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
||||
#if MB_FUNC_READ_COILS_ENABLED > 0
|
||||
#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
|
||||
|
||||
/**
|
||||
* This function will request read discrete inputs.
|
||||
*
|
||||
* @param ucSndAddr salve address
|
||||
* @param usDiscreteAddr discrete start address
|
||||
* @param usNDiscreteIn discrete total number
|
||||
* @param lTimeOut timeout (-1 will waiting forever)
|
||||
*
|
||||
* @return error code
|
||||
*/
|
||||
eMBMasterReqErrCode
|
||||
eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn )
|
||||
eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut )
|
||||
{
|
||||
UCHAR *ucMBFrame;
|
||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||
|
||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
@@ -78,6 +88,7 @@ eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT u
|
||||
ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF + 1] = usNDiscreteIn;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
}
|
||||
@@ -93,7 +104,12 @@ eMBMasterFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )
|
||||
eMBException eStatus = MB_EX_NONE;
|
||||
eMBErrorCode eRegStatus;
|
||||
|
||||
if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
|
||||
/* If this request is broadcast, and it's read mode. This request don't need execute. */
|
||||
if ( xMBMasterRequestIsBroadcast() )
|
||||
{
|
||||
eStatus = MB_EX_NONE;
|
||||
}
|
||||
else if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
||||
@@ -120,7 +136,7 @@ eMBMasterFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )
|
||||
if ((usDiscreteCnt >= 1) && ucNBytes == pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF])
|
||||
{
|
||||
/* Make callback to fill the buffer. */
|
||||
eRegStatus = eMBRegDiscreteCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usDiscreteCnt );
|
||||
eRegStatus = eMBMasterRegDiscreteCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usDiscreteCnt );
|
||||
|
||||
/* If an error occured convert it into a Modbus exception. */
|
||||
if( eRegStatus != MB_ENOERR )
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -59,14 +59,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
|
||||
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
||||
#if MB_FUNC_READ_INPUT_ENABLED > 0
|
||||
|
||||
/**
|
||||
* This function will request read input register.
|
||||
*
|
||||
* @param ucSndAddr salve address
|
||||
* @param usRegAddr register start address
|
||||
* @param usNRegs register total number
|
||||
* @param lTimeOut timeout (-1 will waiting forever)
|
||||
*
|
||||
* @return error code
|
||||
*/
|
||||
eMBMasterReqErrCode
|
||||
eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs )
|
||||
eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut )
|
||||
{
|
||||
UCHAR *ucMBFrame;
|
||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||
|
||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||
else
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
@@ -78,6 +88,7 @@ eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs
|
||||
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
|
||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||
}
|
||||
return eErrStatus;
|
||||
}
|
||||
@@ -92,7 +103,12 @@ eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||
eMBException eStatus = MB_EX_NONE;
|
||||
eMBErrorCode eRegStatus;
|
||||
|
||||
if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN)
|
||||
/* If this request is broadcast, and it's read mode. This request don't need execute. */
|
||||
if ( xMBMasterRequestIsBroadcast() )
|
||||
{
|
||||
eStatus = MB_EX_NONE;
|
||||
}
|
||||
else if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
|
||||
{
|
||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
||||
@@ -100,7 +116,7 @@ eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||
usRegAddress++;
|
||||
|
||||
usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] << 8 );
|
||||
usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] );
|
||||
usRegCount |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] );
|
||||
|
||||
/* Check if the number of registers to read is valid. If not
|
||||
* return Modbus illegal data value exception.
|
||||
@@ -108,7 +124,7 @@ eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||
if( ( usRegCount >= 1 ) && ( 2 * usRegCount == pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ) )
|
||||
{
|
||||
/* Make callback to fill the buffer. */
|
||||
eRegStatus = eMBRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usRegCount );
|
||||
eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usRegCount );
|
||||
/* If an error occured convert it into a Modbus exception. */
|
||||
if( eRegStatus != MB_ENOERR )
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -115,9 +115,9 @@ PR_BEGIN_EXTERN_C
|
||||
/*! \brief If master send a frame which is not broadcast,the master will wait sometime for slave.
|
||||
* And if slave is not respond in this time,the master will process this timeout error.
|
||||
* Then master can send other frame */
|
||||
#define MB_MASTER_TIMEOUT_MS_RESPOND (2000)
|
||||
/*! \brief The total slaves in Modbus Master system.Default 16.
|
||||
* Note : The slave ID must be continuous from 0.*/
|
||||
#define MB_MASTER_TIMEOUT_MS_RESPOND (100 )
|
||||
/*! \brief The total slaves in Modbus Master system. Default 16.
|
||||
* \note : The slave ID must be continuous from 1.*/
|
||||
#define MB_MASTER_TOTAL_SLAVE_NUM ( 16 )
|
||||
#endif
|
||||
|
||||
|
||||
@@ -36,25 +36,38 @@
|
||||
PR_BEGIN_EXTERN_C
|
||||
#endif
|
||||
|
||||
/* ----------------------- Defines ------------------------------------------*/
|
||||
|
||||
/* ----------------------- Type definitions ---------------------------------*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EV_READY, /*!< Startup finished. */
|
||||
EV_FRAME_RECEIVED, /*!< Frame received. */
|
||||
EV_EXECUTE, /*!< Execute function. */
|
||||
EV_FRAME_SENT /*!< Frame sent. */
|
||||
EV_READY = 1<<0, /*!< Startup finished. */
|
||||
EV_FRAME_RECEIVED = 1<<1, /*!< Frame received. */
|
||||
EV_EXECUTE = 1<<2, /*!< Execute function. */
|
||||
EV_FRAME_SENT = 1<<3 /*!< Frame sent. */
|
||||
} eMBEventType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EV_MASTER_READY, /*!< Startup finished. */
|
||||
EV_MASTER_FRAME_RECEIVED, /*!< Frame received. */
|
||||
EV_MASTER_EXECUTE, /*!< Execute function. */
|
||||
EV_MASTER_FRAME_SENT, /*!< Frame sent. */
|
||||
EV_MASTER_ERROR_PROCESS /*!< Frame error process*/
|
||||
EV_MASTER_READY = 1<<0, /*!< Startup finished. */
|
||||
EV_MASTER_FRAME_RECEIVED = 1<<1, /*!< Frame received. */
|
||||
EV_MASTER_EXECUTE = 1<<2, /*!< Execute function. */
|
||||
EV_MASTER_FRAME_SENT = 1<<3, /*!< Frame sent. */
|
||||
EV_MASTER_ERROR_PROCESS = 1<<4, /*!< Frame error process. */
|
||||
EV_MASTER_PROCESS_SUCESS = 1<<5, /*!< Request process success. */
|
||||
EV_MASTER_ERROR_RESPOND_TIMEOUT = 1<<6, /*!< Request respond timeout. */
|
||||
EV_MASTER_ERROR_RECEIVE_DATA = 1<<7, /*!< Request receive data error. */
|
||||
EV_MASTER_ERROR_EXECUTE_FUNCTION = 1<<8, /*!< Request execute function error. */
|
||||
} eMBMasterEventType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EV_ERROR_RESPOND_TIMEOUT, /*!< Slave respond timeout. */
|
||||
EV_ERROR_RECEIVE_DATA, /*!< Receive frame data erroe. */
|
||||
EV_ERROR_EXECUTE_FUNCTION, /*!< Execute function error. */
|
||||
} eMBMasterErrorEventType;
|
||||
|
||||
/*! \ingroup modbus
|
||||
* \brief Parity used for characters in serial mode.
|
||||
*
|
||||
@@ -82,6 +95,12 @@ BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
|
||||
|
||||
BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
|
||||
|
||||
void vMBMasterOsResInit( void );
|
||||
|
||||
BOOL xMBMasterRunResTake( int32_t time );
|
||||
|
||||
void vMBMasterRunResRelease( void );
|
||||
|
||||
/* ----------------------- Serial port functions ----------------------------*/
|
||||
|
||||
BOOL xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
|
||||
@@ -97,7 +116,6 @@ INLINE BOOL xMBPortSerialGetByte( CHAR * pucByte );
|
||||
|
||||
INLINE BOOL xMBPortSerialPutByte( CHAR ucByte );
|
||||
|
||||
|
||||
BOOL xMBMasterPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
|
||||
UCHAR ucDataBits, eMBParity eParity );
|
||||
|
||||
@@ -132,6 +150,18 @@ INLINE void vMBMasterPortTimersRespondTimeoutEnable( void );
|
||||
|
||||
INLINE void vMBMasterPortTimersDisable( void );
|
||||
|
||||
/* ----------------- Callback for the master error process ------------------*/
|
||||
void vMBMasterErrorCBRespondTimeout( UCHAR ucDestAddress, const UCHAR* pucPDUData,
|
||||
USHORT ucPDULength );
|
||||
|
||||
void vMBMasterErrorCBReceiveData( UCHAR ucDestAddress, const UCHAR* pucPDUData,
|
||||
USHORT ucPDULength );
|
||||
|
||||
void vMBMasterErrorCBExecuteFunction( UCHAR ucDestAddress, const UCHAR* pucPDUData,
|
||||
USHORT ucPDULength );
|
||||
|
||||
void vMBMasterCBRequestScuuess( void );
|
||||
|
||||
/* ----------------------- Callback for the protocol stack ------------------*/
|
||||
|
||||
/*!
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
static UCHAR ucMBMasterDestAddress;
|
||||
static BOOL xMBRunInMasterMode = FALSE;
|
||||
static BOOL xMasterIsBusy = FALSE;
|
||||
static eMBMasterErrorEventType eMBMasterCurErrorType;
|
||||
|
||||
static enum
|
||||
{
|
||||
@@ -185,6 +185,8 @@ eMBMasterInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity
|
||||
{
|
||||
eMBState = STATE_DISABLED;
|
||||
}
|
||||
/* initialize the OS resource for modbus master. */
|
||||
vMBMasterOsResInit();
|
||||
}
|
||||
return eStatus;
|
||||
}
|
||||
@@ -257,9 +259,10 @@ eMBMasterPoll( void )
|
||||
static USHORT usLength;
|
||||
static eMBException eException;
|
||||
|
||||
int i;
|
||||
int i , j;
|
||||
eMBErrorCode eStatus = MB_ENOERR;
|
||||
eMBMasterEventType eEvent;
|
||||
eMBMasterErrorEventType errorType;
|
||||
|
||||
/* Check if the protocol stack is ready. */
|
||||
if( eMBState != STATE_ENABLED )
|
||||
@@ -285,6 +288,7 @@ eMBMasterPoll( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
}
|
||||
break;
|
||||
@@ -292,52 +296,80 @@ eMBMasterPoll( void )
|
||||
case EV_MASTER_EXECUTE:
|
||||
ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
|
||||
eException = MB_EX_ILLEGAL_FUNCTION;
|
||||
for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
|
||||
{
|
||||
/* No more function handlers registered. Abort. */
|
||||
if( xMasterFuncHandlers[i].ucFunctionCode == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if( xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode )
|
||||
{
|
||||
vMBMasterSetCBRunInMasterMode(TRUE);
|
||||
eException = xMasterFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
|
||||
vMBMasterSetCBRunInMasterMode(FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If receive frame has exception .The receive function code highest bit is 1.*/
|
||||
if(ucFunctionCode >> 7) eException = (eMBException)ucMBFrame[MB_PDU_DATA_OFF];
|
||||
if(ucFunctionCode >> 7) {
|
||||
eException = (eMBException)ucMBFrame[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;
|
||||
}
|
||||
else 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(ucMBFrame, &usLength);
|
||||
}
|
||||
}
|
||||
else {
|
||||
eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
|
||||
}
|
||||
vMBMasterSetCBRunInMasterMode(FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If master has exception ,Master will send error process.Otherwise the Master is idle.*/
|
||||
if (eException != MB_EX_NONE) ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
else vMBMasterSetIsBusy( FALSE );
|
||||
if (eException != MB_EX_NONE) {
|
||||
vMBMasterSetErrorType(EV_ERROR_EXECUTE_FUNCTION);
|
||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
}
|
||||
else {
|
||||
vMBMasterCBRequestScuuess( );
|
||||
vMBMasterRunResRelease( );
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_MASTER_FRAME_SENT:
|
||||
/* Master is busy now. */
|
||||
vMBMasterSetIsBusy( TRUE );
|
||||
vMBMasterGetPDUSndBuf( &ucMBFrame );
|
||||
eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, ucMBMasterGetPDUSndLength() );
|
||||
eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, usMBMasterGetPDUSndLength() );
|
||||
break;
|
||||
|
||||
case EV_MASTER_ERROR_PROCESS:
|
||||
vMBMasterSetIsBusy( FALSE );
|
||||
/* Execute specified error process callback function. */
|
||||
errorType = eMBMasterGetErrorType();
|
||||
vMBMasterGetPDUSndBuf( &ucMBFrame );
|
||||
switch (errorType) {
|
||||
case EV_ERROR_RESPOND_TIMEOUT:
|
||||
vMBMasterErrorCBRespondTimeout(ucMBMasterGetDestAddress(),
|
||||
ucMBFrame, usMBMasterGetPDUSndLength());
|
||||
break;
|
||||
case EV_ERROR_RECEIVE_DATA:
|
||||
vMBMasterErrorCBReceiveData(ucMBMasterGetDestAddress(),
|
||||
ucMBFrame, usMBMasterGetPDUSndLength());
|
||||
break;
|
||||
case EV_ERROR_EXECUTE_FUNCTION:
|
||||
vMBMasterErrorCBExecuteFunction(ucMBMasterGetDestAddress(),
|
||||
ucMBFrame, usMBMasterGetPDUSndLength());
|
||||
break;
|
||||
}
|
||||
vMBMasterRunResRelease();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return MB_ENOERR;
|
||||
}
|
||||
/* Get whether the Modbus Master is busy.*/
|
||||
BOOL xMBMasterGetIsBusy( void )
|
||||
{
|
||||
return xMasterIsBusy;
|
||||
}
|
||||
/* Set whether the Modbus Master is busy.*/
|
||||
void vMBMasterSetIsBusy( BOOL IsBusy )
|
||||
{
|
||||
xMasterIsBusy = IsBusy;
|
||||
}
|
||||
|
||||
/* Get whether the Modbus Master is run in master mode.*/
|
||||
BOOL xMBMasterGetCBRunInMasterMode( void )
|
||||
{
|
||||
@@ -348,15 +380,27 @@ void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
|
||||
{
|
||||
xMBRunInMasterMode = IsMasterMode;
|
||||
}
|
||||
/* Get Modbus Master send destination address*/
|
||||
/* Get Modbus Master send destination address. */
|
||||
UCHAR ucMBMasterGetDestAddress( void )
|
||||
{
|
||||
return ucMBMasterDestAddress;
|
||||
}
|
||||
/* Set Modbus Master send destination address*/
|
||||
/* Set Modbus Master send destination address. */
|
||||
void vMBMasterSetDestAddress( UCHAR Address )
|
||||
{
|
||||
ucMBMasterDestAddress = Address;
|
||||
}
|
||||
/* Get Modbus Master current error event type. */
|
||||
eMBMasterErrorEventType eMBMasterGetErrorType( void )
|
||||
{
|
||||
return eMBMasterCurErrorType;
|
||||
}
|
||||
/* Set Modbus Master current error event type. */
|
||||
void vMBMasterSetErrorType( eMBMasterErrorEventType errorType )
|
||||
{
|
||||
eMBMasterCurErrorType = errorType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -74,7 +74,7 @@ static volatile eMBMasterRcvState eRcvState;
|
||||
|
||||
static volatile UCHAR ucMasterRTUSndBuf[MB_PDU_SIZE_MAX];
|
||||
static volatile UCHAR ucMasterRTURcvBuf[MB_SER_PDU_SIZE_MAX];
|
||||
static volatile UCHAR ucMasterSendPDULength;
|
||||
static volatile USHORT usMasterSendPDULength;
|
||||
|
||||
static volatile UCHAR *pucMasterSndBufferCur;
|
||||
static volatile USHORT usMasterSndBufferCount;
|
||||
@@ -235,7 +235,7 @@ xMBMasterRTUReceiveFSM( void )
|
||||
BOOL xTaskNeedSwitch = FALSE;
|
||||
UCHAR ucByte;
|
||||
|
||||
assert_param( eSndState == STATE_M_TX_IDLE );
|
||||
assert_param(( eSndState == STATE_M_TX_IDLE ) || ( eSndState == STATE_M_TX_XFWR ));
|
||||
|
||||
/* Always read the character. */
|
||||
( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
|
||||
@@ -364,12 +364,15 @@ xMBMasterRTUTimerExpired(void)
|
||||
|
||||
/* An error occured while receiving the frame. */
|
||||
case STATE_M_RX_ERROR:
|
||||
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||
xNeedPoll = xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||
break;
|
||||
|
||||
/* Function called in an illegal state. */
|
||||
default:
|
||||
assert_param(
|
||||
( eRcvState == STATE_M_RX_INIT ) || ( eRcvState == STATE_M_RX_RCV ) || ( eRcvState == STATE_M_RX_ERROR ));
|
||||
( eRcvState == STATE_M_RX_INIT ) || ( eRcvState == STATE_M_RX_RCV ) ||
|
||||
( eRcvState == STATE_M_RX_ERROR ) || ( eRcvState == STATE_M_RX_IDLE ));
|
||||
break;
|
||||
}
|
||||
eRcvState = STATE_M_RX_IDLE;
|
||||
@@ -380,18 +383,24 @@ xMBMasterRTUTimerExpired(void)
|
||||
* If the frame is broadcast,The master will idle,and if the frame is not
|
||||
* broadcast.Notify the listener process error.*/
|
||||
case STATE_M_TX_XFWR:
|
||||
if ( xFrameIsBroadcast == FALSE ) xNeedPoll = xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS);
|
||||
if ( xFrameIsBroadcast == FALSE ) {
|
||||
vMBMasterSetErrorType(EV_ERROR_RESPOND_TIMEOUT);
|
||||
xNeedPoll = xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS);
|
||||
}
|
||||
break;
|
||||
/* Function called in an illegal state. */
|
||||
default:
|
||||
assert_param( eSndState == STATE_M_TX_XFWR );
|
||||
assert_param(
|
||||
( eSndState == STATE_M_TX_XFWR ) || ( eSndState == STATE_M_TX_IDLE ));
|
||||
break;
|
||||
}
|
||||
eSndState = STATE_M_TX_IDLE;
|
||||
|
||||
vMBMasterPortTimersDisable( );
|
||||
/* If timer mode is convert delay ,then Master is idel now. */
|
||||
if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) vMBMasterSetIsBusy( FALSE );
|
||||
/* If timer mode is convert delay, the master event then turns EV_MASTER_EXECUTE status. */
|
||||
if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) {
|
||||
xNeedPoll = xMBMasterPortEventPost( EV_MASTER_EXECUTE );
|
||||
}
|
||||
|
||||
return xNeedPoll;
|
||||
}
|
||||
@@ -409,15 +418,15 @@ void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
|
||||
}
|
||||
|
||||
/* Set Modbus Master send PDU's buffer length.*/
|
||||
void vMBMasterSetPDUSndLength( UCHAR SendPDULength )
|
||||
void vMBMasterSetPDUSndLength( USHORT SendPDULength )
|
||||
{
|
||||
ucMasterSendPDULength = SendPDULength;
|
||||
usMasterSendPDULength = SendPDULength;
|
||||
}
|
||||
|
||||
/* Get Modbus Master send PDU's buffer length.*/
|
||||
UCHAR ucMBMasterGetPDUSndLength( void )
|
||||
USHORT usMBMasterGetPDUSndLength( void )
|
||||
{
|
||||
return ucMasterSendPDULength;
|
||||
return usMasterSendPDULength;
|
||||
}
|
||||
|
||||
/* Set Modbus Master current timer mode.*/
|
||||
@@ -425,5 +434,10 @@ void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
|
||||
{
|
||||
eMasterCurTimerMode = eMBTimerMode;
|
||||
}
|
||||
|
||||
/* The master request is broadcast? */
|
||||
BOOL xMBMasterRequestIsBroadcast( void ){
|
||||
return xFrameIsBroadcast;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in new issue
Block a user