4
0
mirror of https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32.git synced 2025-02-27 19:27:26 +08:00

1、【增加】FreeModbus主机请求支持同步等待功能,采用RT-Thread互斥锁事件同步机制

Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
armink 2014-01-07 23:39:56 +08:00
parent dfab58957d
commit 01a1f809cf
11 changed files with 97 additions and 56 deletions

View File

@ -35,7 +35,7 @@
#define RT_USING_SEMAPHORE
/* Using Mutex */
//#define RT_USING_MUTEX
#define RT_USING_MUTEX
/* Using Event */
//#define RT_USING_EVENT

View File

@ -49,15 +49,15 @@ void thread_entry_SysMonitor(void* parameter)
usModbusUserData[0] = (USHORT)(rt_tick_get()/10);
usModbusUserData[1] = (USHORT)(rt_tick_get()%10);
ucModbusUserData[0] = 0x1F;
eMBMasterReqReadDiscreteInputs(1,3,8);
// eMBMasterReqWriteMultipleCoils(1,3,5,ucModbusUserData);
// eMBMasterReqWriteCoil(1,8,0xFF00);
// eMBMasterReqReadCoils(1,3,8);
// eMBMasterReqReadInputRegister(1,3,2);
// eMBMasterReqWriteHoldingRegister(1,3,usModbusUserData[0]);
// eMBMasterReqWriteMultipleHoldingRegister(1,3,2,usModbusUserData);
// eMBMasterReqReadHoldingRegister(1,3,2);
// eMBMasterReqReadWriteMultipleHoldingRegister(1,3,2,usModbusUserData,5,2);
eMBMasterReqReadDiscreteInputs(1,3,8,MB_WAITING_FOREVER);
// eMBMasterReqWriteMultipleCoils(1,3,5,ucModbusUserData,MB_WAITING_FOREVER);
// eMBMasterReqWriteCoil(1,8,0xFF00,MB_WAITING_FOREVER);
// eMBMasterReqReadCoils(1,3,8,MB_WAITING_FOREVER);
// eMBMasterReqReadInputRegister(1,3,2,MB_WAITING_FOREVER);
// eMBMasterReqWriteHoldingRegister(1,3,usModbusUserData[0],MB_WAITING_FOREVER);
// eMBMasterReqWriteMultipleHoldingRegister(1,3,2,usModbusUserData,MB_WAITING_FOREVER);
// eMBMasterReqReadHoldingRegister(1,3,2,MB_WAITING_FOREVER);
// eMBMasterReqReadWriteMultipleHoldingRegister(1,3,2,usModbusUserData,5,2,MB_WAITING_FOREVER);
}
}

View File

@ -75,12 +75,12 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
#if MB_FUNC_READ_COILS_ENABLED > 0
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{
@ -162,12 +162,12 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_WRITE_COIL_ENABLED > 0
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
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
@ -242,14 +242,14 @@ eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
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

View File

@ -60,12 +60,12 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{

View File

@ -87,12 +87,12 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{
@ -145,13 +145,13 @@ eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{
@ -228,12 +228,12 @@ eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_READ_HOLDING_ENABLED > 0
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{
@ -303,13 +303,13 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{

View File

@ -60,12 +60,12 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
#if MB_FUNC_READ_INPUT_ENABLED > 0
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;
if ( xMBasterRunMutexLock( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
else if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
else
{

View File

@ -338,26 +338,27 @@ eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress,
*\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 );
@ -383,11 +384,9 @@ 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 );

View File

@ -36,6 +36,16 @@
PR_BEGIN_EXTERN_C
#endif
/* ----------------------- Defines ------------------------------------------*/
/*! \ingroup modbus
* \brief used for master mode.
*
* the mxMBasterRunMutexLock() parameter definitions
*/
#define MB_WAITING_FOREVER -1 /*!< Block forever until get resource. */
#define MB_WAITING_NO 0 /*!< Non-block. */
/* ----------------------- Type definitions ---------------------------------*/
typedef enum
@ -82,6 +92,12 @@ BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
void vMBasterRunMutexInit( void );
BOOL xMBasterRunMutexLock( int32_t time );
void vMBasterRunMutexUnlock( void );
/* ----------------------- Serial port functions ----------------------------*/
BOOL xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
@ -97,7 +113,6 @@ INLINE BOOL xMBPortSerialGetByte( CHAR * pucByte );
INLINE BOOL xMBPortSerialPutByte( CHAR ucByte );
BOOL xMBMasterPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
UCHAR ucDataBits, eMBParity eParity );

View File

@ -65,7 +65,6 @@
static UCHAR ucMBMasterDestAddress;
static BOOL xMBRunInMasterMode = FALSE;
static BOOL xMasterIsBusy = FALSE;
static enum
{
@ -185,6 +184,8 @@ eMBMasterInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity
{
eMBState = STATE_DISABLED;
}
/* initialize the Mobus Master mutex */
vMBasterRunMutexInit();
}
return eStatus;
}
@ -318,33 +319,23 @@ eMBMasterPoll( void )
}
/* 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 );
else vMBasterRunMutexUnlock();
break;
case EV_MASTER_FRAME_SENT:
/* Master is busy now. */
vMBMasterSetIsBusy( TRUE );
vMBMasterGetPDUSndBuf( &ucMBFrame );
eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, ucMBMasterGetPDUSndLength() );
break;
case EV_MASTER_ERROR_PROCESS:
vMBMasterSetIsBusy( FALSE );
vMBasterRunMutexUnlock();
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 )
{

View File

@ -393,7 +393,7 @@ xMBMasterRTUTimerExpired(void)
vMBMasterPortTimersDisable( );
/* If timer mode is convert delay ,then Master is idel now. */
if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) vMBMasterSetIsBusy( FALSE );
if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) vMBasterRunMutexUnlock();
return xNeedPoll;
}

View File

@ -22,11 +22,13 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "port.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
/* ----------------------- Variables ----------------------------------------*/
static eMBMasterEventType eMasterQueuedEvent;
static BOOL xMasterEventInQueue;
static BOOL xMasterEventInQueue;
static struct rt_mutex xMasterRunMutex;
/* ----------------------- Start implementation -----------------------------*/
BOOL
@ -58,4 +60,38 @@ xMBMasterPortEventGet( eMBMasterEventType * eEvent )
return xEventHappened;
}
/**
* This function is initialize the Mobus Master mutex .
* Note:The mutex is define by Operating System.If you not use Opearting System this function can be empty.
*
*/
void vMBasterRunMutexInit( void )
{
rt_mutex_init(&xMasterRunMutex, "master run", RT_IPC_FLAG_PRIO);
}
/**
* This function is lock Mobus Master mutex.
* Note:The mutex is define by Operating System.If you not use Opearting System this function can be just return TRUE.
*
* @param lTimeOut the waiting time.
*
* @return mutex lock result
*/
BOOL xMBasterRunMutexLock( LONG lTimeOut )
{
/*If waiting time is -1 .It will wait forever */
return rt_mutex_take(&xMasterRunMutex, lTimeOut) ? FALSE : TRUE ;
}
/**
* This function is unlock Mobus Master mutex.
* Note:The mutex is define by Operating System.If you not use Opearting System this function can be empty.
*
*/
void vMBasterRunMutexUnlock( void )
{
rt_mutex_release(&xMasterRunMutex);
}
#endif