1、【更新】《FreeModbus 主机分析图》中关于发送及接受状态图,其余还需后期完善;
2、【增加】FreeModbus主机传输层逻辑实现,稳定性还需后期测试; Signed-off-by: armink <armink.ztl@gmail.com>
This commit is contained in:
parent
31fab3ed4d
commit
dfe745c166
Binary file not shown.
|
@ -46,6 +46,15 @@ typedef enum
|
||||||
EV_FRAME_SENT /*!< Frame sent. */
|
EV_FRAME_SENT /*!< Frame sent. */
|
||||||
} eMBEventType;
|
} 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*/
|
||||||
|
} eMBMasterEventType;
|
||||||
|
|
||||||
/*! \ingroup modbus
|
/*! \ingroup modbus
|
||||||
* \brief Parity used for characters in serial mode.
|
* \brief Parity used for characters in serial mode.
|
||||||
*
|
*
|
||||||
|
@ -69,9 +78,9 @@ BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent );
|
||||||
|
|
||||||
BOOL xMBMasterPortEventInit( void );
|
BOOL xMBMasterPortEventInit( void );
|
||||||
|
|
||||||
BOOL xMBMasterPortEventPost( eMBEventType eEvent );
|
BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
|
||||||
|
|
||||||
BOOL xMBMasterPortEventGet( /*@out@ */ eMBEventType * eEvent );
|
BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
|
||||||
|
|
||||||
/* ----------------------- Serial port functions ----------------------------*/
|
/* ----------------------- Serial port functions ----------------------------*/
|
||||||
|
|
||||||
|
@ -100,7 +109,7 @@ void vMBMasterPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable );
|
||||||
|
|
||||||
INLINE BOOL xMBMasterPortSerialGetByte( CHAR * pucByte );
|
INLINE BOOL xMBMasterPortSerialGetByte( CHAR * pucByte );
|
||||||
|
|
||||||
INLINE BOOL xMBPortSerialPutByte( CHAR ucByte );
|
INLINE BOOL xMBMasterPortSerialPutByte( CHAR ucByte );
|
||||||
|
|
||||||
/* ----------------------- Timers functions ---------------------------------*/
|
/* ----------------------- Timers functions ---------------------------------*/
|
||||||
BOOL xMBPortTimersInit( USHORT usTimeOut50us );
|
BOOL xMBPortTimersInit( USHORT usTimeOut50us );
|
||||||
|
@ -115,7 +124,11 @@ BOOL xMBMasterPortTimersInit( USHORT usTimeOut50us );
|
||||||
|
|
||||||
void xMBMasterPortTimersClose( void );
|
void xMBMasterPortTimersClose( void );
|
||||||
|
|
||||||
INLINE void vMBMasterPortTimersEnable( void );
|
INLINE void vMBMasterPortTimersT35Enable( void );
|
||||||
|
|
||||||
|
INLINE void vMBMasterPortTimersConvertDelayEnable( void );
|
||||||
|
|
||||||
|
INLINE void vMBMasterPortTimersRespondTimeoutEnable( void );
|
||||||
|
|
||||||
INLINE void vMBMasterPortTimersDisable( void );
|
INLINE void vMBMasterPortTimersDisable( void );
|
||||||
|
|
||||||
|
|
|
@ -346,6 +346,7 @@ xMBRTUTimerT35Expired( void )
|
||||||
default:
|
default:
|
||||||
assert_param( ( eRcvState == STATE_RX_INIT ) ||
|
assert_param( ( eRcvState == STATE_RX_INIT ) ||
|
||||||
( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
|
( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vMBPortTimersDisable( );
|
vMBPortTimersDisable( );
|
||||||
|
|
|
@ -57,13 +57,14 @@ typedef enum
|
||||||
STATE_M_RX_INIT, /*!< Receiver is in initial state. */
|
STATE_M_RX_INIT, /*!< Receiver is in initial state. */
|
||||||
STATE_M_RX_IDLE, /*!< Receiver is in idle state. */
|
STATE_M_RX_IDLE, /*!< Receiver is in idle state. */
|
||||||
STATE_M_RX_RCV, /*!< Frame is beeing received. */
|
STATE_M_RX_RCV, /*!< Frame is beeing received. */
|
||||||
STATE_M_RX_ERROR /*!< If the frame is invalid. */
|
STATE_M_RX_ERROR, /*!< If the frame is invalid. */
|
||||||
} eMBMasterRcvState;
|
} eMBMasterRcvState;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
STATE_M_TX_IDLE, /*!< Transmitter is in idle state. */
|
STATE_M_TX_IDLE, /*!< Transmitter is in idle state. */
|
||||||
STATE_M_TX_XMIT, /*!< Transmitter is in transfer state. */
|
STATE_M_TX_XMIT, /*!< Transmitter is in transfer state. */
|
||||||
|
STATE_M_TX_XFWR, /*!< Transmitter is in transfer finish and wait receive state. */
|
||||||
} eMBMasterSndState;
|
} eMBMasterSndState;
|
||||||
|
|
||||||
/* ----------------------- Static variables ---------------------------------*/
|
/* ----------------------- Static variables ---------------------------------*/
|
||||||
|
@ -72,11 +73,11 @@ static volatile eMBMasterRcvState eRcvState;
|
||||||
|
|
||||||
volatile UCHAR ucMasterRTUBuf[MB_SER_PDU_SIZE_MAX];
|
volatile UCHAR ucMasterRTUBuf[MB_SER_PDU_SIZE_MAX];
|
||||||
|
|
||||||
static volatile UCHAR *pucSndBufferCur;
|
static volatile UCHAR *pucMasterSndBufferCur;
|
||||||
static volatile USHORT usSndBufferCount;
|
static volatile USHORT usMasterSndBufferCount;
|
||||||
|
|
||||||
static volatile USHORT usRcvBufferPos;
|
|
||||||
|
|
||||||
|
static volatile USHORT usMasterRcvBufferPos;
|
||||||
|
static volatile BOOL bFrameIsBroadcast = FALSE;
|
||||||
/* ----------------------- Start implementation -----------------------------*/
|
/* ----------------------- Start implementation -----------------------------*/
|
||||||
eMBErrorCode
|
eMBErrorCode
|
||||||
eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
|
eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
|
||||||
|
@ -133,7 +134,7 @@ eMBMasterRTUStart( void )
|
||||||
*/
|
*/
|
||||||
eRcvState = STATE_M_RX_INIT;
|
eRcvState = STATE_M_RX_INIT;
|
||||||
vMBMasterPortSerialEnable( TRUE, FALSE );
|
vMBMasterPortSerialEnable( TRUE, FALSE );
|
||||||
vMBMasterPortTimersEnable( );
|
vMBMasterPortTimersT35Enable( );
|
||||||
|
|
||||||
EXIT_CRITICAL_SECTION( );
|
EXIT_CRITICAL_SECTION( );
|
||||||
}
|
}
|
||||||
|
@ -147,179 +148,191 @@ eMBMasterRTUStop( void )
|
||||||
EXIT_CRITICAL_SECTION( );
|
EXIT_CRITICAL_SECTION( );
|
||||||
}
|
}
|
||||||
|
|
||||||
//eMBErrorCode
|
eMBErrorCode
|
||||||
//eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
|
||||||
//{
|
{
|
||||||
// BOOL xFrameReceived = FALSE;
|
BOOL xFrameReceived = FALSE;
|
||||||
// eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
//
|
|
||||||
// ENTER_CRITICAL_SECTION( );
|
ENTER_CRITICAL_SECTION( );
|
||||||
// assert_param( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
|
assert_param( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
|
||||||
//
|
|
||||||
// /* Length and CRC check */
|
/* Length and CRC check */
|
||||||
// if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
|
if( ( usMasterRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
|
||||||
// && ( usMBCRC16( ( UCHAR * ) ucMasterRTUBuf, usRcvBufferPos ) == 0 ) )
|
&& ( usMBCRC16( ( UCHAR * ) ucMasterRTUBuf, usMasterRcvBufferPos ) == 0 ) )
|
||||||
// {
|
{
|
||||||
// /* Save the address field. All frames are passed to the upper layed
|
/* Save the address field. All frames are passed to the upper layed
|
||||||
// * and the decision if a frame is used is done there.
|
* and the decision if a frame is used is done there.
|
||||||
// */
|
*/
|
||||||
// *pucRcvAddress = ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF];
|
*pucRcvAddress = ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF];
|
||||||
//
|
|
||||||
// /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
/* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
|
||||||
// * size of address field and CRC checksum.
|
* size of address field and CRC checksum.
|
||||||
// */
|
*/
|
||||||
// *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
|
*pusLength = ( USHORT )( usMasterRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
|
||||||
//
|
|
||||||
// /* Return the start of the Modbus PDU to the caller. */
|
/* Return the start of the Modbus PDU to the caller. */
|
||||||
// *pucFrame = ( UCHAR * ) & ucMasterRTUBuf[MB_SER_PDU_PDU_OFF];
|
*pucFrame = ( UCHAR * ) & ucMasterRTUBuf[MB_SER_PDU_PDU_OFF];
|
||||||
// xFrameReceived = TRUE;
|
xFrameReceived = TRUE;
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// {
|
{
|
||||||
// eStatus = MB_EIO;
|
eStatus = MB_EIO;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// EXIT_CRITICAL_SECTION( );
|
EXIT_CRITICAL_SECTION( );
|
||||||
// return eStatus;
|
return eStatus;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//eMBErrorCode
|
eMBErrorCode
|
||||||
//eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
|
eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
|
||||||
//{
|
{
|
||||||
// eMBErrorCode eStatus = MB_ENOERR;
|
eMBErrorCode eStatus = MB_ENOERR;
|
||||||
// USHORT usCRC16;
|
USHORT usCRC16;
|
||||||
//
|
|
||||||
// ENTER_CRITICAL_SECTION( );
|
ENTER_CRITICAL_SECTION( );
|
||||||
//
|
|
||||||
// /* Check if the receiver is still in idle state. If not we where to
|
/* Check if the receiver is still in idle state. If not we where to
|
||||||
// * slow with processing the received frame and the master sent another
|
* slow with processing the received frame and the master sent another
|
||||||
// * frame on the network. We have to abort sending the frame.
|
* frame on the network. We have to abort sending the frame.
|
||||||
// */
|
*/
|
||||||
// if( eRcvState == STATE_M_RX_IDLE )
|
if( eRcvState == STATE_M_RX_IDLE )
|
||||||
// {
|
{
|
||||||
// /* First byte before the Modbus-PDU is the slave address. */
|
/* First byte before the Modbus-PDU is the slave address. */
|
||||||
// pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
|
||||||
// usSndBufferCount = 1;
|
usMasterSndBufferCount = 1;
|
||||||
//
|
|
||||||
// /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
|
/* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
|
||||||
// pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
|
pucMasterSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
|
||||||
// usSndBufferCount += usLength;
|
usMasterSndBufferCount += usLength;
|
||||||
//
|
|
||||||
// /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
|
/* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
|
||||||
// usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
|
usCRC16 = usMBCRC16( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
|
||||||
// ucMasterRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
|
ucMasterRTUBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
|
||||||
// ucMasterRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
|
ucMasterRTUBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
|
||||||
//
|
|
||||||
// /* Activate the transmitter. */
|
/* Activate the transmitter. */
|
||||||
// eSndState = STATE_M_TX_XMIT;
|
eSndState = STATE_M_TX_XMIT;
|
||||||
// vMBMasterPortSerialEnable( FALSE, TRUE );
|
vMBMasterPortSerialEnable( FALSE, TRUE );
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// {
|
{
|
||||||
// eStatus = MB_EIO;
|
eStatus = MB_EIO;
|
||||||
// }
|
}
|
||||||
// EXIT_CRITICAL_SECTION( );
|
EXIT_CRITICAL_SECTION( );
|
||||||
// return eStatus;
|
return eStatus;
|
||||||
//}
|
}
|
||||||
//
|
|
||||||
//BOOL
|
BOOL
|
||||||
//xMBMasterRTUReceiveFSM( void )
|
xMBMasterRTUReceiveFSM( void )
|
||||||
//{
|
{
|
||||||
// BOOL xTaskNeedSwitch = FALSE;
|
BOOL xTaskNeedSwitch = FALSE;
|
||||||
// UCHAR ucByte;
|
UCHAR ucByte;
|
||||||
//
|
|
||||||
// assert_param( eSndState == STATE_TX_IDLE );
|
assert_param( eSndState == STATE_TX_IDLE );
|
||||||
//
|
|
||||||
// /* Always read the character. */
|
/* Always read the character. */
|
||||||
// ( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
|
( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
|
||||||
//
|
|
||||||
// switch ( eRcvState )
|
switch ( eRcvState )
|
||||||
// {
|
{
|
||||||
// /* If we have received a character in the init state we have to
|
/* If we have received a character in the init state we have to
|
||||||
// * wait until the frame is finished.
|
* wait until the frame is finished.
|
||||||
// */
|
*/
|
||||||
// case STATE_RX_INIT:
|
case STATE_M_RX_INIT:
|
||||||
// vMBMasterPortTimersEnable( );
|
vMBMasterPortTimersT35Enable( );
|
||||||
// break;
|
break;
|
||||||
//
|
|
||||||
// /* In the error state we wait until all characters in the
|
/* In the error state we wait until all characters in the
|
||||||
// * damaged frame are transmitted.
|
* damaged frame are transmitted.
|
||||||
// */
|
*/
|
||||||
// case STATE_RX_ERROR:
|
case STATE_M_RX_ERROR:
|
||||||
// vMBMasterPortTimersEnable( );
|
vMBMasterPortTimersT35Enable( );
|
||||||
// break;
|
break;
|
||||||
//
|
|
||||||
// /* In the idle state we wait for a new character. If a character
|
/* In the idle state we wait for a new character. If a character
|
||||||
// * is received the t1.5 and t3.5 timers are started and the
|
* is received the t1.5 and t3.5 timers are started and the
|
||||||
// * receiver is in the state STATE_RX_RECEIVCE.
|
* receiver is in the state STATE_RX_RECEIVCE and disable early
|
||||||
// */
|
* the timer of respond timeout .
|
||||||
// case STATE_M_RX_IDLE:
|
*/
|
||||||
// usRcvBufferPos = 0;
|
case STATE_M_RX_IDLE:
|
||||||
// ucMasterRTUBuf[usRcvBufferPos++] = ucByte;
|
/* In time of respond timeout,the receiver receive a frame.
|
||||||
// eRcvState = STATE_M_RX_RCV;
|
* Disable timer of respond timeout and change the transmiter state to idle.
|
||||||
//
|
*/
|
||||||
// /* Enable t3.5 timers. */
|
vMBMasterPortTimersDisable( );
|
||||||
// vMBMasterPortTimersEnable( );
|
eSndState = STATE_M_TX_IDLE;
|
||||||
// break;
|
|
||||||
//
|
usMasterRcvBufferPos = 0;
|
||||||
// /* We are currently receiving a frame. Reset the timer after
|
ucMasterRTUBuf[usMasterRcvBufferPos++] = ucByte;
|
||||||
// * every character received. If more than the maximum possible
|
eRcvState = STATE_M_RX_RCV;
|
||||||
// * number of bytes in a modbus frame is received the frame is
|
|
||||||
// * ignored.
|
/* Enable t3.5 timers. */
|
||||||
// */
|
vMBMasterPortTimersT35Enable( );
|
||||||
// case STATE_M_RX_RCV:
|
break;
|
||||||
// if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
|
|
||||||
// {
|
/* We are currently receiving a frame. Reset the timer after
|
||||||
// ucMasterRTUBuf[usRcvBufferPos++] = ucByte;
|
* every character received. If more than the maximum possible
|
||||||
// }
|
* number of bytes in a modbus frame is received the frame is
|
||||||
// else
|
* ignored.
|
||||||
// {
|
*/
|
||||||
// eRcvState = STATE_RX_ERROR;
|
case STATE_M_RX_RCV:
|
||||||
// }
|
if( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX )
|
||||||
// vMBMasterPortTimersEnable();
|
{
|
||||||
// break;
|
ucMasterRTUBuf[usMasterRcvBufferPos++] = ucByte;
|
||||||
// }
|
}
|
||||||
// return xTaskNeedSwitch;
|
else
|
||||||
//}
|
{
|
||||||
//
|
eRcvState = STATE_M_RX_ERROR;
|
||||||
//BOOL
|
}
|
||||||
//xMBMasterRTUTransmitFSM( void )
|
vMBMasterPortTimersT35Enable();
|
||||||
//{
|
break;
|
||||||
// BOOL xNeedPoll = FALSE;
|
}
|
||||||
//
|
return xTaskNeedSwitch;
|
||||||
// assert_param( eRcvState == STATE_RX_IDLE );
|
}
|
||||||
//
|
|
||||||
// switch ( eSndState )
|
BOOL
|
||||||
// {
|
xMBMasterRTUTransmitFSM( void )
|
||||||
// /* We should not get a transmitter event if the transmitter is in
|
{
|
||||||
// * idle state. */
|
BOOL xNeedPoll = FALSE;
|
||||||
// case STATE_M_TX_IDLE:
|
|
||||||
// /* enable receiver/disable transmitter. */
|
assert_param( eRcvState == STATE_RX_IDLE );
|
||||||
// vMBMasterPortSerialEnable( TRUE, FALSE );
|
|
||||||
// break;
|
switch ( eSndState )
|
||||||
//
|
{
|
||||||
// case STATE_M_TX_XMIT:
|
/* We should not get a transmitter event if the transmitter is in
|
||||||
// /* check if we are finished. */
|
* idle state. */
|
||||||
// if( usSndBufferCount != 0 )
|
case STATE_M_TX_IDLE:
|
||||||
// {
|
/* enable receiver/disable transmitter. */
|
||||||
// xMBMasterPortSerialPutByte( ( CHAR )*pucSndBufferCur );
|
vMBMasterPortSerialEnable( TRUE, FALSE );
|
||||||
// pucSndBufferCur++; /* next byte in sendbuffer. */
|
break;
|
||||||
// usSndBufferCount--;
|
|
||||||
// }
|
case STATE_M_TX_XMIT:
|
||||||
// else
|
/* check if we are finished. */
|
||||||
// {
|
if( usMasterSndBufferCount != 0 )
|
||||||
// xNeedPoll = xMBMasterPortEventPost( EV_FRAME_SENT );
|
{
|
||||||
// /* Disable transmitter. This prevents another transmit buffer
|
xMBMasterPortSerialPutByte( ( CHAR )*pucMasterSndBufferCur );
|
||||||
// * empty interrupt. */
|
pucMasterSndBufferCur++; /* next byte in sendbuffer. */
|
||||||
// vMBMasterPortSerialEnable( TRUE, FALSE );
|
usMasterSndBufferCount--;
|
||||||
// eSndState = STATE_M_TX_IDLE;
|
}
|
||||||
// }
|
else
|
||||||
// break;
|
{
|
||||||
// }
|
bFrameIsBroadcast = ( ucMasterRTUBuf[MB_SER_PDU_ADDR_OFF] == MB_ADDRESS_BROADCAST ) ? TRUE : FALSE;
|
||||||
//
|
xNeedPoll = xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
|
||||||
// return xNeedPoll;
|
/* Disable transmitter. This prevents another transmit buffer
|
||||||
//}
|
* empty interrupt. */
|
||||||
//
|
vMBMasterPortSerialEnable( TRUE, FALSE );
|
||||||
|
eSndState = STATE_M_TX_XFWR;
|
||||||
|
/* If the frame is broadcast ,master will enable timer of convert delay,
|
||||||
|
* else master will enable timer of respond timeout. */
|
||||||
|
if ( bFrameIsBroadcast == TRUE ) vMBMasterPortTimersConvertDelayEnable( );
|
||||||
|
else vMBMasterPortTimersRespondTimeoutEnable( );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xNeedPoll;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
xMBMasterRTUTimerT35Expired(void)
|
xMBMasterRTUTimerT35Expired(void)
|
||||||
{
|
{
|
||||||
|
@ -329,13 +342,13 @@ xMBMasterRTUTimerT35Expired(void)
|
||||||
{
|
{
|
||||||
/* Timer t35 expired. Startup phase is finished. */
|
/* Timer t35 expired. Startup phase is finished. */
|
||||||
case STATE_M_RX_INIT:
|
case STATE_M_RX_INIT:
|
||||||
xNeedPoll = xMBMasterPortEventPost(EV_READY);
|
xNeedPoll = xMBMasterPortEventPost(EV_MASTER_READY);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* A frame was received and t35 expired. Notify the listener that
|
/* A frame was received and t35 expired. Notify the listener that
|
||||||
* a new frame was received. */
|
* a new frame was received. */
|
||||||
case STATE_M_RX_RCV:
|
case STATE_M_RX_RCV:
|
||||||
xNeedPoll = xMBMasterPortEventPost(EV_FRAME_RECEIVED);
|
xNeedPoll = xMBMasterPortEventPost(EV_MASTER_FRAME_RECEIVED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* An error occured while receiving the frame. */
|
/* An error occured while receiving the frame. */
|
||||||
|
@ -348,19 +361,24 @@ xMBMasterRTUTimerT35Expired(void)
|
||||||
( 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 ));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vMBMasterPortTimersDisable();
|
|
||||||
eRcvState = STATE_M_RX_IDLE;
|
eRcvState = STATE_M_RX_IDLE;
|
||||||
|
|
||||||
//TODO 发送状态在超时后的状态转换需要添加
|
switch (eSndState)
|
||||||
|
|
||||||
switch(eSndState)
|
|
||||||
{
|
{
|
||||||
/* Timer t35 expired. . */
|
/* A frame was send finish and convert delay or respond timeout expired.
|
||||||
case STATE_M_TX_XMIT :
|
* 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 ( bFrameIsBroadcast == FALSE ) xNeedPoll = xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS);
|
||||||
|
break;
|
||||||
|
/* Function called in an illegal state. */
|
||||||
|
default:
|
||||||
|
assert_param( eSndState == STATE_M_TX_XFWR );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
eSndState = STATE_M_TX_IDLE;
|
||||||
|
|
||||||
|
vMBMasterPortTimersDisable();
|
||||||
return xNeedPoll;
|
return xNeedPoll;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#define _PORT_H
|
#define _PORT_H
|
||||||
|
|
||||||
#include <stm32f10x_conf.h>
|
#include <stm32f10x_conf.h>
|
||||||
|
#include "mbconfig.h"
|
||||||
#include <rthw.h>
|
#include <rthw.h>
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,9 @@
|
||||||
#include "mb.h"
|
#include "mb.h"
|
||||||
#include "mbport.h"
|
#include "mbport.h"
|
||||||
|
|
||||||
|
#if MB_MASTER_RTU_ENABLED > 0
|
||||||
/* ----------------------- Variables ----------------------------------------*/
|
/* ----------------------- Variables ----------------------------------------*/
|
||||||
static eMBEventType eMasterQueuedEvent;
|
static eMBMasterEventType eMasterQueuedEvent;
|
||||||
static BOOL xMasterEventInQueue;
|
static BOOL xMasterEventInQueue;
|
||||||
|
|
||||||
/* ----------------------- Start implementation -----------------------------*/
|
/* ----------------------- Start implementation -----------------------------*/
|
||||||
|
@ -36,7 +37,7 @@ xMBMasterPortEventInit( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
xMBMasterPortEventPost( eMBEventType eEvent )
|
xMBMasterPortEventPost( eMBMasterEventType eEvent )
|
||||||
{
|
{
|
||||||
xMasterEventInQueue = TRUE;
|
xMasterEventInQueue = TRUE;
|
||||||
eMasterQueuedEvent = eEvent;
|
eMasterQueuedEvent = eEvent;
|
||||||
|
@ -44,7 +45,7 @@ xMBMasterPortEventPost( eMBEventType eEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
xMBMasterPortEventGet( eMBEventType * eEvent )
|
xMBMasterPortEventGet( eMBMasterEventType * eEvent )
|
||||||
{
|
{
|
||||||
BOOL xEventHappened = FALSE;
|
BOOL xEventHappened = FALSE;
|
||||||
|
|
||||||
|
@ -56,3 +57,5 @@ xMBMasterPortEventGet( eMBEventType * eEvent )
|
||||||
}
|
}
|
||||||
return xEventHappened;
|
return xEventHappened;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
/* ----------------------- Modbus includes ----------------------------------*/
|
/* ----------------------- Modbus includes ----------------------------------*/
|
||||||
#include "mb.h"
|
#include "mb.h"
|
||||||
#include "mbport.h"
|
#include "mbport.h"
|
||||||
|
|
||||||
|
#if MB_MASTER_RTU_ENABLED > 0
|
||||||
/* ----------------------- static functions ---------------------------------*/
|
/* ----------------------- static functions ---------------------------------*/
|
||||||
static void prvvUARTTxReadyISR(void);
|
static void prvvUARTTxReadyISR(void);
|
||||||
static void prvvUARTRxISR(void);
|
static void prvvUARTRxISR(void);
|
||||||
|
@ -188,3 +190,5 @@ void USART2_IRQHandler(void)
|
||||||
}
|
}
|
||||||
rt_interrupt_leave();
|
rt_interrupt_leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -26,11 +26,15 @@
|
||||||
#include "mb.h"
|
#include "mb.h"
|
||||||
#include "mbport.h"
|
#include "mbport.h"
|
||||||
|
|
||||||
|
#if MB_MASTER_RTU_ENABLED > 0
|
||||||
|
/* ----------------------- Variables ----------------------------------------*/
|
||||||
|
static USHORT usT35TimeOut50us;
|
||||||
|
|
||||||
/* ----------------------- static functions ---------------------------------*/
|
/* ----------------------- static functions ---------------------------------*/
|
||||||
static void prvvTIMERExpiredISR(void);
|
static void prvvTIMERExpiredISR(void);
|
||||||
|
|
||||||
/* ----------------------- Start implementation -----------------------------*/
|
/* ----------------------- Start implementation -----------------------------*/
|
||||||
BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us)
|
BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint16_t PrescalerValue = 0;
|
uint16_t PrescalerValue = 0;
|
||||||
|
@ -48,7 +52,8 @@ BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us)
|
||||||
|
|
||||||
PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1;
|
PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1;
|
||||||
//¶¨Ê±Æ÷1³õʼ»¯
|
//¶¨Ê±Æ÷1³õʼ»¯
|
||||||
TIM_TimeBaseStructure.TIM_Period = (uint16_t) usTim1Timerout50us;
|
usT35TimeOut50us = usTimeOut50us; //保存T35定时器计数值
|
||||||
|
|
||||||
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
|
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
|
||||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
|
@ -72,8 +77,39 @@ BOOL xMBMasterPortTimersInit(USHORT usTim1Timerout50us)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vMBMasterPortTimersEnable()
|
void vMBMasterPortTimersT35Enable()
|
||||||
{
|
{
|
||||||
|
//装载计数值 基准50us
|
||||||
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
|
TIM_TimeBaseStructure.TIM_Period = (uint16_t) usT35TimeOut50us;
|
||||||
|
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
||||||
|
|
||||||
|
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
||||||
|
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
||||||
|
TIM_SetCounter(TIM2, 0);
|
||||||
|
TIM_Cmd(TIM2, ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vMBMasterPortTimersConvertDelayEnable()
|
||||||
|
{
|
||||||
|
//装载计数值 基准50us
|
||||||
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
|
TIM_TimeBaseStructure.TIM_Period = (uint16_t)(MB_MASTER_DELAY_MS_CONVERT * 1000 / 50) ;
|
||||||
|
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
||||||
|
|
||||||
|
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
||||||
|
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
||||||
|
TIM_SetCounter(TIM2, 0);
|
||||||
|
TIM_Cmd(TIM2, ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vMBMasterPortTimersRespondTimeoutEnable()
|
||||||
|
{
|
||||||
|
//装载计数值 基准50us
|
||||||
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
|
TIM_TimeBaseStructure.TIM_Period = (uint16_t)(MB_MASTER_TIMEOUT_MS_RESPOND * 1000 / 50);
|
||||||
|
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
||||||
|
|
||||||
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
||||||
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
||||||
TIM_SetCounter(TIM2, 0);
|
TIM_SetCounter(TIM2, 0);
|
||||||
|
@ -105,3 +141,5 @@ void TIM2_IRQHandler(void)
|
||||||
}
|
}
|
||||||
rt_interrupt_leave();
|
rt_interrupt_leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue