[modbus]update modbus master and slave source code to lastest.
This commit is contained in:
parent
204298c1b2
commit
d8bbb5f126
|
@ -74,14 +74,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
|
||||||
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
||||||
#if MB_FUNC_READ_COILS_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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils )
|
eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils ,LONG lTimeOut )
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -93,6 +103,8 @@ eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils )
|
||||||
ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF + 1] = usNCoils;
|
ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF + 1] = usNCoils;
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
|
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +120,12 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
|
||||||
eMBException eStatus = MB_EX_NONE;
|
eMBException eStatus = MB_EX_NONE;
|
||||||
eMBErrorCode eRegStatus;
|
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);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
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] ) )
|
( ucByteCount == pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] ) )
|
||||||
{
|
{
|
||||||
/* Make callback to fill the buffer. */
|
/* 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 an error occured convert it into a Modbus exception. */
|
||||||
if( eRegStatus != MB_ENOERR )
|
if( eRegStatus != MB_ENOERR )
|
||||||
|
@ -161,15 +178,27 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
|
||||||
|
|
||||||
#if MB_FUNC_WRITE_COIL_ENABLED > 0
|
#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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData )
|
eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LONG lTimeOut )
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( usCoilAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else 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 ( ( usCoilData != 0xFF00 ) && ( usCoilData != 0x0000 ) ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -181,6 +210,7 @@ eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData )
|
||||||
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usCoilData;
|
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usCoilData;
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +244,7 @@ eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
|
||||||
ucBuf[0] = 0;
|
ucBuf[0] = 0;
|
||||||
}
|
}
|
||||||
eRegStatus =
|
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 an error occured convert it into a Modbus exception. */
|
||||||
if( eRegStatus != MB_ENOERR )
|
if( eRegStatus != MB_ENOERR )
|
||||||
|
@ -240,18 +270,31 @@ eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
|
||||||
|
|
||||||
#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
|
#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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
||||||
USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer )
|
USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer, LONG lTimeOut)
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
USHORT usRegIndex = 0;
|
USHORT usRegIndex = 0;
|
||||||
UCHAR ucByteCount;
|
UCHAR ucByteCount;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else 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 ( usNCoils > MB_PDU_REQ_WRITE_MUL_COILCNT_MAX ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -277,6 +320,7 @@ eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
||||||
}
|
}
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + ucByteCount );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + ucByteCount );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +337,8 @@ eMBMasterFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
|
||||||
eMBException eStatus = MB_EX_NONE;
|
eMBException eStatus = MB_EX_NONE;
|
||||||
eMBErrorCode eRegStatus;
|
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);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
|
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 ) )
|
if( ( usCoilCnt >= 1 ) && ( ucByteCountVerify == ucByteCount ) )
|
||||||
{
|
{
|
||||||
eRegStatus =
|
eRegStatus =
|
||||||
eMBRegCoilsCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
|
eMBMasterRegCoilsCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
|
||||||
usRegAddress, usCoilCnt, MB_REG_WRITE );
|
usRegAddress, usCoilCnt, MB_REG_WRITE );
|
||||||
|
|
||||||
/* If an error occured convert it into a Modbus exception. */
|
/* If an error occured convert it into a Modbus exception. */
|
||||||
|
|
|
@ -57,16 +57,26 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
|
||||||
|
|
||||||
/* ----------------------- Start implementation -----------------------------*/
|
/* ----------------------- Start implementation -----------------------------*/
|
||||||
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
#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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn )
|
eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut )
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -78,6 +88,7 @@ eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT u
|
||||||
ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF + 1] = usNDiscreteIn;
|
ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF + 1] = usNDiscreteIn;
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +104,12 @@ eMBMasterFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )
|
||||||
eMBException eStatus = MB_EX_NONE;
|
eMBException eStatus = MB_EX_NONE;
|
||||||
eMBErrorCode eRegStatus;
|
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);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
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])
|
if ((usDiscreteCnt >= 1) && ucNBytes == pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF])
|
||||||
{
|
{
|
||||||
/* Make callback to fill the buffer. */
|
/* 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 an error occured convert it into a Modbus exception. */
|
||||||
if( eRegStatus != MB_ENOERR )
|
if( eRegStatus != MB_ENOERR )
|
||||||
|
|
|
@ -86,14 +86,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
|
||||||
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
||||||
#if MB_FUNC_WRITE_HOLDING_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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData )
|
eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut )
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -105,6 +115,7 @@ eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRe
|
||||||
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usRegData ;
|
ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usRegData ;
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -123,7 +134,7 @@ eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
usRegAddress++;
|
usRegAddress++;
|
||||||
|
|
||||||
/* Make callback to update the value. */
|
/* 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 );
|
usRegAddress, 1, MB_REG_WRITE );
|
||||||
|
|
||||||
/* If an error occured convert it into a Modbus exception. */
|
/* 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
|
#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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
||||||
USHORT usRegAddr, USHORT usNRegs, USHORT * pusDataBuffer )
|
USHORT usRegAddr, USHORT usNRegs, USHORT * pusDataBuffer, LONG lTimeOut )
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
USHORT usRegIndex = 0;
|
USHORT usRegIndex = 0;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -171,6 +193,7 @@ eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
||||||
}
|
}
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + 2*usNRegs );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + 2*usNRegs );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +209,8 @@ eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
eMBException eStatus = MB_EX_NONE;
|
eMBException eStatus = MB_EX_NONE;
|
||||||
eMBErrorCode eRegStatus;
|
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);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_WRITE_MUL_ADDR_OFF] << 8 );
|
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. */
|
/* Make callback to update the register values. */
|
||||||
eRegStatus =
|
eRegStatus =
|
||||||
eMBRegHoldingCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
|
eMBMasterRegHoldingCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
|
||||||
usRegAddress, usRegCount, MB_REG_WRITE );
|
usRegAddress, usRegCount, MB_REG_WRITE );
|
||||||
|
|
||||||
/* If an error occured convert it into a Modbus exception. */
|
/* 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
|
#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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs )
|
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut )
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -246,6 +280,7 @@ eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRe
|
||||||
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
|
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +295,12 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
eMBException eStatus = MB_EX_NONE;
|
eMBException eStatus = MB_EX_NONE;
|
||||||
eMBErrorCode eRegStatus;
|
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);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
||||||
|
@ -268,7 +308,7 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
usRegAddress++;
|
usRegAddress++;
|
||||||
|
|
||||||
usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] << 8 );
|
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
|
/* Check if the number of registers to read is valid. If not
|
||||||
* return Modbus illegal data value exception.
|
* 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] ) )
|
if( ( usRegCount >= 1 ) && ( 2 * usRegCount == pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ) )
|
||||||
{
|
{
|
||||||
/* Make callback to fill the buffer. */
|
/* 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 an error occured convert it into a Modbus exception. */
|
||||||
if( eRegStatus != MB_ENOERR )
|
if( eRegStatus != MB_ENOERR )
|
||||||
{
|
{
|
||||||
|
@ -300,17 +340,30 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
|
|
||||||
#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
|
#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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
||||||
USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
|
USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
|
||||||
USHORT usWriteRegAddr, USHORT usNWriteRegs )
|
USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut )
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
USHORT usRegIndex = 0;
|
USHORT usRegIndex = 0;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -333,6 +386,7 @@ eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
||||||
}
|
}
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READWRITE_SIZE_MIN + 2*usNWriteRegs );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READWRITE_SIZE_MIN + 2*usNWriteRegs );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -349,7 +403,12 @@ eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen
|
||||||
eMBException eStatus = MB_EX_NONE;
|
eMBException eStatus = MB_EX_NONE;
|
||||||
eMBErrorCode eRegStatus;
|
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);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
usRegReadAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_READ_ADDR_OFF] << 8U );
|
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] )
|
if( ( 2 * usRegReadCount ) == pucFrame[MB_PDU_FUNC_READWRITE_READ_BYTECNT_OFF] )
|
||||||
{
|
{
|
||||||
/* Make callback to update the register values. */
|
/* 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 );
|
usRegWriteAddress, usRegWriteCount, MB_REG_WRITE );
|
||||||
|
|
||||||
if( eRegStatus == MB_ENOERR )
|
if( eRegStatus == MB_ENOERR )
|
||||||
{
|
{
|
||||||
/* Make the read callback. */
|
/* 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);
|
usRegReadAddress, usRegReadCount, MB_REG_READ);
|
||||||
}
|
}
|
||||||
if( eRegStatus != MB_ENOERR )
|
if( eRegStatus != MB_ENOERR )
|
||||||
|
|
|
@ -59,14 +59,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
|
||||||
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
|
||||||
#if MB_FUNC_READ_INPUT_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
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs )
|
eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut )
|
||||||
{
|
{
|
||||||
UCHAR *ucMBFrame;
|
UCHAR *ucMBFrame;
|
||||||
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
|
||||||
|
|
||||||
if ( xMBMasterGetIsBusy() ) eErrStatus = MB_MRE_MASTER_BUSY;
|
if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
||||||
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
|
else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
|
@ -78,6 +88,7 @@ eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs
|
||||||
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
|
ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
|
||||||
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
|
eErrStatus = eMBMasterWaitRequestFinish( );
|
||||||
}
|
}
|
||||||
return eErrStatus;
|
return eErrStatus;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +103,12 @@ eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
eMBException eStatus = MB_EX_NONE;
|
eMBException eStatus = MB_EX_NONE;
|
||||||
eMBErrorCode eRegStatus;
|
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);
|
vMBMasterGetPDUSndBuf(&ucMBFrame);
|
||||||
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
|
||||||
|
@ -100,7 +116,7 @@ eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
|
||||||
usRegAddress++;
|
usRegAddress++;
|
||||||
|
|
||||||
usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] << 8 );
|
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
|
/* Check if the number of registers to read is valid. If not
|
||||||
* return Modbus illegal data value exception.
|
* 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] ) )
|
if( ( usRegCount >= 1 ) && ( 2 * usRegCount == pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ) )
|
||||||
{
|
{
|
||||||
/* Make callback to fill the buffer. */
|
/* 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 an error occured convert it into a Modbus exception. */
|
||||||
if( eRegStatus != MB_ENOERR )
|
if( eRegStatus != MB_ENOERR )
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,13 +77,10 @@ typedef enum
|
||||||
MB_MRE_NO_ERR, /*!< no error. */
|
MB_MRE_NO_ERR, /*!< no error. */
|
||||||
MB_MRE_NO_REG, /*!< illegal register address. */
|
MB_MRE_NO_REG, /*!< illegal register address. */
|
||||||
MB_MRE_ILL_ARG, /*!< illegal argument. */
|
MB_MRE_ILL_ARG, /*!< illegal argument. */
|
||||||
MB_MRE_PORT_ERR, /*!< porting layer error. */
|
MB_MRE_REV_DATA, /*!< receive data error. */
|
||||||
MB_MRE_NO_RES, /*!< insufficient resources. */
|
|
||||||
MB_MRE_IO, /*!< I/O error. */
|
|
||||||
MB_MRE_ILL_STATE, /*!< protocol stack in illegal state. */
|
|
||||||
MB_MRE_TIMEDOUT, /*!< timeout error occurred. */
|
MB_MRE_TIMEDOUT, /*!< timeout error occurred. */
|
||||||
MB_MRE_MASTER_BUSY, /*!< master is busy now. */
|
MB_MRE_MASTER_BUSY, /*!< master is busy now. */
|
||||||
MB_MRE_SLAVE_EXCE /*!< slave has exception. */
|
MB_MRE_EXE_FUN /*!< execute function error. */
|
||||||
} eMBMasterReqErrCode;
|
} eMBMasterReqErrCode;
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
* \brief TimerMode is Master 3 kind of Timer modes.
|
* \brief TimerMode is Master 3 kind of Timer modes.
|
||||||
|
@ -189,31 +186,176 @@ eMBErrorCode eMBMasterDisable( void );
|
||||||
*/
|
*/
|
||||||
eMBErrorCode eMBMasterPoll( 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
|
/*! \ingroup modbus
|
||||||
*\brief These Modbus functions are called for user when Modbus run in Master Mode.
|
*\brief These Modbus functions are called for user when Modbus run in Master Mode.
|
||||||
*/
|
*/
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs );
|
eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData );
|
eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, USHORT * pusDataBuffer );
|
eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr,
|
||||||
|
USHORT usNRegs, USHORT * pusDataBuffer, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs );
|
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
|
||||||
USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
|
USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
|
||||||
USHORT usWriteRegAddr, USHORT usNWriteRegs );
|
USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils );
|
eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData );
|
eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
|
||||||
USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer );
|
USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer, LONG lTimeOut );
|
||||||
eMBMasterReqErrCode
|
eMBMasterReqErrCode
|
||||||
eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn );
|
eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut );
|
||||||
|
|
||||||
eMBException
|
eMBException
|
||||||
eMBMasterFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen );
|
eMBMasterFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen );
|
||||||
|
@ -239,16 +381,18 @@ eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen
|
||||||
/*£¡ \ingroup modbus
|
/*£¡ \ingroup modbus
|
||||||
*\brief These functions are interface for Modbus Master
|
*\brief These functions are interface for Modbus Master
|
||||||
*/
|
*/
|
||||||
BOOL xMBMasterGetIsBusy( void );
|
|
||||||
void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame );
|
void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame );
|
||||||
UCHAR ucMBMasterGetDestAddress( void );
|
UCHAR ucMBMasterGetDestAddress( void );
|
||||||
void vMBMasterSetDestAddress( UCHAR Address );
|
void vMBMasterSetDestAddress( UCHAR Address );
|
||||||
void vMBMasterSetIsBusy( BOOL IsBusy );
|
|
||||||
BOOL xMBMasterGetCBRunInMasterMode( void );
|
BOOL xMBMasterGetCBRunInMasterMode( void );
|
||||||
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode );
|
void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode );
|
||||||
UCHAR ucMBMasterGetPDUSndLength( void );
|
USHORT usMBMasterGetPDUSndLength( void );
|
||||||
void vMBMasterSetPDUSndLength( UCHAR SendPDULength );
|
void vMBMasterSetPDUSndLength( USHORT SendPDULength );
|
||||||
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode );
|
void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode );
|
||||||
|
BOOL xMBMasterRequestIsBroadcast( void );
|
||||||
|
eMBMasterErrorEventType eMBMasterGetErrorType( void );
|
||||||
|
void vMBMasterSetErrorType( eMBMasterErrorEventType errorType );
|
||||||
|
eMBMasterReqErrCode eMBMasterWaitRequestFinish( void );
|
||||||
|
|
||||||
/* ----------------------- Callback -----------------------------------------*/
|
/* ----------------------- Callback -----------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -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.
|
/*! \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.
|
* And if slave is not respond in this time,the master will process this timeout error.
|
||||||
* Then master can send other frame */
|
* Then master can send other frame */
|
||||||
#define MB_MASTER_TIMEOUT_MS_RESPOND (2000)
|
#define MB_MASTER_TIMEOUT_MS_RESPOND (100 )
|
||||||
/*! \brief The total slaves in Modbus Master system. Default 16.
|
/*! \brief The total slaves in Modbus Master system. Default 16.
|
||||||
* Note : The slave ID must be continuous from 0.*/
|
* \note : The slave ID must be continuous from 1.*/
|
||||||
#define MB_MASTER_TOTAL_SLAVE_NUM ( 16 )
|
#define MB_MASTER_TOTAL_SLAVE_NUM ( 16 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -36,25 +36,38 @@
|
||||||
PR_BEGIN_EXTERN_C
|
PR_BEGIN_EXTERN_C
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ----------------------- Defines ------------------------------------------*/
|
||||||
|
|
||||||
/* ----------------------- Type definitions ---------------------------------*/
|
/* ----------------------- Type definitions ---------------------------------*/
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
EV_READY, /*!< Startup finished. */
|
EV_READY = 1<<0, /*!< Startup finished. */
|
||||||
EV_FRAME_RECEIVED, /*!< Frame received. */
|
EV_FRAME_RECEIVED = 1<<1, /*!< Frame received. */
|
||||||
EV_EXECUTE, /*!< Execute function. */
|
EV_EXECUTE = 1<<2, /*!< Execute function. */
|
||||||
EV_FRAME_SENT /*!< Frame sent. */
|
EV_FRAME_SENT = 1<<3 /*!< Frame sent. */
|
||||||
} eMBEventType;
|
} eMBEventType;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
EV_MASTER_READY, /*!< Startup finished. */
|
EV_MASTER_READY = 1<<0, /*!< Startup finished. */
|
||||||
EV_MASTER_FRAME_RECEIVED, /*!< Frame received. */
|
EV_MASTER_FRAME_RECEIVED = 1<<1, /*!< Frame received. */
|
||||||
EV_MASTER_EXECUTE, /*!< Execute function. */
|
EV_MASTER_EXECUTE = 1<<2, /*!< Execute function. */
|
||||||
EV_MASTER_FRAME_SENT, /*!< Frame sent. */
|
EV_MASTER_FRAME_SENT = 1<<3, /*!< Frame sent. */
|
||||||
EV_MASTER_ERROR_PROCESS /*!< Frame error process*/
|
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;
|
} 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
|
/*! \ingroup modbus
|
||||||
* \brief Parity used for characters in serial mode.
|
* \brief Parity used for characters in serial mode.
|
||||||
*
|
*
|
||||||
|
@ -82,6 +95,12 @@ BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
|
||||||
|
|
||||||
BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
|
BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
|
||||||
|
|
||||||
|
void vMBMasterOsResInit( void );
|
||||||
|
|
||||||
|
BOOL xMBMasterRunResTake( int32_t time );
|
||||||
|
|
||||||
|
void vMBMasterRunResRelease( void );
|
||||||
|
|
||||||
/* ----------------------- Serial port functions ----------------------------*/
|
/* ----------------------- Serial port functions ----------------------------*/
|
||||||
|
|
||||||
BOOL xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
|
BOOL xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
|
||||||
|
@ -97,7 +116,6 @@ INLINE BOOL xMBPortSerialGetByte( CHAR * pucByte );
|
||||||
|
|
||||||
INLINE BOOL xMBPortSerialPutByte( CHAR ucByte );
|
INLINE BOOL xMBPortSerialPutByte( CHAR ucByte );
|
||||||
|
|
||||||
|
|
||||||
BOOL xMBMasterPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
|
BOOL xMBMasterPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
|
||||||
UCHAR ucDataBits, eMBParity eParity );
|
UCHAR ucDataBits, eMBParity eParity );
|
||||||
|
|
||||||
|
@ -132,6 +150,18 @@ INLINE void vMBMasterPortTimersRespondTimeoutEnable( void );
|
||||||
|
|
||||||
INLINE void vMBMasterPortTimersDisable( 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 ------------------*/
|
/* ----------------------- Callback for the protocol stack ------------------*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
|
|
||||||
static UCHAR ucMBMasterDestAddress;
|
static UCHAR ucMBMasterDestAddress;
|
||||||
static BOOL xMBRunInMasterMode = FALSE;
|
static BOOL xMBRunInMasterMode = FALSE;
|
||||||
static BOOL xMasterIsBusy = FALSE;
|
static eMBMasterErrorEventType eMBMasterCurErrorType;
|
||||||
|
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
|
@ -185,6 +185,8 @@ eMBMasterInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity
|
||||||
{
|
{
|
||||||
eMBState = STATE_DISABLED;
|
eMBState = STATE_DISABLED;
|
||||||
}
|
}
|
||||||
|
/* initialize the OS resource for modbus master. */
|
||||||
|
vMBMasterOsResInit();
|
||||||
}
|
}
|
||||||
return eStatus;
|
return eStatus;
|
||||||
}
|
}
|
||||||
|
@ -257,9 +259,10 @@ eMBMasterPoll( void )
|
||||||
static USHORT usLength;
|
static USHORT usLength;
|
||||||
static eMBException eException;
|
static eMBException eException;
|
||||||
|
|
||||||
int i;
|
int i , j;
|
||||||
eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
eMBMasterEventType eEvent;
|
eMBMasterEventType eEvent;
|
||||||
|
eMBMasterErrorEventType errorType;
|
||||||
|
|
||||||
/* Check if the protocol stack is ready. */
|
/* Check if the protocol stack is ready. */
|
||||||
if( eMBState != STATE_ENABLED )
|
if( eMBState != STATE_ENABLED )
|
||||||
|
@ -285,6 +288,7 @@ eMBMasterPoll( void )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||||
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -292,52 +296,80 @@ eMBMasterPoll( void )
|
||||||
case EV_MASTER_EXECUTE:
|
case EV_MASTER_EXECUTE:
|
||||||
ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
|
ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
|
||||||
eException = MB_EX_ILLEGAL_FUNCTION;
|
eException = MB_EX_ILLEGAL_FUNCTION;
|
||||||
|
/* If receive frame has exception .The receive function code highest bit is 1.*/
|
||||||
|
if(ucFunctionCode >> 7) {
|
||||||
|
eException = (eMBException)ucMBFrame[MB_PDU_DATA_OFF];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (i = 0; i < MB_FUNC_HANDLERS_MAX; i++)
|
for (i = 0; i < MB_FUNC_HANDLERS_MAX; i++)
|
||||||
{
|
{
|
||||||
/* No more function handlers registered. Abort. */
|
/* No more function handlers registered. Abort. */
|
||||||
if( xMasterFuncHandlers[i].ucFunctionCode == 0 )
|
if (xMasterFuncHandlers[i].ucFunctionCode == 0) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if( xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode )
|
else if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode) {
|
||||||
{
|
|
||||||
vMBMasterSetCBRunInMasterMode(TRUE);
|
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);
|
eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
|
||||||
|
}
|
||||||
vMBMasterSetCBRunInMasterMode(FALSE);
|
vMBMasterSetCBRunInMasterMode(FALSE);
|
||||||
break;
|
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 master has exception ,Master will send error process.Otherwise the Master is idle.*/
|
/* 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 );
|
if (eException != MB_EX_NONE) {
|
||||||
else vMBMasterSetIsBusy( FALSE );
|
vMBMasterSetErrorType(EV_ERROR_EXECUTE_FUNCTION);
|
||||||
|
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vMBMasterCBRequestScuuess( );
|
||||||
|
vMBMasterRunResRelease( );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_MASTER_FRAME_SENT:
|
case EV_MASTER_FRAME_SENT:
|
||||||
/* Master is busy now. */
|
/* Master is busy now. */
|
||||||
vMBMasterSetIsBusy( TRUE );
|
|
||||||
vMBMasterGetPDUSndBuf( &ucMBFrame );
|
vMBMasterGetPDUSndBuf( &ucMBFrame );
|
||||||
eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, ucMBMasterGetPDUSndLength() );
|
eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, usMBMasterGetPDUSndLength() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EV_MASTER_ERROR_PROCESS:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MB_ENOERR;
|
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.*/
|
/* Get whether the Modbus Master is run in master mode.*/
|
||||||
BOOL xMBMasterGetCBRunInMasterMode( void )
|
BOOL xMBMasterGetCBRunInMasterMode( void )
|
||||||
{
|
{
|
||||||
|
@ -348,15 +380,27 @@ void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
|
||||||
{
|
{
|
||||||
xMBRunInMasterMode = IsMasterMode;
|
xMBRunInMasterMode = IsMasterMode;
|
||||||
}
|
}
|
||||||
/* Get Modbus Master send destination address*/
|
/* Get Modbus Master send destination address. */
|
||||||
UCHAR ucMBMasterGetDestAddress( void )
|
UCHAR ucMBMasterGetDestAddress( void )
|
||||||
{
|
{
|
||||||
return ucMBMasterDestAddress;
|
return ucMBMasterDestAddress;
|
||||||
}
|
}
|
||||||
/* Set Modbus Master send destination address*/
|
/* Set Modbus Master send destination address. */
|
||||||
void vMBMasterSetDestAddress( UCHAR Address )
|
void vMBMasterSetDestAddress( UCHAR Address )
|
||||||
{
|
{
|
||||||
ucMBMasterDestAddress = 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
|
#endif
|
||||||
|
|
|
@ -74,7 +74,7 @@ static volatile eMBMasterRcvState eRcvState;
|
||||||
|
|
||||||
static volatile UCHAR ucMasterRTUSndBuf[MB_PDU_SIZE_MAX];
|
static volatile UCHAR ucMasterRTUSndBuf[MB_PDU_SIZE_MAX];
|
||||||
static volatile UCHAR ucMasterRTURcvBuf[MB_SER_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 UCHAR *pucMasterSndBufferCur;
|
||||||
static volatile USHORT usMasterSndBufferCount;
|
static volatile USHORT usMasterSndBufferCount;
|
||||||
|
@ -235,7 +235,7 @@ xMBMasterRTUReceiveFSM( void )
|
||||||
BOOL xTaskNeedSwitch = FALSE;
|
BOOL xTaskNeedSwitch = FALSE;
|
||||||
UCHAR ucByte;
|
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. */
|
/* Always read the character. */
|
||||||
( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
|
( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
|
||||||
|
@ -364,12 +364,15 @@ xMBMasterRTUTimerExpired(void)
|
||||||
|
|
||||||
/* An error occured while receiving the frame. */
|
/* An error occured while receiving the frame. */
|
||||||
case STATE_M_RX_ERROR:
|
case STATE_M_RX_ERROR:
|
||||||
|
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||||
|
xNeedPoll = xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Function called in an illegal state. */
|
/* Function called in an illegal state. */
|
||||||
default:
|
default:
|
||||||
assert_param(
|
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;
|
break;
|
||||||
}
|
}
|
||||||
eRcvState = STATE_M_RX_IDLE;
|
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
|
* If the frame is broadcast,The master will idle,and if the frame is not
|
||||||
* broadcast.Notify the listener process error.*/
|
* broadcast.Notify the listener process error.*/
|
||||||
case STATE_M_TX_XFWR:
|
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;
|
break;
|
||||||
/* Function called in an illegal state. */
|
/* Function called in an illegal state. */
|
||||||
default:
|
default:
|
||||||
assert_param( eSndState == STATE_M_TX_XFWR );
|
assert_param(
|
||||||
|
( eSndState == STATE_M_TX_XFWR ) || ( eSndState == STATE_M_TX_IDLE ));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
eSndState = STATE_M_TX_IDLE;
|
eSndState = STATE_M_TX_IDLE;
|
||||||
|
|
||||||
vMBMasterPortTimersDisable( );
|
vMBMasterPortTimersDisable( );
|
||||||
/* If timer mode is convert delay ,then Master is idel now. */
|
/* If timer mode is convert delay, the master event then turns EV_MASTER_EXECUTE status. */
|
||||||
if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) vMBMasterSetIsBusy( FALSE );
|
if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) {
|
||||||
|
xNeedPoll = xMBMasterPortEventPost( EV_MASTER_EXECUTE );
|
||||||
|
}
|
||||||
|
|
||||||
return xNeedPoll;
|
return xNeedPoll;
|
||||||
}
|
}
|
||||||
|
@ -409,15 +418,15 @@ void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Modbus Master send PDU's buffer length.*/
|
/* 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.*/
|
/* Get Modbus Master send PDU's buffer length.*/
|
||||||
UCHAR ucMBMasterGetPDUSndLength( void )
|
USHORT usMBMasterGetPDUSndLength( void )
|
||||||
{
|
{
|
||||||
return ucMasterSendPDULength;
|
return usMasterSendPDULength;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Modbus Master current timer mode.*/
|
/* Set Modbus Master current timer mode.*/
|
||||||
|
@ -425,5 +434,10 @@ void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
|
||||||
{
|
{
|
||||||
eMasterCurTimerMode = eMBTimerMode;
|
eMasterCurTimerMode = eMBTimerMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The master request is broadcast? */
|
||||||
|
BOOL xMBMasterRequestIsBroadcast( void ){
|
||||||
|
return xFrameIsBroadcast;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue