diff --git a/components/net/freemodbus-v1.6.0/modbus/functions/mbfunccoils_m.c b/components/net/freemodbus-v1.6.0/modbus/functions/mbfunccoils_m.c
index 553f57b1b7..f6bb51cdf6 100644
--- a/components/net/freemodbus-v1.6.0/modbus/functions/mbfunccoils_m.c
+++ b/components/net/freemodbus-v1.6.0/modbus/functions/mbfunccoils_m.c
@@ -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. */
diff --git a/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncdisc_m.c b/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncdisc_m.c
index 187872c2a6..6c8d6c4741 100644
--- a/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncdisc_m.c
+++ b/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncdisc_m.c
@@ -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 )
diff --git a/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncholding_m.c b/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncholding_m.c
index faefbbbb40..e1fe69e383 100644
--- a/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncholding_m.c
+++ b/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncholding_m.c
@@ -86,14 +86,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
+/**
+ * This function will request write holding register.
+ *
+ * @param ucSndAddr salve address
+ * @param usRegAddr register start address
+ * @param usRegData register data to be written
+ * @param lTimeOut timeout (-1 will waiting forever)
+ *
+ * @return error code
+ */
eMBMasterReqErrCode
-eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData )
+eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, 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);
@@ -105,6 +115,7 @@ eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRe
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usRegData ;
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
+ eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
}
@@ -123,7 +134,7 @@ eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
usRegAddress++;
/* Make callback to update the value. */
- eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF],
+ eRegStatus = eMBMasterRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF],
usRegAddress, 1, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */
@@ -143,16 +154,27 @@ eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
+/**
+ * This function will request write multiple holding register.
+ *
+ * @param ucSndAddr salve address
+ * @param usRegAddr register start address
+ * @param usNRegs register total number
+ * @param pusDataBuffer data to be written
+ * @param lTimeOut timeout (-1 will waiting forever)
+ *
+ * @return error code
+ */
eMBMasterReqErrCode
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
- USHORT usRegAddr, USHORT usNRegs, USHORT * pusDataBuffer )
+ USHORT usRegAddr, USHORT usNRegs, USHORT * pusDataBuffer, LONG lTimeOut )
{
UCHAR *ucMBFrame;
USHORT usRegIndex = 0;
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);
@@ -171,6 +193,7 @@ eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
}
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + 2*usNRegs );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
+ eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
}
@@ -186,7 +209,8 @@ eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
- if( *usLen == MB_PDU_SIZE_MIN + MB_PDU_FUNC_WRITE_MUL_SIZE )
+ /* If this request is broadcast, the *usLen is not need check. */
+ if( ( *usLen == MB_PDU_SIZE_MIN + MB_PDU_FUNC_WRITE_MUL_SIZE ) || xMBMasterRequestIsBroadcast() )
{
vMBMasterGetPDUSndBuf(&ucMBFrame);
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_WRITE_MUL_ADDR_OFF] << 8 );
@@ -202,7 +226,7 @@ eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
{
/* Make callback to update the register values. */
eRegStatus =
- eMBRegHoldingCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
+ eMBMasterRegHoldingCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
usRegAddress, usRegCount, MB_REG_WRITE );
/* If an error occured convert it into a Modbus exception. */
@@ -227,14 +251,24 @@ eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_READ_HOLDING_ENABLED > 0
+/**
+ * This function will request read holding 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
-eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs )
+eMBMasterReqReadHoldingRegister( 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);
@@ -246,6 +280,7 @@ eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRe
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;
}
@@ -260,7 +295,12 @@ eMBMasterFuncReadHoldingRegister( 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 );
@@ -268,7 +308,7 @@ eMBMasterFuncReadHoldingRegister( 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.
@@ -276,7 +316,7 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
if( ( usRegCount >= 1 ) && ( 2 * usRegCount == pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ) )
{
/* Make callback to fill the buffer. */
- eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usRegCount, MB_REG_READ );
+ eRegStatus = eMBMasterRegHoldingCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usRegCount, MB_REG_READ );
/* If an error occured convert it into a Modbus exception. */
if( eRegStatus != MB_ENOERR )
{
@@ -300,17 +340,30 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
+/**
+ * This function will request read and write holding register.
+ *
+ * @param ucSndAddr salve address
+ * @param usReadRegAddr read register start address
+ * @param usNReadRegs read register total number
+ * @param pusDataBuffer data to be written
+ * @param usWriteRegAddr write register start address
+ * @param usNWriteRegs write register total number
+ * @param lTimeOut timeout (-1 will waiting forever)
+ *
+ * @return error code
+ */
eMBMasterReqErrCode
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
- USHORT usWriteRegAddr, USHORT usNWriteRegs )
+ USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut )
{
UCHAR *ucMBFrame;
USHORT usRegIndex = 0;
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);
@@ -333,6 +386,7 @@ eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
}
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READWRITE_SIZE_MIN + 2*usNWriteRegs );
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
+ eErrStatus = eMBMasterWaitRequestFinish( );
}
return eErrStatus;
}
@@ -349,7 +403,12 @@ eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen
eMBException eStatus = MB_EX_NONE;
eMBErrorCode eRegStatus;
- if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READWRITE_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_READWRITE_SIZE_MIN )
{
vMBMasterGetPDUSndBuf(&ucMBFrame);
usRegReadAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_READ_ADDR_OFF] << 8U );
@@ -369,13 +428,13 @@ eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen
if( ( 2 * usRegReadCount ) == pucFrame[MB_PDU_FUNC_READWRITE_READ_BYTECNT_OFF] )
{
/* Make callback to update the register values. */
- eRegStatus = eMBRegHoldingCB( &ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_VALUES_OFF],
+ eRegStatus = eMBMasterRegHoldingCB( &ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_VALUES_OFF],
usRegWriteAddress, usRegWriteCount, MB_REG_WRITE );
if( eRegStatus == MB_ENOERR )
{
/* Make the read callback. */
- eRegStatus = eMBRegHoldingCB(&pucFrame[MB_PDU_FUNC_READWRITE_READ_VALUES_OFF],
+ eRegStatus = eMBMasterRegHoldingCB(&pucFrame[MB_PDU_FUNC_READWRITE_READ_VALUES_OFF],
usRegReadAddress, usRegReadCount, MB_REG_READ);
}
if( eRegStatus != MB_ENOERR )
diff --git a/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncinput_m.c b/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncinput_m.c
index e5f362bbec..2127efef67 100644
--- a/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncinput_m.c
+++ b/components/net/freemodbus-v1.6.0/modbus/functions/mbfuncinput_m.c
@@ -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 )
{
diff --git a/components/net/freemodbus-v1.6.0/modbus/include/mb_m.h b/components/net/freemodbus-v1.6.0/modbus/include/mb_m.h
index 9c4fa43e60..f6b25e2cf3 100644
--- a/components/net/freemodbus-v1.6.0/modbus/include/mb_m.h
+++ b/components/net/freemodbus-v1.6.0/modbus/include/mb_m.h
@@ -77,13 +77,10 @@ typedef enum
MB_MRE_NO_ERR, /*!< no error. */
MB_MRE_NO_REG, /*!< illegal register address. */
MB_MRE_ILL_ARG, /*!< illegal argument. */
- MB_MRE_PORT_ERR, /*!< porting layer error. */
- MB_MRE_NO_RES, /*!< insufficient resources. */
- MB_MRE_IO, /*!< I/O error. */
- MB_MRE_ILL_STATE, /*!< protocol stack in illegal state. */
+ MB_MRE_REV_DATA, /*!< receive data error. */
MB_MRE_TIMEDOUT, /*!< timeout error occurred. */
MB_MRE_MASTER_BUSY, /*!< master is busy now. */
- MB_MRE_SLAVE_EXCE /*!< slave has exception. */
+ MB_MRE_EXE_FUN /*!< execute function error. */
} eMBMasterReqErrCode;
/*! \ingroup modbus
* \brief TimerMode is Master 3 kind of Timer modes.
@@ -189,31 +186,176 @@ eMBErrorCode eMBMasterDisable( void );
*/
eMBErrorCode eMBMasterPoll( void );
+/*! \ingroup modbus
+ * \brief Registers a callback handler for a given function code.
+ *
+ * This function registers a new callback handler for a given function code.
+ * The callback handler supplied is responsible for interpreting the Modbus PDU and
+ * the creation of an appropriate response. In case of an error it should return
+ * one of the possible Modbus exceptions which results in a Modbus exception frame
+ * sent by the protocol stack.
+ *
+ * \param ucFunctionCode The Modbus function code for which this handler should
+ * be registers. Valid function codes are in the range 1 to 127.
+ * \param pxHandler The function handler which should be called in case
+ * such a frame is received. If \c NULL a previously registered function handler
+ * for this function code is removed.
+ *
+ * \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no
+ * more resources are available it returns eMBErrorCode::MB_ENORES. In this
+ * case the values in mbconfig.h should be adjusted. If the argument was not
+ * valid it returns eMBErrorCode::MB_EINVAL.
+ */
+eMBErrorCode eMBMasterRegisterCB( UCHAR ucFunctionCode,
+ pxMBFunctionHandler pxHandler );
+
+/* ----------------------- Callback -----------------------------------------*/
+
+/*! \defgroup modbus_master registers Modbus Registers
+ * \code #include "mb_m.h" \endcode
+ * The protocol stack does not internally allocate any memory for the
+ * registers. This makes the protocol stack very small and also usable on
+ * low end targets. In addition the values don't have to be in the memory
+ * and could for example be stored in a flash.
+ * Whenever the protocol stack requires a value it calls one of the callback
+ * function with the register address and the number of registers to read
+ * as an argument. The application should then read the actual register values
+ * (for example the ADC voltage) and should store the result in the supplied
+ * buffer.
+ * If the protocol stack wants to update a register value because a write
+ * register function was received a buffer with the new register values is
+ * passed to the callback function. The function should then use these values
+ * to update the application register values.
+ */
+
+/*! \ingroup modbus_registers
+ * \brief Callback function used if the value of a Input Register
+ * is required by the protocol stack. The starting register address is given
+ * by \c usAddress and the last register is given by usAddress +
+ * usNRegs - 1.
+ *
+ * \param pucRegBuffer A buffer where the callback function should write
+ * the current value of the modbus registers to.
+ * \param usAddress The starting address of the register. Input registers
+ * are in the range 1 - 65535.
+ * \param usNRegs Number of registers the callback function must supply.
+ *
+ * \return The function must return one of the following error codes:
+ * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
+ * Modbus response is sent.
+ * - eMBErrorCode::MB_ENOREG If the application does not map an coils
+ * within the requested address range. In this case a
+ * ILLEGAL DATA ADDRESS is sent as a response.
+ */
+eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
+ USHORT usNRegs );
+
+/*! \ingroup modbus_registers
+ * \brief Callback function used if a Holding Register value is
+ * read or written by the protocol stack. The starting register address
+ * is given by \c usAddress and the last register is given by
+ * usAddress + usNRegs - 1.
+ *
+ * \param pucRegBuffer If the application registers values should be updated the
+ * buffer points to the new registers values. If the protocol stack needs
+ * to now the current values the callback function should write them into
+ * this buffer.
+ * \param usAddress The starting address of the register.
+ * \param usNRegs Number of registers to read or write.
+ * \param eMode If eMBRegisterMode::MB_REG_WRITE the application register
+ * values should be updated from the values in the buffer. For example
+ * this would be the case when the Modbus master has issued an
+ * WRITE SINGLE REGISTER command.
+ * If the value eMBRegisterMode::MB_REG_READ the application should copy
+ * the current values into the buffer \c pucRegBuffer.
+ *
+ * \return The function must return one of the following error codes:
+ * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
+ * Modbus response is sent.
+ * - eMBErrorCode::MB_ENOREG If the application does not map an coils
+ * within the requested address range. In this case a
+ * ILLEGAL DATA ADDRESS is sent as a response.
+ */
+eMBErrorCode eMBMasterRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
+ USHORT usNRegs, eMBRegisterMode eMode );
+
+/*! \ingroup modbus_registers
+ * \brief Callback function used if a Coil Register value is
+ * read or written by the protocol stack. If you are going to use
+ * this function you might use the functions xMBUtilSetBits( ) and
+ * xMBUtilGetBits( ) for working with bitfields.
+ *
+ * \param pucRegBuffer The bits are packed in bytes where the first coil
+ * starting at address \c usAddress is stored in the LSB of the
+ * first byte in the buffer pucRegBuffer
.
+ * If the buffer should be written by the callback function unused
+ * coil values (I.e. if not a multiple of eight coils is used) should be set
+ * to zero.
+ * \param usAddress The first coil number.
+ * \param usNCoils Number of coil values requested.
+ * \param eMode If eMBRegisterMode::MB_REG_WRITE the application values should
+ * be updated from the values supplied in the buffer \c pucRegBuffer.
+ * If eMBRegisterMode::MB_REG_READ the application should store the current
+ * values in the buffer \c pucRegBuffer.
+ *
+ * \return The function must return one of the following error codes:
+ * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
+ * Modbus response is sent.
+ * - eMBErrorCode::MB_ENOREG If the application does not map an coils
+ * within the requested address range. In this case a
+ * ILLEGAL DATA ADDRESS is sent as a response.
+ */
+eMBErrorCode eMBMasterRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
+ USHORT usNCoils, eMBRegisterMode eMode );
+
+/*! \ingroup modbus_registers
+ * \brief Callback function used if a Input Discrete Register value is
+ * read by the protocol stack.
+ *
+ * If you are going to use his function you might use the functions
+ * xMBUtilSetBits( ) and xMBUtilGetBits( ) for working with bitfields.
+ *
+ * \param pucRegBuffer The buffer should be updated with the current
+ * coil values. The first discrete input starting at \c usAddress must be
+ * stored at the LSB of the first byte in the buffer. If the requested number
+ * is not a multiple of eight the remaining bits should be set to zero.
+ * \param usAddress The starting address of the first discrete input.
+ * \param usNDiscrete Number of discrete input values.
+ * \return The function must return one of the following error codes:
+ * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
+ * Modbus response is sent.
+ * - eMBErrorCode::MB_ENOREG If the application does not map an coils
+ * within the requested address range. In this case a
+ * ILLEGAL DATA ADDRESS is sent as a response.
+ */
+eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress,
+ USHORT usNDiscrete );
/*! \ingroup modbus
*\brief These Modbus functions are called for user when Modbus run in Master Mode.
*/
eMBMasterReqErrCode
-eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs );
+eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut );
eMBMasterReqErrCode
-eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData );
+eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut );
eMBMasterReqErrCode
-eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, USHORT * pusDataBuffer );
+eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr,
+ USHORT usNRegs, USHORT * pusDataBuffer, LONG lTimeOut );
eMBMasterReqErrCode
-eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs );
+eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut );
eMBMasterReqErrCode
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
- USHORT usWriteRegAddr, USHORT usNWriteRegs );
+ USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut );
eMBMasterReqErrCode
-eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils );
+eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils, LONG lTimeOut );
eMBMasterReqErrCode
-eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData );
+eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LONG lTimeOut );
eMBMasterReqErrCode
eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
- USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer );
+ USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer, LONG lTimeOut );
eMBMasterReqErrCode
-eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn );
+eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut );
eMBException
eMBMasterFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen );
@@ -239,16 +381,18 @@ eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen
/*ŁĄ \ingroup modbus
*\brief These functions are interface for Modbus Master
*/
-BOOL xMBMasterGetIsBusy( void );
void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame );
UCHAR ucMBMasterGetDestAddress( void );
void vMBMasterSetDestAddress( UCHAR Address );
-void vMBMasterSetIsBusy( BOOL IsBusy );
BOOL xMBMasterGetCBRunInMasterMode( void );
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode );
-UCHAR ucMBMasterGetPDUSndLength( void );
-void vMBMasterSetPDUSndLength( UCHAR SendPDULength );
+USHORT usMBMasterGetPDUSndLength( void );
+void vMBMasterSetPDUSndLength( USHORT SendPDULength );
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode );
+BOOL xMBMasterRequestIsBroadcast( void );
+eMBMasterErrorEventType eMBMasterGetErrorType( void );
+void vMBMasterSetErrorType( eMBMasterErrorEventType errorType );
+eMBMasterReqErrCode eMBMasterWaitRequestFinish( void );
/* ----------------------- Callback -----------------------------------------*/
diff --git a/components/net/freemodbus-v1.6.0/modbus/include/mbconfig.h b/components/net/freemodbus-v1.6.0/modbus/include/mbconfig.h
index c5434de47e..89030b7abd 100644
--- a/components/net/freemodbus-v1.6.0/modbus/include/mbconfig.h
+++ b/components/net/freemodbus-v1.6.0/modbus/include/mbconfig.h
@@ -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
diff --git a/components/net/freemodbus-v1.6.0/modbus/include/mbport.h b/components/net/freemodbus-v1.6.0/modbus/include/mbport.h
index a4c0a24dd4..11794a2929 100644
--- a/components/net/freemodbus-v1.6.0/modbus/include/mbport.h
+++ b/components/net/freemodbus-v1.6.0/modbus/include/mbport.h
@@ -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 ------------------*/
/*!
diff --git a/components/net/freemodbus-v1.6.0/modbus/mb_m.c b/components/net/freemodbus-v1.6.0/modbus/mb_m.c
index 8f86f54182..4e7c4b2b74 100644
--- a/components/net/freemodbus-v1.6.0/modbus/mb_m.c
+++ b/components/net/freemodbus-v1.6.0/modbus/mb_m.c
@@ -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
diff --git a/components/net/freemodbus-v1.6.0/modbus/rtu/mbrtu_m.c b/components/net/freemodbus-v1.6.0/modbus/rtu/mbrtu_m.c
index fffbb23f9f..987c9a3156 100644
--- a/components/net/freemodbus-v1.6.0/modbus/rtu/mbrtu_m.c
+++ b/components/net/freemodbus-v1.6.0/modbus/rtu/mbrtu_m.c
@@ -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