Browse Source

[modbus]update modbus master and slave source code to lastest.

armink 10 years ago
parent
commit
d8bbb5f126

+ 59 - 14
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. */

+ 22 - 6
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 )

+ 80 - 21
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 )

+ 22 - 6
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 )
             {

+ 162 - 18
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.<br>
+ * 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.<br>
+ * 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 <em>Input Register</em>
+ *   is required by the protocol stack. The starting register address is given
+ *   by \c usAddress and the last register is given by <tt>usAddress +
+ *   usNRegs - 1</tt>.
+ *
+ * \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
+ *       <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
+ */
+eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
+		USHORT usNRegs );
+
+/*! \ingroup modbus_registers
+ * \brief Callback function used if a <em>Holding Register</em> 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
+ *   <tt>usAddress + usNRegs - 1</tt>.
+ *
+ * \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
+ *   <b>WRITE SINGLE REGISTER</b> 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
+ *       <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
+ */
+eMBErrorCode eMBMasterRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
+		USHORT usNRegs, eMBRegisterMode eMode );
+
+/*! \ingroup modbus_registers
+ * \brief Callback function used if a <em>Coil Register</em> 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 <code>pucRegBuffer</code>.
+ *   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
+ *       <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
+ */
+eMBErrorCode eMBMasterRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
+		USHORT usNCoils, eMBRegisterMode eMode );
+
+/*! \ingroup modbus_registers
+ * \brief Callback function used if a <em>Input Discrete Register</em> 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
+ *       <b>ILLEGAL DATA ADDRESS</b> 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 -----------------------------------------*/
 

+ 3 - 3
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
 

+ 40 - 10
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 ------------------*/
 
 /*!

+ 79 - 35
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

+ 25 - 11
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